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.
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
+