versionist 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
|