versionist 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/generators/versionist/inflector_fixes.rb +14 -0
- data/lib/generators/versionist/new_api_version/USAGE +19 -0
- data/lib/generators/versionist/new_api_version/new_api_version_generator.rb +76 -0
- data/lib/generators/versionist/new_api_version/templates/base_controller.rb +2 -0
- data/lib/generators/versionist/new_api_version/templates/base_controller_spec.rb +5 -0
- data/lib/generators/versionist/new_api_version/templates/base_controller_test.rb +8 -0
- data/lib/generators/versionist/new_api_version/templates/base_presenter.rb +2 -0
- data/lib/generators/versionist/new_api_version/templates/base_presenter_spec.rb +5 -0
- data/lib/generators/versionist/new_api_version/templates/base_presenter_test.rb +8 -0
- data/lib/generators/versionist/new_api_version/templates/docs_index.rb +17 -0
- data/lib/generators/versionist/new_api_version/templates/docs_style.rb +5 -0
- data/lib/generators/versionist/new_controller/USAGE +10 -0
- data/lib/generators/versionist/new_controller/new_controller_generator.rb +43 -0
- data/lib/generators/versionist/new_controller/templates/new_controller.rb +2 -0
- data/lib/generators/versionist/new_controller/templates/new_controller_spec.rb +5 -0
- data/lib/generators/versionist/new_controller/templates/new_controller_test.rb +9 -0
- data/lib/generators/versionist/new_presenter/USAGE +10 -0
- data/lib/generators/versionist/new_presenter/new_presenter_generator.rb +30 -0
- data/lib/generators/versionist/new_presenter/templates/new_presenter.rb +15 -0
- data/lib/generators/versionist/new_presenter/templates/new_presenter_spec.rb +5 -0
- data/lib/generators/versionist/new_presenter/templates/new_presenter_test.rb +8 -0
- data/lib/versionist.rb +20 -0
- data/lib/versionist/configuration.rb +15 -0
- data/lib/versionist/middleware.rb +39 -0
- data/lib/versionist/railtie.rb +18 -0
- data/lib/versionist/routing.rb +47 -0
- data/lib/versionist/version.rb +3 -0
- data/lib/versionist/versioning_strategy.rb +10 -0
- data/lib/versionist/versioning_strategy/base.rb +26 -0
- data/lib/versionist/versioning_strategy/header.rb +23 -0
- data/lib/versionist/versioning_strategy/parameter.rb +23 -0
- data/lib/versionist/versioning_strategy/path.rb +15 -0
- metadata +183 -0
@@ -0,0 +1,14 @@
|
|
1
|
+
module Versionist
|
2
|
+
# Various fixes for quirks in Rails' inflector
|
3
|
+
module InflectorFixes
|
4
|
+
# Transforms a module name for use in a route
|
5
|
+
def module_name_for_route(module_name)
|
6
|
+
module_name.gsub(/_{1}/, "__")
|
7
|
+
end
|
8
|
+
|
9
|
+
# Transforms a module name for use in a file path
|
10
|
+
def module_name_for_path(module_name)
|
11
|
+
module_name.underscore
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
Description:
|
2
|
+
Creates the infrastructure for a new API version.
|
3
|
+
|
4
|
+
Example:
|
5
|
+
rails generate versionist:new_api_version v2.0.0 V2_0_0 header:Accept value:application/vnd.mycompany.com-v2.0.0
|
6
|
+
|
7
|
+
This will create:
|
8
|
+
|
9
|
+
route api_version(:module => "V2__0__0", :header=>"Accept", :value=>"application/vnd.mycompany.com-v2.0.0") do
|
10
|
+
end
|
11
|
+
create app/controllers/v2_0_0
|
12
|
+
create app/controllers/v2_0_0/base_controller.rb
|
13
|
+
create app/presenters/v2_0_0
|
14
|
+
create app/presenters/v2_0_0/base_presenter.rb
|
15
|
+
create public/docs/v2.0.0
|
16
|
+
create public/docs/v2.0.0/index.html
|
17
|
+
create public/docs/v2.0.0/style.css
|
18
|
+
|
19
|
+
In addition this will create tests for base_controller.rb and base_presenter.rb using the test_framework currently configured in your Rails app.
|
@@ -0,0 +1,76 @@
|
|
1
|
+
module Versionist
|
2
|
+
class NewApiVersionGenerator < Rails::Generators::Base
|
3
|
+
include InflectorFixes
|
4
|
+
|
5
|
+
desc "creates the infrastructure for a new API version"
|
6
|
+
|
7
|
+
source_root File.expand_path('../templates', __FILE__)
|
8
|
+
|
9
|
+
argument :version, :type => :string
|
10
|
+
argument :module_name, :type => :string
|
11
|
+
argument :versioning_strategy, :banner => "VERSIONING_STRATEGY_OPTIONS", :type => :hash
|
12
|
+
|
13
|
+
def add_routes
|
14
|
+
in_root do
|
15
|
+
api_version_block = /api_version.*:module\s*(=>|:)\s*("|')#{module_name_for_route(module_name)}("|').*do/
|
16
|
+
matching_version_blocks = File.readlines("config/routes.rb").grep(api_version_block)
|
17
|
+
raise "API version already exists in config/routes.rb" if !matching_version_blocks.empty?
|
18
|
+
versioning_strategy.symbolize_keys!
|
19
|
+
route "api_version(:module => \"#{module_name_for_route(module_name)}\", #{versioning_strategy.to_s.gsub(/[\{\}]/, '')}) do\n end"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def add_controller_base
|
24
|
+
in_root do
|
25
|
+
empty_directory "app/controllers/#{module_name_for_path(module_name)}"
|
26
|
+
template 'base_controller.rb', File.join("app", "controllers", "#{module_name_for_path(module_name)}", "base_controller.rb")
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# due to the inflector quirks we can't use hook_for :test_framework
|
31
|
+
def add_controller_base_test
|
32
|
+
in_root do
|
33
|
+
case Versionist.configuration.configured_test_framework
|
34
|
+
when :test_unit
|
35
|
+
empty_directory "test/functional/#{module_name_for_path(module_name)}"
|
36
|
+
template 'base_controller_test.rb', File.join("test", "functional", "#{module_name_for_path(module_name)}", "base_controller_test.rb")
|
37
|
+
when :rspec
|
38
|
+
empty_directory "spec/controllers/#{module_name_for_path(module_name)}"
|
39
|
+
template 'base_controller_spec.rb', File.join("spec", "controllers", "#{module_name_for_path(module_name)}", "base_controller_spec.rb")
|
40
|
+
else
|
41
|
+
say "Unsupported test_framework: #{Versionist.configuration.configured_test_framework}"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def add_presenters_base
|
47
|
+
in_root do
|
48
|
+
empty_directory "app/presenters/#{module_name_for_path(module_name)}"
|
49
|
+
template 'base_presenter.rb', File.join("app", "presenters", "#{module_name_for_path(module_name)}", "base_presenter.rb")
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def add_presenter_test
|
54
|
+
in_root do
|
55
|
+
case Versionist.configuration.configured_test_framework
|
56
|
+
when :test_unit
|
57
|
+
empty_directory "test/presenters/#{module_name_for_path(module_name)}"
|
58
|
+
template 'base_presenter_test.rb', File.join("test", "presenters", "#{module_name_for_path(module_name)}", "base_presenter_test.rb")
|
59
|
+
when :rspec
|
60
|
+
empty_directory "spec/presenters/#{module_name_for_path(module_name)}"
|
61
|
+
template 'base_presenter_spec.rb', File.join("spec", "presenters", "#{module_name_for_path(module_name)}", "base_presenter_spec.rb")
|
62
|
+
else
|
63
|
+
say "Unsupported test_framework: #{Versionist.configuration.configured_test_framework}"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def add_documentation_base
|
69
|
+
in_root do
|
70
|
+
empty_directory "public/docs/#{version}"
|
71
|
+
template 'docs_index.rb', File.join("public", "docs", "#{version}", "index.html")
|
72
|
+
template 'docs_style.rb', File.join("public", "docs", "#{version}", "style.css")
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html lang="en-US">
|
3
|
+
<head>
|
4
|
+
<title>Documentation for <%= version%></title>
|
5
|
+
<link href="<%= version%>/style.css" media="screen" rel="stylesheet" type="text/css">
|
6
|
+
</head>
|
7
|
+
<body>
|
8
|
+
<div id="container">
|
9
|
+
<div id="operations">
|
10
|
+
<h3>API Operations</h3>
|
11
|
+
</div>
|
12
|
+
<div id="content">
|
13
|
+
<h1>Documentation for <%= version%></h1>
|
14
|
+
</div>
|
15
|
+
</div>
|
16
|
+
</body>
|
17
|
+
</html>
|
@@ -0,0 +1,10 @@
|
|
1
|
+
Description:
|
2
|
+
Creates a new controller class with the given name under the given module namespace
|
3
|
+
|
4
|
+
Example:
|
5
|
+
rails generate versionist:new_controller test V2_0_0
|
6
|
+
|
7
|
+
This will create:
|
8
|
+
app/controllers/V2_0_0/test_controller.rb
|
9
|
+
|
10
|
+
In addition this will create a test for the new controller using the test_framework currently configured in your Rails app.
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Versionist
|
2
|
+
class NewControllerGenerator < Rails::Generators::NamedBase
|
3
|
+
include InflectorFixes
|
4
|
+
|
5
|
+
desc "creates a new controller for an existing API version"
|
6
|
+
source_root File.expand_path('../templates', __FILE__)
|
7
|
+
|
8
|
+
argument :module_name, :type => :string
|
9
|
+
|
10
|
+
def new_controller
|
11
|
+
in_root do
|
12
|
+
raise "API module namespace #{module_name} doesn't exist. Please run \'rails generate versionist:new_api_version\' generator first" if !File.exists?("app/controllers/#{module_name_for_path(module_name)}")
|
13
|
+
template 'new_controller.rb', File.join("app", "controllers", "#{module_name_for_path(module_name)}", "#{file_name}_controller.rb")
|
14
|
+
|
15
|
+
api_version_block = /api_version.*:module\s*(=>|:)\s*("|')#{module_name_for_route(module_name)}("|').*do/
|
16
|
+
new_route = " resources :#{file_name}\n"
|
17
|
+
matching_version_blocks = File.readlines("config/routes.rb").grep(api_version_block)
|
18
|
+
if matching_version_blocks.empty?
|
19
|
+
raise "API version doesn't exist in config/routes.rb. Please run \'rails generate versionist:new_api_version\' generator first"
|
20
|
+
elsif matching_version_blocks.size > 1
|
21
|
+
raise "API version is duplicated in config/routes.rb"
|
22
|
+
else
|
23
|
+
version_block = matching_version_blocks.first
|
24
|
+
inject_into_file "config/routes.rb", "#{new_route}", {:after => version_block, :verbose => false}
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# due to the inflector quirks we can't use hook_for :test_framework
|
30
|
+
def new_controller_test
|
31
|
+
in_root do
|
32
|
+
case Versionist.configuration.configured_test_framework
|
33
|
+
when :test_unit
|
34
|
+
template 'new_controller_test.rb', File.join("test", "functional", "#{module_name_for_path(module_name)}", "#{file_name}_controller_test.rb")
|
35
|
+
when :rspec
|
36
|
+
template 'new_controller_spec.rb', File.join("spec", "controllers", "#{module_name_for_path(module_name)}", "#{file_name}_controller_spec.rb")
|
37
|
+
else
|
38
|
+
say "Unsupported test_framework: #{Versionist.configuration.configured_test_framework}"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
Description:
|
2
|
+
Creates a new presenter class with the given name under the given version
|
3
|
+
|
4
|
+
Example:
|
5
|
+
rails generate versionist:new_presenter foo V2_0_0
|
6
|
+
|
7
|
+
This will create:
|
8
|
+
app/presenters/v2_0_0/foo_presenter.rb
|
9
|
+
|
10
|
+
In addition this will create a test for the new controller using the test_framework currently configured in your Rails app.
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Versionist
|
2
|
+
class NewPresenterGenerator < Rails::Generators::NamedBase
|
3
|
+
include InflectorFixes
|
4
|
+
|
5
|
+
desc "creates a new presenter for an existing API version"
|
6
|
+
source_root File.expand_path('../templates', __FILE__)
|
7
|
+
|
8
|
+
argument :module_name, :type => :string
|
9
|
+
|
10
|
+
def new_presenter
|
11
|
+
in_root do
|
12
|
+
raise "API module namespace #{module_name} doesn't exist. Please run \'rails generate versionist:new_api_version\' generator first" if !File.exists?("app/presenters/#{module_name_for_path(module_name)}")
|
13
|
+
template 'new_presenter.rb', File.join("app", "presenters", "#{module_name_for_path(module_name)}", "#{file_name}_presenter.rb")
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def new_presenter_test
|
18
|
+
in_root do
|
19
|
+
case Versionist.configuration.configured_test_framework
|
20
|
+
when :test_unit
|
21
|
+
template 'new_presenter_test.rb', File.join("test", "presenters", "#{module_name_for_path(module_name)}", "#{file_name}_presenter_test.rb")
|
22
|
+
when :rspec
|
23
|
+
template 'new_presenter_spec.rb', File.join("spec", "presenters", "#{module_name_for_path(module_name)}", "#{file_name}_presenter_spec.rb")
|
24
|
+
else
|
25
|
+
say "Unsupported test_framework: #{Versionist.configuration.configured_test_framework}"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class <%= module_name %>::<%= class_name%>Presenter
|
2
|
+
|
3
|
+
def initialize(<%= file_name %>)
|
4
|
+
@<%= file_name %> = <%= file_name %>
|
5
|
+
end
|
6
|
+
|
7
|
+
def as_json(options={})
|
8
|
+
# fill me in...
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_xml(options={}, &block)
|
12
|
+
xml = options[:builder] ||= Builder::XmlMarkup.new
|
13
|
+
# fill me in...
|
14
|
+
end
|
15
|
+
end
|
data/lib/versionist.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'active_support/dependencies/autoload'
|
2
|
+
|
3
|
+
module Versionist
|
4
|
+
extend ActiveSupport::Autoload
|
5
|
+
|
6
|
+
autoload :Configuration
|
7
|
+
autoload :InflectorFixes, "generators/versionist/inflector_fixes"
|
8
|
+
autoload :NewApiVersionGenerator, "generators/versionist/new_api_version/new_api_version_generator"
|
9
|
+
autoload :NewControllerGenerator, "generators/versionist/new_controller/new_controller_generator"
|
10
|
+
autoload :NewPresenterGenerator, "generators/versionist/new_presenter/new_presenter_generator"
|
11
|
+
autoload :VersioningStrategy, "versionist/versioning_strategy"
|
12
|
+
autoload :Middleware
|
13
|
+
autoload :Routing
|
14
|
+
|
15
|
+
def self.configuration
|
16
|
+
@@configuration ||= Configuration.new
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
require 'versionist/railtie' if defined?(Rails) && Rails::VERSION::MAJOR == 3
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Versionist
|
2
|
+
class Configuration
|
3
|
+
attr_accessor :versioning_strategies
|
4
|
+
attr_accessor :default_version
|
5
|
+
attr_accessor :header_versions
|
6
|
+
attr_accessor :parameter_versions
|
7
|
+
attr_accessor :configured_test_framework
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
@versioning_strategies ||= Array.new
|
11
|
+
@header_versions ||= Array.new
|
12
|
+
@parameter_versions ||= Array.new
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Versionist
|
2
|
+
# When your routes don't include an explicit format in the URL (i.e. `match 'foos.(:format)' => foos#index`),
|
3
|
+
# Rails inspects the `Accept` header to determine the requested format. Since an `Accept` header can have multiple values,
|
4
|
+
# Rails uses the first one present to determine the format. If your custom version header happens to be the first value
|
5
|
+
# in the `Accept` header, it would incorrectly be interpretted as the format. This middleware moves your custom version header
|
6
|
+
# (if found) to the end of the `Accept` header so as to not interfere with this format logic in Rails.
|
7
|
+
class Middleware
|
8
|
+
|
9
|
+
ACCEPT = "Accept"
|
10
|
+
HTTP_ACCEPT = "HTTP_ACCEPT"
|
11
|
+
|
12
|
+
def initialize(app)
|
13
|
+
@app = app
|
14
|
+
end
|
15
|
+
|
16
|
+
def call(env)
|
17
|
+
dup._call(env)
|
18
|
+
end
|
19
|
+
|
20
|
+
def _call(env)
|
21
|
+
request = ::Rack::Request.new(env)
|
22
|
+
strategy = Versionist.configuration.versioning_strategies.detect {|vs| vs.is_a?(Versionist::VersioningStrategy::Header) && vs.config[:header] == ACCEPT && env[HTTP_ACCEPT].include?(vs.config[:value])}
|
23
|
+
if !strategy.nil?
|
24
|
+
entries = env[HTTP_ACCEPT].split(',')
|
25
|
+
index = -1
|
26
|
+
entries.each_with_index do |e, i|
|
27
|
+
e.strip!
|
28
|
+
index = i if e == strategy.config[:value]
|
29
|
+
end
|
30
|
+
if (index != -1)
|
31
|
+
version = entries.delete_at(index)
|
32
|
+
entries << version
|
33
|
+
end
|
34
|
+
env[HTTP_ACCEPT] = entries.join(", ")
|
35
|
+
end
|
36
|
+
@app.call(env)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'rails/railtie'
|
2
|
+
|
3
|
+
module Versionist
|
4
|
+
class Railtie < Rails::Railtie
|
5
|
+
config.versionist = ActiveSupport::OrderedOptions.new
|
6
|
+
|
7
|
+
initializer 'versionist.configure' do |app|
|
8
|
+
ActionDispatch::Routing::Mapper.send :include, Versionist::Routing
|
9
|
+
end
|
10
|
+
|
11
|
+
config.app_middleware.use Versionist::Middleware
|
12
|
+
|
13
|
+
config.after_initialize do
|
14
|
+
generators = config.respond_to?(:app_generators) ? config.app_generators : config.generators
|
15
|
+
Versionist.configuration.configured_test_framework = generators.options[:rails][:test_framework]
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Versionist
|
2
|
+
module Routing
|
3
|
+
# Allows you to constrain routes to specific versions of your api using versioning strategies.
|
4
|
+
# Supported formats:
|
5
|
+
# api_version(:module => "v1", :header => "Accept", :value => "application/vnd.mycompany.com-v1")
|
6
|
+
# api_version(:module => "v2__3__4", :path => "/v2.3.4")
|
7
|
+
# api_version(:module => "v20120317", :parameter => "version", :value => "v20120317")
|
8
|
+
#
|
9
|
+
# Specifying default version:
|
10
|
+
# api_version(:module => "v3__0__0", :header => "X-MY-HEADER", :value => "v3.0.0", :default => true)
|
11
|
+
def api_version(config, &block)
|
12
|
+
raise ArgumentError, "you must pass a configuration Hash to api_version" if config.nil? || !config.is_a?(Hash)
|
13
|
+
raise ArgumentError, "you must specify :module in configuration Hash passed to api_version" if !config.has_key?(:module)
|
14
|
+
raise ArgumentError, "you must specify :header, :path, or :parameter in configuration Hash passed to api_version" if !config.has_key?(:header) && !config.has_key?(:path) && !config.has_key?(:parameter)
|
15
|
+
if config.has_key?(:header)
|
16
|
+
return configure_header(config, &block)
|
17
|
+
elsif config.has_key?(:path)
|
18
|
+
return configure_path(config, &block)
|
19
|
+
elsif config.has_key?(:parameter)
|
20
|
+
configure_parameter(config, &block)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def configure_header(config, &block)
|
28
|
+
header = Versionist::VersioningStrategy::Header.new(config)
|
29
|
+
scope({:module => config[:module], :constraints => header}, &block)
|
30
|
+
end
|
31
|
+
|
32
|
+
def configure_path(config, &block)
|
33
|
+
path = Versionist::VersioningStrategy::Path.new(config)
|
34
|
+
# Use the :as option and strip out non-word characters from the path to avoid this:
|
35
|
+
# https://github.com/rails/rails/issues/3224
|
36
|
+
namespace(config[:path], {:module => config[:module], :as => config[:path].gsub(/\W/, '_')}, &block)
|
37
|
+
if path.default?
|
38
|
+
scope({:module => config[:module], :as => config[:path].gsub(/\W/, '_')}, &block)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def configure_parameter(config, &block)
|
43
|
+
parameter = Versionist::VersioningStrategy::Parameter.new(config)
|
44
|
+
scope({:module => config[:module], :constraints => parameter}, &block)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
module Versionist
|
2
|
+
module VersioningStrategy
|
3
|
+
extend ActiveSupport::Autoload
|
4
|
+
|
5
|
+
autoload :Base, 'versionist/versioning_strategy/base'
|
6
|
+
autoload :Header, 'versionist/versioning_strategy/header'
|
7
|
+
autoload :Path, 'versionist/versioning_strategy/path'
|
8
|
+
autoload :Parameter, 'versionist/versioning_strategy/parameter'
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'active_support/core_ext/hash/keys'
|
2
|
+
|
3
|
+
module Versionist
|
4
|
+
module VersioningStrategy
|
5
|
+
class Base
|
6
|
+
attr_reader :config
|
7
|
+
attr_reader :default
|
8
|
+
|
9
|
+
def initialize(config={})
|
10
|
+
raise ArgumentError, "you must pass a configuration Hash" if config.nil? || !config.is_a?(Hash)
|
11
|
+
@config = config
|
12
|
+
@config.symbolize_keys!
|
13
|
+
Versionist.configuration.versioning_strategies << self
|
14
|
+
raise ArgumentError, "attempt set more than one default api version" if !Versionist.configuration.default_version.nil? && @config.has_key?(:default)
|
15
|
+
if @config.has_key?(:default)
|
16
|
+
Versionist.configuration.default_version = self
|
17
|
+
@default = true
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def default?
|
22
|
+
@default
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Versionist
|
2
|
+
module VersioningStrategy
|
3
|
+
# Implements the header versioning strategy.
|
4
|
+
class Header < Base
|
5
|
+
|
6
|
+
# Creates a new Header VersioningStrategy object. config must contain the following keys:
|
7
|
+
# - :header the header to inspect
|
8
|
+
# - :value the value of the header specifying the version
|
9
|
+
def initialize(config)
|
10
|
+
raise ArgumentError, "you must specify :header in the configuration Hash" if !config.has_key?(:header)
|
11
|
+
raise ArgumentError, "you must specify :value in the configuration Hash" if !config.has_key?(:value)
|
12
|
+
super
|
13
|
+
Versionist.configuration.header_versions << config[:value]
|
14
|
+
end
|
15
|
+
|
16
|
+
def matches?(request)
|
17
|
+
header_string = request.headers[config[:header]].to_s
|
18
|
+
return ((!header_string.blank? && header_string.include?(config[:value])) ||
|
19
|
+
(self.default? && (Versionist.configuration.header_versions.none? {|v| header_string.include?(v)})))
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Versionist
|
2
|
+
module VersioningStrategy
|
3
|
+
# Implements the parameter versioning strategy.
|
4
|
+
class Parameter < Base
|
5
|
+
|
6
|
+
# Creates a new Parameter VersioningStrategy object. config must contain the following keys:
|
7
|
+
# - :parameter the parameter to inspect
|
8
|
+
# - :value the value of the parameter specifying the version
|
9
|
+
def initialize(config)
|
10
|
+
raise ArgumentError, "you must specify :parameter in the configuration Hash" if !config.has_key?(:parameter)
|
11
|
+
raise ArgumentError, "you must specify :value in the configuration Hash" if !config.has_key?(:value)
|
12
|
+
super
|
13
|
+
Versionist.configuration.parameter_versions << config[:value]
|
14
|
+
end
|
15
|
+
|
16
|
+
def matches?(request)
|
17
|
+
parameter_string = request.params[config[:parameter]].to_s
|
18
|
+
return ((!parameter_string.blank? && parameter_string == config[:value]) ||
|
19
|
+
(self.default? && (Versionist.configuration.parameter_versions.none? {|v| parameter_string.include?(v)})))
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Versionist
|
2
|
+
module VersioningStrategy
|
3
|
+
# Implements the path versioning strategy. It expects the following path format:
|
4
|
+
# GET /<version>/...
|
5
|
+
class Path < Base
|
6
|
+
|
7
|
+
# Creates a new Path VersioningStrategy object. config must contain the following keys:
|
8
|
+
# - :path the path prefix containing the version
|
9
|
+
def initialize(config)
|
10
|
+
raise ArgumentError, "you must specify :path in the configuration Hash" if !config.has_key?(:path)
|
11
|
+
super
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
metadata
ADDED
@@ -0,0 +1,183 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: versionist
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 0.1.0
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Brian Ploetz
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2012-03-05 00:00:00 Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: rails
|
17
|
+
prerelease: false
|
18
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
19
|
+
none: false
|
20
|
+
requirements:
|
21
|
+
- - ~>
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "3.0"
|
24
|
+
type: :runtime
|
25
|
+
version_requirements: *id001
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: awesome_print
|
28
|
+
prerelease: false
|
29
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
30
|
+
none: false
|
31
|
+
requirements:
|
32
|
+
- - "="
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: 1.0.2
|
35
|
+
type: :development
|
36
|
+
version_requirements: *id002
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
name: rake
|
39
|
+
prerelease: false
|
40
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ">="
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 0.9.2
|
46
|
+
type: :development
|
47
|
+
version_requirements: *id003
|
48
|
+
- !ruby/object:Gem::Dependency
|
49
|
+
name: rspec
|
50
|
+
prerelease: false
|
51
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
52
|
+
none: false
|
53
|
+
requirements:
|
54
|
+
- - "="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: 2.8.0
|
57
|
+
type: :development
|
58
|
+
version_requirements: *id004
|
59
|
+
- !ruby/object:Gem::Dependency
|
60
|
+
name: rspec-rails
|
61
|
+
prerelease: false
|
62
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
63
|
+
none: false
|
64
|
+
requirements:
|
65
|
+
- - "="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: 2.8.0
|
68
|
+
type: :development
|
69
|
+
version_requirements: *id005
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: generator_spec
|
72
|
+
prerelease: false
|
73
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
74
|
+
none: false
|
75
|
+
requirements:
|
76
|
+
- - "="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: 0.8.4
|
79
|
+
type: :development
|
80
|
+
version_requirements: *id006
|
81
|
+
- !ruby/object:Gem::Dependency
|
82
|
+
name: rails
|
83
|
+
prerelease: false
|
84
|
+
requirement: &id007 !ruby/object:Gem::Requirement
|
85
|
+
none: false
|
86
|
+
requirements:
|
87
|
+
- - ~>
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: "3.0"
|
90
|
+
type: :development
|
91
|
+
version_requirements: *id007
|
92
|
+
- !ruby/object:Gem::Dependency
|
93
|
+
name: rdoc
|
94
|
+
prerelease: false
|
95
|
+
requirement: &id008 !ruby/object:Gem::Requirement
|
96
|
+
none: false
|
97
|
+
requirements:
|
98
|
+
- - ">="
|
99
|
+
- !ruby/object:Gem::Version
|
100
|
+
version: "3.11"
|
101
|
+
type: :development
|
102
|
+
version_requirements: *id008
|
103
|
+
- !ruby/object:Gem::Dependency
|
104
|
+
name: simplecov
|
105
|
+
prerelease: false
|
106
|
+
requirement: &id009 !ruby/object:Gem::Requirement
|
107
|
+
none: false
|
108
|
+
requirements:
|
109
|
+
- - "="
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: 0.5.4
|
112
|
+
type: :development
|
113
|
+
version_requirements: *id009
|
114
|
+
description: A plugin for versioning Rails 3 based RESTful APIs.
|
115
|
+
email:
|
116
|
+
executables: []
|
117
|
+
|
118
|
+
extensions: []
|
119
|
+
|
120
|
+
extra_rdoc_files: []
|
121
|
+
|
122
|
+
files:
|
123
|
+
- lib/generators/versionist/inflector_fixes.rb
|
124
|
+
- lib/generators/versionist/new_api_version/new_api_version_generator.rb
|
125
|
+
- lib/generators/versionist/new_api_version/templates/base_controller.rb
|
126
|
+
- lib/generators/versionist/new_api_version/templates/base_controller_spec.rb
|
127
|
+
- lib/generators/versionist/new_api_version/templates/base_controller_test.rb
|
128
|
+
- lib/generators/versionist/new_api_version/templates/base_presenter.rb
|
129
|
+
- lib/generators/versionist/new_api_version/templates/base_presenter_spec.rb
|
130
|
+
- lib/generators/versionist/new_api_version/templates/base_presenter_test.rb
|
131
|
+
- lib/generators/versionist/new_api_version/templates/docs_index.rb
|
132
|
+
- lib/generators/versionist/new_api_version/templates/docs_style.rb
|
133
|
+
- lib/generators/versionist/new_api_version/USAGE
|
134
|
+
- lib/generators/versionist/new_controller/new_controller_generator.rb
|
135
|
+
- lib/generators/versionist/new_controller/templates/new_controller.rb
|
136
|
+
- lib/generators/versionist/new_controller/templates/new_controller_spec.rb
|
137
|
+
- lib/generators/versionist/new_controller/templates/new_controller_test.rb
|
138
|
+
- lib/generators/versionist/new_controller/USAGE
|
139
|
+
- lib/generators/versionist/new_presenter/new_presenter_generator.rb
|
140
|
+
- lib/generators/versionist/new_presenter/templates/new_presenter.rb
|
141
|
+
- lib/generators/versionist/new_presenter/templates/new_presenter_spec.rb
|
142
|
+
- lib/generators/versionist/new_presenter/templates/new_presenter_test.rb
|
143
|
+
- lib/generators/versionist/new_presenter/USAGE
|
144
|
+
- lib/versionist/configuration.rb
|
145
|
+
- lib/versionist/middleware.rb
|
146
|
+
- lib/versionist/railtie.rb
|
147
|
+
- lib/versionist/routing.rb
|
148
|
+
- lib/versionist/version.rb
|
149
|
+
- lib/versionist/versioning_strategy/base.rb
|
150
|
+
- lib/versionist/versioning_strategy/header.rb
|
151
|
+
- lib/versionist/versioning_strategy/parameter.rb
|
152
|
+
- lib/versionist/versioning_strategy/path.rb
|
153
|
+
- lib/versionist/versioning_strategy.rb
|
154
|
+
- lib/versionist.rb
|
155
|
+
homepage: https://github.com/bploetz/versionist
|
156
|
+
licenses: []
|
157
|
+
|
158
|
+
post_install_message:
|
159
|
+
rdoc_options:
|
160
|
+
- --charset=UTF-8
|
161
|
+
require_paths:
|
162
|
+
- lib
|
163
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
164
|
+
none: false
|
165
|
+
requirements:
|
166
|
+
- - ">="
|
167
|
+
- !ruby/object:Gem::Version
|
168
|
+
version: "0"
|
169
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
170
|
+
none: false
|
171
|
+
requirements:
|
172
|
+
- - ">="
|
173
|
+
- !ruby/object:Gem::Version
|
174
|
+
version: 1.3.6
|
175
|
+
requirements: []
|
176
|
+
|
177
|
+
rubyforge_project:
|
178
|
+
rubygems_version: 1.8.17
|
179
|
+
signing_key:
|
180
|
+
specification_version: 3
|
181
|
+
summary: versionist-0.1.0
|
182
|
+
test_files: []
|
183
|
+
|