rack-service_api_versioning 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +13 -0
- data/.rubocop.yml +14 -0
- data/.travis.yml +5 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +105 -0
- data/Rakefile +60 -0
- data/bin/console +14 -0
- data/bin/setup +12 -0
- data/config.reek +21 -0
- data/doc/API-DOCUMENTATION.md +166 -0
- data/doc/CODE_OF_CONDUCT.md +74 -0
- data/doc/UBIQUITOUS-LANGUAGE.md +286 -0
- data/lib/rack/service_api_versioning/accept_content_type_selector.rb +78 -0
- data/lib/rack/service_api_versioning/api_version_redirector.rb +60 -0
- data/lib/rack/service_api_versioning/build_redirect_location_uri.rb +55 -0
- data/lib/rack/service_api_versioning/build_redirect_uri_from_env.rb +54 -0
- data/lib/rack/service_api_versioning/encoded_api_version_data/input_data.rb +45 -0
- data/lib/rack/service_api_versioning/encoded_api_version_data/invalid_base_url_error.rb +22 -0
- data/lib/rack/service_api_versioning/encoded_api_version_data/return_data.rb +44 -0
- data/lib/rack/service_api_versioning/encoded_api_version_data.rb +61 -0
- data/lib/rack/service_api_versioning/http_error_response.rb +29 -0
- data/lib/rack/service_api_versioning/input_env.rb +38 -0
- data/lib/rack/service_api_versioning/input_is_invalid.rb +36 -0
- data/lib/rack/service_api_versioning/match_header_against_api_versions.rb +55 -0
- data/lib/rack/service_api_versioning/report_invalid_description.rb +19 -0
- data/lib/rack/service_api_versioning/report_no_matching_version.rb +34 -0
- data/lib/rack/service_api_versioning/report_not_found.rb +18 -0
- data/lib/rack/service_api_versioning/service_component_describer/report_service_not_found.rb +44 -0
- data/lib/rack/service_api_versioning/service_component_describer.rb +68 -0
- data/lib/rack/service_api_versioning/version.rb +7 -0
- data/lib/rack/service_api_versioning.rb +14 -0
- data/lib/tasks/flog_task_patch.rb +12 -0
- data/rack-service_api_versioning.gemspec +62 -0
- data/tmp/gemsets/setup-and-bundle.sh +48 -0
- metadata +415 -0
@@ -0,0 +1,61 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'forwardable'
|
4
|
+
|
5
|
+
require 'prolog/dry_types'
|
6
|
+
|
7
|
+
require_relative './encoded_api_version_data/input_data'
|
8
|
+
require_relative './encoded_api_version_data/return_data'
|
9
|
+
require_relative './encoded_api_version_data/invalid_base_url_error'
|
10
|
+
|
11
|
+
# All(?) Rack code is namespaced within this module.
|
12
|
+
module Rack
|
13
|
+
# Module includes our middleware components for managing service API versions.
|
14
|
+
module ServiceApiVersioning
|
15
|
+
# Builds an API Version data hash and encodes as JSON, for injection into a
|
16
|
+
# Rack environment, normally with the key "COMPONENT_API_VERSION_DATA".
|
17
|
+
class EncodedApiVersionData
|
18
|
+
def self.call(api_version:, data:)
|
19
|
+
new(api_version, data).call
|
20
|
+
end
|
21
|
+
|
22
|
+
def call
|
23
|
+
JSON.dump(version_data.to_hash)
|
24
|
+
end
|
25
|
+
|
26
|
+
protected
|
27
|
+
|
28
|
+
def initialize(api_version, input_data)
|
29
|
+
@api_version = api_version.to_sym
|
30
|
+
@data_obj = InputData.new api_version: api_version,
|
31
|
+
input_data: input_data
|
32
|
+
self
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
extend Forwardable
|
38
|
+
def_delegators :@data_obj, :base_url, :name, :vendor_org
|
39
|
+
|
40
|
+
attr_reader :api_version
|
41
|
+
|
42
|
+
def raise_invalid_base_url_error(original_error)
|
43
|
+
raise InvalidBaseUrlError.new base_url, original_error
|
44
|
+
end
|
45
|
+
|
46
|
+
def return_data_params
|
47
|
+
{ api_version: api_version, base_url: base_url, name: name,
|
48
|
+
vendor_org: vendor_org }
|
49
|
+
end
|
50
|
+
|
51
|
+
def version_data
|
52
|
+
ReturnData.new return_data_params
|
53
|
+
rescue Dry::Struct::Error => original_error
|
54
|
+
raise_invalid_base_url_error original_error
|
55
|
+
end
|
56
|
+
|
57
|
+
private_constant :InputData
|
58
|
+
private_constant :ReturnData
|
59
|
+
end # class EncodedApiVersionData
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rack'
|
4
|
+
require 'rack/response'
|
5
|
+
|
6
|
+
# All(?) Rack code is namespaced within this module.
|
7
|
+
module Rack
|
8
|
+
# Module includes our middleware components for managing service API versions.
|
9
|
+
module ServiceApiVersioning
|
10
|
+
# Builds Rack::Response with specified status code and body message.
|
11
|
+
class HttpErrorResponse
|
12
|
+
def call
|
13
|
+
Rack::Response.new(message, code).finish
|
14
|
+
end
|
15
|
+
|
16
|
+
protected
|
17
|
+
|
18
|
+
def initialize(code, message)
|
19
|
+
@code = code.to_i
|
20
|
+
@message = Array(message)
|
21
|
+
self
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
attr_reader :code, :message
|
27
|
+
end # class Rack::ServiceApiVersioning::HttpErrorResponse
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# All(?) Rack code is namespaced within this module.
|
4
|
+
module Rack
|
5
|
+
# Module includes our middleware components for managing service API versions.
|
6
|
+
module ServiceApiVersioning
|
7
|
+
# Wrapper around JSON encoding of object in environment with defaulted key.
|
8
|
+
class InputEnv
|
9
|
+
DEFAULT_INPUT_KEY = 'COMPONENT_DESCRIPTION'
|
10
|
+
|
11
|
+
def initialize(env, input_key = DEFAULT_INPUT_KEY)
|
12
|
+
@env = env
|
13
|
+
@key = input_key
|
14
|
+
self
|
15
|
+
end
|
16
|
+
|
17
|
+
def any?
|
18
|
+
!input_str.empty?
|
19
|
+
end
|
20
|
+
|
21
|
+
def data
|
22
|
+
JSON.parse input_str, symbolize_names: true
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
attr_reader :env, :key
|
28
|
+
|
29
|
+
def input_str
|
30
|
+
input_value.strip
|
31
|
+
end
|
32
|
+
|
33
|
+
def input_value
|
34
|
+
env[key].to_s
|
35
|
+
end
|
36
|
+
end # class Rack::ServiceApiVersioning::InputEnv
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative './report_invalid_description'
|
4
|
+
require_relative './report_not_found'
|
5
|
+
|
6
|
+
# All(?) Rack code is namespaced within this module.
|
7
|
+
module Rack
|
8
|
+
# Module includes our middleware components for managing service API versions.
|
9
|
+
module ServiceApiVersioning
|
10
|
+
# Validates input for AcceptContentTypeSelector. If input passes checks,
|
11
|
+
# returns `nil`. Returns a Rack::Response instance if any validation step
|
12
|
+
# failed.
|
13
|
+
class InputIsInvalid
|
14
|
+
def self.call(input)
|
15
|
+
Internals.verify_input(input) || Internals.verify_api_versions(input)
|
16
|
+
end
|
17
|
+
|
18
|
+
# Stateless methods
|
19
|
+
module Internals
|
20
|
+
def self._api_versions?(input)
|
21
|
+
input.data[:api_versions].any?
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.verify_api_versions(input)
|
25
|
+
return ReportNotFound.call unless _api_versions?(input)
|
26
|
+
nil
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.verify_input(input)
|
30
|
+
return ReportInvalidDescription.call unless input.any?
|
31
|
+
nil
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end # class Rack::ServiceApiVersioning::InputIsInvalid
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rack'
|
4
|
+
require 'rack/utils'
|
5
|
+
|
6
|
+
# All(?) Rack code is namespaced within this module.
|
7
|
+
module Rack
|
8
|
+
# Module includes our middleware components for managing service API versions.
|
9
|
+
module ServiceApiVersioning
|
10
|
+
# Matches content of HTTP Accept header against presently-available API
|
11
|
+
# Versions. Returns either a symbolic value (e.g., `:v2`) on success or
|
12
|
+
# `nil` on failure.
|
13
|
+
class MatchHeaderAgainstApiVersions
|
14
|
+
def self.call(accept_header:, api_versions:)
|
15
|
+
new(accept_header, api_versions).call
|
16
|
+
end
|
17
|
+
|
18
|
+
def call
|
19
|
+
best_match
|
20
|
+
end
|
21
|
+
|
22
|
+
protected
|
23
|
+
|
24
|
+
def initialize(accept_header, api_versions)
|
25
|
+
@accept_header = accept_header
|
26
|
+
@api_versions = api_versions
|
27
|
+
self
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
attr_reader :accept_header, :api_versions
|
33
|
+
|
34
|
+
def all_matches
|
35
|
+
api_versions.select { |_, version| best_type?(version) }
|
36
|
+
end
|
37
|
+
|
38
|
+
def all_types
|
39
|
+
api_versions.values.map { |version| version[:content_type] }
|
40
|
+
end
|
41
|
+
|
42
|
+
def best_match
|
43
|
+
all_matches.keys.first
|
44
|
+
end
|
45
|
+
|
46
|
+
def best_type
|
47
|
+
Rack::Utils.best_q_match(accept_header, all_types)
|
48
|
+
end
|
49
|
+
|
50
|
+
def best_type?(version)
|
51
|
+
version[:content_type] == best_type
|
52
|
+
end
|
53
|
+
end # class Rack::ServiceApiVersioning::MatchHeaderAgainstApiVersions
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative './http_error_response'
|
4
|
+
|
5
|
+
# All(?) Rack code is namespaced within this module.
|
6
|
+
module Rack
|
7
|
+
# Module includes our middleware components for managing service API versions.
|
8
|
+
module ServiceApiVersioning
|
9
|
+
# Builds Rack::Response to halt request execution with an HTTP status code
|
10
|
+
# of 400 ("Bad Request").
|
11
|
+
class ReportInvalidDescription < HttpErrorResponse
|
12
|
+
DEFAULT_MESSAGE = 'Invalid value for COMPONENT_DESCRIPTION'
|
13
|
+
|
14
|
+
def self.call(code: 400, message: DEFAULT_MESSAGE)
|
15
|
+
new(code, message).call
|
16
|
+
end
|
17
|
+
end # class Rack::ServiceApiVersioning::ReportInvalidDescription
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative './http_error_response'
|
4
|
+
|
5
|
+
# All(?) Rack code is namespaced within this module.
|
6
|
+
module Rack
|
7
|
+
# Module includes our middleware components for managing service API versions.
|
8
|
+
module ServiceApiVersioning
|
9
|
+
# Builds Rack::Response to halt request execution with an HTTP status code
|
10
|
+
# of 406 ("Not Acceptable") when no presently available API Version has been
|
11
|
+
# specified in an HTTP `Accept` header.
|
12
|
+
class ReportNoMatchingVersion < HttpErrorResponse
|
13
|
+
def self.call(api_versions:, code: 406)
|
14
|
+
new(code, Internals.message_data(api_versions)).call
|
15
|
+
end
|
16
|
+
|
17
|
+
# Stateless methods.
|
18
|
+
module Internals
|
19
|
+
def self.all_types_as_string(api_versions, separator = ', ')
|
20
|
+
all_types = api_versions.values.map do |version|
|
21
|
+
version[:content_type]
|
22
|
+
end
|
23
|
+
all_types.join(separator)
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.message_data(api_versions)
|
27
|
+
types = all_types_as_string(api_versions)
|
28
|
+
JSON.dump('supported-media-types': types)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
private_constant :Internals
|
32
|
+
end # class Rack::ServiceApiVersioning::ReportNoMatchingVersion
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative './http_error_response'
|
4
|
+
|
5
|
+
# All(?) Rack code is namespaced within this module.
|
6
|
+
module Rack
|
7
|
+
# Module includes our middleware components for managing service API versions.
|
8
|
+
module ServiceApiVersioning
|
9
|
+
# Builds Rack::Response to halt request execution, responding with a 404.
|
10
|
+
class ReportNotFound < HttpErrorResponse
|
11
|
+
DEFAULT_MESSAGE = 'Invalid value for COMPONENT_DESCRIPTION'
|
12
|
+
|
13
|
+
def self.call(code: 404, message: DEFAULT_MESSAGE)
|
14
|
+
new(code, message).call
|
15
|
+
end
|
16
|
+
end # class Rack::ServiceApiVersioning::ReportNotFound
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rack'
|
4
|
+
require 'rack/response'
|
5
|
+
|
6
|
+
# All(?) Rack code is namespaced within this module.
|
7
|
+
module Rack
|
8
|
+
# Module includes our middleware components for managing service API versions.
|
9
|
+
module ServiceApiVersioning
|
10
|
+
# Middlware to query and encode data on a named service, making it available
|
11
|
+
# to later entries in the middleware chain via an environment variable.
|
12
|
+
class ServiceComponentDescriber
|
13
|
+
# Builds Rack::Result to halt request execution, responding with a 404.
|
14
|
+
class ReportServiceNotFound
|
15
|
+
def self.call(service_name)
|
16
|
+
new(service_name).call
|
17
|
+
end
|
18
|
+
|
19
|
+
def call
|
20
|
+
new_response.finish
|
21
|
+
end
|
22
|
+
|
23
|
+
protected
|
24
|
+
|
25
|
+
def initialize(service_name)
|
26
|
+
@service_name = service_name
|
27
|
+
self
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
attr_reader :service_name
|
33
|
+
|
34
|
+
def body
|
35
|
+
%(Service not found: "#{service_name}")
|
36
|
+
end
|
37
|
+
|
38
|
+
def new_response
|
39
|
+
Rack::Response.new(Array(body), 404)
|
40
|
+
end
|
41
|
+
end # class ServiceComponentDescriber::ReportServiceNotFound
|
42
|
+
end # class ServiceComponentDescriber
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rack'
|
4
|
+
require 'rack/response'
|
5
|
+
|
6
|
+
require_relative './service_component_describer/report_service_not_found'
|
7
|
+
|
8
|
+
# All(?) Rack code is namespaced within this module.
|
9
|
+
module Rack
|
10
|
+
# Module includes our middleware components for managing service API versions.
|
11
|
+
module ServiceApiVersioning
|
12
|
+
# Middleware that, given a "service name" parameter, will read descriptive
|
13
|
+
# data from a supplied repository regarding the named service, format that
|
14
|
+
# data as a JSON string, assign it to the `COMPONENT_DESCRIPTION`
|
15
|
+
# environment variable, and pass the updated environment along to the next
|
16
|
+
# link in the Rack call chain (app or more middleware). If there is no data
|
17
|
+
# for the named service in the repository, this middleware will halt
|
18
|
+
# execution with a 404 (Not Found).
|
19
|
+
#
|
20
|
+
# Also bear in mind that both usual parameters (`repository` and
|
21
|
+
# `service_name`) are supplied *by the AVIDA,* which should know what those
|
22
|
+
# "ought" to be.
|
23
|
+
class ServiceComponentDescriber
|
24
|
+
DEFAULT_ENV_KEYS = { result: 'COMPONENT_DESCRIPTION' }.freeze
|
25
|
+
|
26
|
+
def initialize(app, repository:, service_name:,
|
27
|
+
env_keys: DEFAULT_ENV_KEYS)
|
28
|
+
@app = app
|
29
|
+
@env_keys = env_keys
|
30
|
+
@repository = repository
|
31
|
+
@service_name = service_name
|
32
|
+
self
|
33
|
+
end
|
34
|
+
|
35
|
+
def call(env)
|
36
|
+
env = update_env(env)
|
37
|
+
verify_datum_set(env) { |app_env| app.call app_env }
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
attr_reader :app, :env_keys, :repository, :service_name
|
43
|
+
|
44
|
+
def first_record
|
45
|
+
repository.find(name: service_name).first
|
46
|
+
end
|
47
|
+
|
48
|
+
def result_key
|
49
|
+
env_keys[:result]
|
50
|
+
end
|
51
|
+
|
52
|
+
def update_env(env)
|
53
|
+
datum = first_record
|
54
|
+
env[result_key] = JSON.dump(datum) if datum
|
55
|
+
env
|
56
|
+
end
|
57
|
+
|
58
|
+
def verify_datum_set(env)
|
59
|
+
verify_found(env) || yield(env)
|
60
|
+
end
|
61
|
+
|
62
|
+
def verify_found(env)
|
63
|
+
return nil if env[result_key]
|
64
|
+
ReportServiceNotFound.call(service_name)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rack/service_api_versioning/version'
|
4
|
+
require 'rack/service_api_versioning/accept_content_type_selector'
|
5
|
+
require 'rack/service_api_versioning/api_version_redirector'
|
6
|
+
require 'rack/service_api_versioning/service_component_describer'
|
7
|
+
|
8
|
+
# All(?) Rack code is namespaced within this module.
|
9
|
+
module Rack
|
10
|
+
# Module includes our middleware components for managing service API versions.
|
11
|
+
module ServiceApiVersioning
|
12
|
+
# Your code goes here...
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rake/tasklib'
|
4
|
+
require 'flog'
|
5
|
+
require 'flog_task'
|
6
|
+
|
7
|
+
# Redefinition of standard task's Rake invocation. Because we don't like
|
8
|
+
# inconsistency in option settings.
|
9
|
+
class FlogTask < Rake::TaskLib
|
10
|
+
# Reek bitches that this is a :reek:Attribute (writable). That's the *point*.
|
11
|
+
attr_accessor :methods_only
|
12
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
lib = File.expand_path('../lib', __FILE__)
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
require 'rack/service_api_versioning/version'
|
6
|
+
|
7
|
+
Gem::Specification.new do |spec|
|
8
|
+
spec.name = "rack-service_api_versioning"
|
9
|
+
spec.version = Rack::ServiceApiVersioning::VERSION
|
10
|
+
spec.authors = ["Jeff Dickey"]
|
11
|
+
spec.email = ["jdickey@seven-sigma.com"]
|
12
|
+
|
13
|
+
spec.summary = %q{Rack middleware for API Version-specific Component Service redirection.}
|
14
|
+
# spec.description = %q{TODO: Write a longer description or delete this line.}
|
15
|
+
spec.homepage = "https://github.com/jdickey/rack-service_api_versioning"
|
16
|
+
spec.required_ruby_version = ">= 2.3.0"
|
17
|
+
spec.license = "MIT"
|
18
|
+
|
19
|
+
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
|
20
|
+
# to allow pushing to a single host or delete this section to allow pushing to any host.
|
21
|
+
# if spec.respond_to?(:metadata)
|
22
|
+
# spec.metadata['allowed_push_host'] = "TODO: Set to 'http://mygemserver.com'"
|
23
|
+
# else
|
24
|
+
# raise "RubyGems 2.0 or newer is required to protect against " \
|
25
|
+
# "public gem pushes."
|
26
|
+
# end
|
27
|
+
|
28
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
29
|
+
f.match(%r{^(test|spec|features)/})
|
30
|
+
end
|
31
|
+
spec.bindir = "exe"
|
32
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
33
|
+
spec.require_paths = ["lib"]
|
34
|
+
|
35
|
+
spec.add_dependency "prolog-dry_types", '0.3.3'
|
36
|
+
spec.add_dependency "rack", '2.0.1'
|
37
|
+
|
38
|
+
spec.add_development_dependency "bundler", '1.14.6'
|
39
|
+
spec.add_development_dependency "rake", '12.0.0'
|
40
|
+
spec.add_development_dependency "minitest", '5.10.1'
|
41
|
+
|
42
|
+
spec.add_development_dependency "minitest-matchers", '1.4.1'
|
43
|
+
spec.add_development_dependency "minitest-reporters", '1.1.14'
|
44
|
+
spec.add_development_dependency "minitest-tagz", '1.5.2'
|
45
|
+
spec.add_development_dependency "flay", '2.8.1'
|
46
|
+
spec.add_development_dependency "flog", '4.6.1'
|
47
|
+
spec.add_development_dependency "reek", '4.5.6'
|
48
|
+
spec.add_development_dependency "rubocop", '0.47.1'
|
49
|
+
spec.add_development_dependency "simplecov", '0.14.1'
|
50
|
+
spec.add_development_dependency "pry-byebug", '3.4.2'
|
51
|
+
spec.add_development_dependency "pry-doc", '0.10.0'
|
52
|
+
spec.add_development_dependency "awesome_print", '1.7.0'
|
53
|
+
spec.add_development_dependency "colorator", '1.1.0'
|
54
|
+
|
55
|
+
spec.add_development_dependency 'guard', '2.14.1'
|
56
|
+
spec.add_development_dependency 'guard-livereload', '2.5.2'
|
57
|
+
spec.add_development_dependency 'guard-minitest', '2.4.6'
|
58
|
+
spec.add_development_dependency 'guard-rake', '1.0.0'
|
59
|
+
spec.add_development_dependency 'guard-reek', '1.0.2'
|
60
|
+
spec.add_development_dependency 'guard-rubocop', '1.2.0'
|
61
|
+
spec.add_development_dependency 'guard-rubycritic', '2.9.3'
|
62
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
#!/usr/bin/env zsh
|
2
|
+
|
3
|
+
RBVER=`rbenv version | cut -f 1 -d ' '`
|
4
|
+
GEMSETBASE="./tmp/gemsets/$RBVER"
|
5
|
+
rm -rf .rbenv-gemsets $GEMSETBASE/{dev,extras,runtime}
|
6
|
+
mkdir -p $RBENV_ROOT/versions/$RBVER/gemsets/.project-gemsets/rack-service_api_versioning-dummy
|
7
|
+
rm -rf $RBENV_ROOT/versions/$RBVER/gemsets/.project-gemsets/*rack-service_api_versioning*
|
8
|
+
|
9
|
+
mkdir -p $GEMSETBASE
|
10
|
+
rbenv gemset init $GEMSETBASE/runtime
|
11
|
+
gem install prolog-dry_types -v 0.3.3
|
12
|
+
gem install rack -v 2.0.1
|
13
|
+
|
14
|
+
rbenv gemset init $GEMSETBASE/dev
|
15
|
+
echo "$GEMSETBASE/dev\n$GEMSETBASE/runtime" > .rbenv-gemsets
|
16
|
+
gem install rake -v 12.0.0
|
17
|
+
gem install minitest -v 5.10.1
|
18
|
+
gem install minitest-matchers -v 1.4.1
|
19
|
+
gem install minitest-reporters -v 1.1.14
|
20
|
+
gem install minitest-tagz -v 1.5.2
|
21
|
+
|
22
|
+
gem install flay -v 2.8.1
|
23
|
+
gem install flog -v 4.6.1
|
24
|
+
gem install pry-byebug -v 3.4.2
|
25
|
+
gem install pry-doc -v 0.10.0
|
26
|
+
gem install reek -v 4.5.6
|
27
|
+
gem install rubocop -v 0.47.1
|
28
|
+
gem install simplecov -v 0.14.1
|
29
|
+
|
30
|
+
gem install awesome_print -v 1.7.0
|
31
|
+
gem install colorator -v 1.1.0
|
32
|
+
|
33
|
+
gem install guard -v 2.14.1
|
34
|
+
gem install guard-livereload -v 2.5.2
|
35
|
+
gem install guard-minitest -v 2.4.6
|
36
|
+
gem install guard-rake -v 1.0.0
|
37
|
+
gem install guard-reek -v 1.0.2
|
38
|
+
gem install guard-rubocop -v 1.2.0
|
39
|
+
gem install guard-rubycritic -v 2.9.3
|
40
|
+
# gem install guard-shell -v 0.7.1
|
41
|
+
|
42
|
+
# gem install fury -v 0.0.5
|
43
|
+
rbenv gemset init $GEMSETBASE/extras
|
44
|
+
echo "$GEMSETBASE/extras\n$GEMSETBASE/dev\n$GEMSETBASE/runtime" > .rbenv-gemsets
|
45
|
+
unset RBVER
|
46
|
+
rbenv rehash
|
47
|
+
|
48
|
+
bundle install --local
|