versionist 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. data/lib/generators/versionist/inflector_fixes.rb +14 -0
  2. data/lib/generators/versionist/new_api_version/USAGE +19 -0
  3. data/lib/generators/versionist/new_api_version/new_api_version_generator.rb +76 -0
  4. data/lib/generators/versionist/new_api_version/templates/base_controller.rb +2 -0
  5. data/lib/generators/versionist/new_api_version/templates/base_controller_spec.rb +5 -0
  6. data/lib/generators/versionist/new_api_version/templates/base_controller_test.rb +8 -0
  7. data/lib/generators/versionist/new_api_version/templates/base_presenter.rb +2 -0
  8. data/lib/generators/versionist/new_api_version/templates/base_presenter_spec.rb +5 -0
  9. data/lib/generators/versionist/new_api_version/templates/base_presenter_test.rb +8 -0
  10. data/lib/generators/versionist/new_api_version/templates/docs_index.rb +17 -0
  11. data/lib/generators/versionist/new_api_version/templates/docs_style.rb +5 -0
  12. data/lib/generators/versionist/new_controller/USAGE +10 -0
  13. data/lib/generators/versionist/new_controller/new_controller_generator.rb +43 -0
  14. data/lib/generators/versionist/new_controller/templates/new_controller.rb +2 -0
  15. data/lib/generators/versionist/new_controller/templates/new_controller_spec.rb +5 -0
  16. data/lib/generators/versionist/new_controller/templates/new_controller_test.rb +9 -0
  17. data/lib/generators/versionist/new_presenter/USAGE +10 -0
  18. data/lib/generators/versionist/new_presenter/new_presenter_generator.rb +30 -0
  19. data/lib/generators/versionist/new_presenter/templates/new_presenter.rb +15 -0
  20. data/lib/generators/versionist/new_presenter/templates/new_presenter_spec.rb +5 -0
  21. data/lib/generators/versionist/new_presenter/templates/new_presenter_test.rb +8 -0
  22. data/lib/versionist.rb +20 -0
  23. data/lib/versionist/configuration.rb +15 -0
  24. data/lib/versionist/middleware.rb +39 -0
  25. data/lib/versionist/railtie.rb +18 -0
  26. data/lib/versionist/routing.rb +47 -0
  27. data/lib/versionist/version.rb +3 -0
  28. data/lib/versionist/versioning_strategy.rb +10 -0
  29. data/lib/versionist/versioning_strategy/base.rb +26 -0
  30. data/lib/versionist/versioning_strategy/header.rb +23 -0
  31. data/lib/versionist/versioning_strategy/parameter.rb +23 -0
  32. data/lib/versionist/versioning_strategy/path.rb +15 -0
  33. 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,2 @@
1
+ class <%= module_name %>::BaseController < ApplicationController
2
+ end
@@ -0,0 +1,5 @@
1
+ require 'spec_helper'
2
+
3
+ describe <%= module_name %>::BaseController do
4
+
5
+ end
@@ -0,0 +1,8 @@
1
+ require 'test_helper'
2
+
3
+ class <%= module_name %>::BaseControllerTest < ActionController::TestCase
4
+ # Replace this with your real tests.
5
+ test "the truth" do
6
+ assert true
7
+ end
8
+ end
@@ -0,0 +1,2 @@
1
+ class <%= module_name %>::BasePresenter
2
+ end
@@ -0,0 +1,5 @@
1
+ require 'spec_helper'
2
+
3
+ describe <%= module_name %>::BasePresenter do
4
+
5
+ end
@@ -0,0 +1,8 @@
1
+ require 'test_helper'
2
+
3
+ class <%= module_name %>::BaseControllerTest < Test::Unit::TestCase
4
+ # Replace this with your real tests.
5
+ test "the truth" do
6
+ assert true
7
+ end
8
+ 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,5 @@
1
+ body {margin: 0; background-color: #fff; color: #000; font-family: Arial,sans-serif;}
2
+ #content {margin-left: 200px;}
3
+ #content h1 {text-align: center;}
4
+ #operations {float: left; width: 200px; border-right: 1px solid #ccc;}
5
+ #operations h3 {text-align: center;}
@@ -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,2 @@
1
+ class <%= module_name %>::<%= class_name%>Controller < <%= module_name %>::BaseController
2
+ end
@@ -0,0 +1,5 @@
1
+ require 'spec_helper'
2
+
3
+ describe <%= module_name %>::<%= class_name%>Controller do
4
+
5
+ end
@@ -0,0 +1,9 @@
1
+ require 'test_helper'
2
+
3
+ class <%= module_name %>::<%= class_name%>Controller < ActionController::TestCase
4
+
5
+ # Replace this with your real tests.
6
+ test "the truth" do
7
+ assert true
8
+ end
9
+ 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
@@ -0,0 +1,5 @@
1
+ require 'spec_helper'
2
+
3
+ describe <%= module_name %>::<%= class_name%>Presenter do
4
+
5
+ end
@@ -0,0 +1,8 @@
1
+ require 'test_helper'
2
+
3
+ class <%= module_name %>::<%= class_name%>PresenterTest < Test::Unit::TestCase
4
+ # Replace this with your real tests.
5
+ test "the truth" do
6
+ assert true
7
+ end
8
+ end
@@ -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,3 @@
1
+ module Versionist
2
+ VERSION = '0.1.0'
3
+ 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
+