versionist 0.1.3 → 0.2.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.
@@ -0,0 +1,19 @@
1
+ Description:
2
+ Copies an existing API version to a new API version.
3
+
4
+ Example:
5
+ rails generate versionist:copy_api_version v2.0.0 V2_0_0 v3.0.0 V3_0_0
6
+
7
+ This will do the following:
8
+
9
+ route api_version(:module => "V3__0__0", :header=>"Accept", :value=>"application/vnd.mycompany.com-v3.0.0") do
10
+ end
11
+ Copying all files from app/controllers/v2_0_0 to app/controllers/v3_0_0
12
+ Copying all files from spec/controllers/v2_0_0 to spec/controllers/v3_0_0
13
+ Copying all files from app/presenters/v2_0_0 to app/presenters/v3_0_0
14
+ Copying all files from spec/presenters/v2_0_0 to spec/presenters/v3_0_0
15
+ Copying all files from public/docs/v2.0.0 to public/docs/v3.0.0
16
+
17
+ Note: routes can only be copied with MRI Ruby 1.9 and above, as this feature relies on Ripper which is only available
18
+ in stdlib in MRI Ruby 1.9 and above. Outside of routes copying, the other copy steps will work just fine in Ruby 1.8 and other
19
+ non-MRI Ruby implementations.
@@ -0,0 +1,134 @@
1
+ require 'yard'
2
+ require 'fileutils'
3
+
4
+ module Versionist
5
+ class CopyApiVersionGenerator < Rails::Generators::Base
6
+ include InflectorFixes
7
+
8
+ desc "copies an existing API version a new API version"
9
+
10
+ source_root File.expand_path('../templates', __FILE__)
11
+
12
+ argument :old_version, :type => :string
13
+ argument :old_module_name, :type => :string
14
+ argument :new_version, :type => :string
15
+ argument :new_module_name, :type => :string
16
+
17
+ def validate_old_version
18
+ in_root do
19
+ api_version_block = /api_version.*:module\s*(=>|:)\s*("|')#{module_name_for_route(old_module_name)}("|').*do/
20
+ matching_version_blocks = File.readlines("config/routes.rb").grep(api_version_block)
21
+ raise "old API version #{old_module_name} not found in config/routes.rb" if matching_version_blocks.empty?
22
+ raise "old API version module namespace #{old_module_name} not found in app/controllers" if !File.exists?("app/controllers/#{module_name_for_path(old_module_name)}")
23
+ raise "old API version module namespace #{old_module_name} not found in app/presenters" if !File.exists?("app/presenters/#{module_name_for_path(old_module_name)}")
24
+ case Versionist.configuration.configured_test_framework
25
+ when :test_unit
26
+ raise "old API version module namespace #{old_module_name} not found in test/functional/#{module_name_for_path(old_module_name)}" if !File.exists?("test/functional/#{module_name_for_path(old_module_name)}")
27
+ raise "old API version module namespace #{old_module_name} not found in test/presenters/#{module_name_for_path(old_module_name)}" if !File.exists?("test/presenters/#{module_name_for_path(old_module_name)}")
28
+ when :rspec
29
+ raise "old API version module namespace #{old_module_name} not found in spec/controllers/#{module_name_for_path(old_module_name)}" if !File.exists?("spec/controllers/#{module_name_for_path(old_module_name)}")
30
+ raise "old API version module namespace #{old_module_name} not found in spec/presenters/#{module_name_for_path(old_module_name)}" if !File.exists?("spec/presenters/#{module_name_for_path(old_module_name)}")
31
+ end
32
+ raise "old API version #{old_version} not found in public/docs" if !File.exists?("public/docs/#{old_version}")
33
+ end
34
+ end
35
+
36
+ def copy_routes
37
+ in_root do
38
+ if RUBY_VERSION =~ /1.8/ || !defined?(RUBY_ENGINE) || RUBY_ENGINE != "ruby"
39
+ log "ERROR: Cannot copy routes as this feature relies on the Ripper library, which is only available in MRI 1.9."
40
+ return
41
+ end
42
+ parser = YARD::Parser::SourceParser.parse_string(File.read("config/routes.rb"))
43
+ existing_routes = nil
44
+ parser.enumerator.first.traverse do |node|
45
+ existing_routes = node.source if node.type == :fcall && node.source =~ /api_version.*:module\s*(=>|:)\s*("|')#{module_name_for_route(old_module_name)}("|')/
46
+ end
47
+ copied_routes = String.new(existing_routes)
48
+ copied_routes.gsub!(/"#{module_name_for_route(old_module_name)}"/, "\"#{module_name_for_route(new_module_name)}\"")
49
+ copied_routes.gsub!(/#{old_version}/, new_version)
50
+ route copied_routes
51
+ end
52
+ end
53
+
54
+ def copy_controllers
55
+ in_root do
56
+ log "Copying all files from app/controllers/#{module_name_for_path(old_module_name)} to app/controllers/#{module_name_for_path(new_module_name)}"
57
+ FileUtils.cp_r "app/controllers/#{module_name_for_path(old_module_name)}", "app/controllers/#{module_name_for_path(new_module_name)}"
58
+ Dir.glob("app/controllers/#{module_name_for_path(new_module_name)}/*.rb").each do |f|
59
+ text = File.read(f)
60
+ File.open(f, 'w') {|f| f << text.gsub(/#{old_module_name}/, new_module_name)}
61
+ end
62
+ end
63
+ end
64
+
65
+ # due to the inflector quirks we can't use hook_for :test_framework
66
+ def copy_controller_tests
67
+ in_root do
68
+ case Versionist.configuration.configured_test_framework
69
+ when :test_unit
70
+ log "Copying all files from test/functional/#{module_name_for_path(old_module_name)} to test/functional/#{module_name_for_path(new_module_name)}"
71
+ FileUtils.cp_r "test/functional/#{module_name_for_path(old_module_name)}", "test/functional/#{module_name_for_path(new_module_name)}"
72
+ Dir.glob("test/functional/#{module_name_for_path(new_module_name)}/*.rb").each do |f|
73
+ text = File.read(f)
74
+ File.open(f, 'w') {|f| f << text.gsub(/#{old_module_name}/, new_module_name)}
75
+ end
76
+ when :rspec
77
+ log "Copying all files from spec/controllers/#{module_name_for_path(old_module_name)} to spec/controllers/#{module_name_for_path(new_module_name)}"
78
+ FileUtils.cp_r "spec/controllers/#{module_name_for_path(old_module_name)}", "spec/controllers/#{module_name_for_path(new_module_name)}"
79
+ Dir.glob("spec/controllers/#{module_name_for_path(new_module_name)}/*.rb").each do |f|
80
+ text = File.read(f)
81
+ File.open(f, 'w') {|f| f << text.gsub(/#{old_module_name}/, new_module_name)}
82
+ end
83
+ else
84
+ say "Unsupported test_framework: #{Versionist.configuration.configured_test_framework}"
85
+ end
86
+ end
87
+ end
88
+
89
+ def copy_presenters
90
+ in_root do
91
+ log "Copying all files from app/presenters/#{module_name_for_path(old_module_name)} to app/presenters/#{module_name_for_path(new_module_name)}"
92
+ FileUtils.cp_r "app/presenters/#{module_name_for_path(old_module_name)}", "app/presenters/#{module_name_for_path(new_module_name)}"
93
+ Dir.glob("app/presenters/#{module_name_for_path(new_module_name)}/*.rb").each do |f|
94
+ text = File.read(f)
95
+ File.open(f, 'w') {|f| f << text.gsub(/#{old_module_name}/, new_module_name)}
96
+ end
97
+ end
98
+ end
99
+
100
+ def copy_presenter_tests
101
+ in_root do
102
+ case Versionist.configuration.configured_test_framework
103
+ when :test_unit
104
+ log "Copying all files from test/presenters/#{module_name_for_path(old_module_name)} to test/presenters/#{module_name_for_path(new_module_name)}"
105
+ FileUtils.cp_r "test/presenters/#{module_name_for_path(old_module_name)}", "test/presenters/#{module_name_for_path(new_module_name)}"
106
+ Dir.glob("test/presenters/#{module_name_for_path(new_module_name)}/*.rb").each do |f|
107
+ text = File.read(f)
108
+ File.open(f, 'w') {|f| f << text.gsub(/#{old_module_name}/, new_module_name)}
109
+ end
110
+ when :rspec
111
+ log "Copying all files from spec/presenters/#{module_name_for_path(old_module_name)} to spec/presenters/#{module_name_for_path(new_module_name)}"
112
+ FileUtils.cp_r "spec/presenters/#{module_name_for_path(old_module_name)}", "spec/presenters/#{module_name_for_path(new_module_name)}"
113
+ Dir.glob("spec/presenters/#{module_name_for_path(new_module_name)}/*.rb").each do |f|
114
+ text = File.read(f)
115
+ File.open(f, 'w') {|f| f << text.gsub(/#{old_module_name}/, new_module_name)}
116
+ end
117
+ else
118
+ say "Unsupported test_framework: #{Versionist.configuration.configured_test_framework}"
119
+ end
120
+ end
121
+ end
122
+
123
+ def copy_documentation
124
+ in_root do
125
+ log "Copying all files from public/docs/#{old_version} to public/docs/#{new_version}"
126
+ FileUtils.cp_r "public/docs/#{old_version}", "public/docs/#{new_version}"
127
+ Dir.glob("public/docs/#{new_version}/*.html").each do |f|
128
+ text = File.read(f)
129
+ File.open(f, 'w') {|f| f << text.gsub(/#{old_version}/, new_version)}
130
+ end
131
+ end
132
+ end
133
+ end
134
+ end
@@ -12,7 +12,7 @@ module Versionist
12
12
 
13
13
  def add_routes
14
14
  in_root do
15
- api_version_block = /api_version.*:module\s*(=>|:)\s*("|')#{module_name_for_route(module_name)}("|').*do/
15
+ api_version_block = /api_version.*:module\s*(=>|:)\s*("|')#{module_name_for_route(module_name)}("|')/
16
16
  matching_version_blocks = File.readlines("config/routes.rb").grep(api_version_block)
17
17
  raise "API version already exists in config/routes.rb" if !matching_version_blocks.empty?
18
18
  versioning_strategy.symbolize_keys!
@@ -28,15 +28,19 @@ module Versionist
28
28
  end
29
29
 
30
30
  # due to the inflector quirks we can't use hook_for :test_framework
31
- def add_controller_base_test
31
+ def add_controller_base_tests
32
32
  in_root do
33
33
  case Versionist.configuration.configured_test_framework
34
34
  when :test_unit
35
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")
36
+ template 'base_controller_functional_test.rb', File.join("test", "functional", "#{module_name_for_path(module_name)}", "base_controller_test.rb")
37
+ empty_directory "test/integration/#{module_name_for_path(module_name)}"
38
+ template 'base_controller_integration_test.rb', File.join("test", "integration", "#{module_name_for_path(module_name)}", "base_controller_test.rb")
37
39
  when :rspec
38
40
  empty_directory "spec/controllers/#{module_name_for_path(module_name)}"
39
41
  template 'base_controller_spec.rb', File.join("spec", "controllers", "#{module_name_for_path(module_name)}", "base_controller_spec.rb")
42
+ empty_directory "spec/requests/#{module_name_for_path(module_name)}"
43
+ template 'base_controller_spec.rb', File.join("spec", "requests", "#{module_name_for_path(module_name)}", "base_controller_spec.rb")
40
44
  else
41
45
  say "Unsupported test_framework: #{Versionist.configuration.configured_test_framework}"
42
46
  end
@@ -1,7 +1,6 @@
1
1
  require 'test_helper'
2
2
 
3
- class <%= module_name %>::<%= class_name%>Controller < ActionController::TestCase
4
-
3
+ class <%= module_name %>::BaseControllerTest < ActionDispatch::IntegrationTest
5
4
  # Replace this with your real tests.
6
5
  test "the truth" do
7
6
  assert true
@@ -1,6 +1,6 @@
1
1
  require 'test_helper'
2
2
 
3
- class <%= module_name %>::BaseControllerTest < Test::Unit::TestCase
3
+ class <%= module_name %>::BasePresenterTest < Test::Unit::TestCase
4
4
  # Replace this with your real tests.
5
5
  test "the truth" do
6
6
  assert true
@@ -1,5 +1,5 @@
1
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;}
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;}
@@ -12,7 +12,7 @@ module Versionist
12
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
13
  template 'new_controller.rb', File.join("app", "controllers", "#{module_name_for_path(module_name)}", "#{file_name}_controller.rb")
14
14
 
15
- api_version_block = /api_version.*:module\s*(=>|:)\s*("|')#{module_name_for_route(module_name)}("|').*do/
15
+ api_version_block = /api_version.*:module\s*(=>|:)\s*("|')#{module_name_for_route(module_name)}("|')/
16
16
  new_route = " resources :#{file_name}\n"
17
17
  matching_version_blocks = File.readlines("config/routes.rb").grep(api_version_block)
18
18
  if matching_version_blocks.empty?
@@ -27,13 +27,15 @@ module Versionist
27
27
  end
28
28
 
29
29
  # due to the inflector quirks we can't use hook_for :test_framework
30
- def new_controller_test
30
+ def new_controller_tests
31
31
  in_root do
32
32
  case Versionist.configuration.configured_test_framework
33
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")
34
+ template 'new_controller_functional_test.rb', File.join("test", "functional", "#{module_name_for_path(module_name)}", "#{file_name}_controller_test.rb")
35
+ template 'new_controller_integration_test.rb', File.join("test", "integration", "#{module_name_for_path(module_name)}", "#{file_name}_controller_test.rb")
35
36
  when :rspec
36
37
  template 'new_controller_spec.rb', File.join("spec", "controllers", "#{module_name_for_path(module_name)}", "#{file_name}_controller_spec.rb")
38
+ template 'new_controller_spec.rb', File.join("spec", "requests", "#{module_name_for_path(module_name)}", "#{file_name}_controller_spec.rb")
37
39
  else
38
40
  say "Unsupported test_framework: #{Versionist.configuration.configured_test_framework}"
39
41
  end
@@ -0,0 +1,9 @@
1
+ require 'test_helper'
2
+
3
+ class <%= module_name %>::<%= class_name%>ControllerTest < 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,9 @@
1
+ require 'test_helper'
2
+
3
+ class <%= module_name %>::<%= class_name%>ControllerTest < ActionDispatch::IntegrationTest
4
+
5
+ # Replace this with your real tests.
6
+ test "the truth" do
7
+ assert true
8
+ end
9
+ end
@@ -1,4 +1,4 @@
1
- class <%= module_name %>::<%= class_name%>Presenter
1
+ class <%= module_name %>::<%= class_name%>Presenter < <%= module_name %>::BasePresenter
2
2
 
3
3
  def initialize(<%= file_name %>)
4
4
  @<%= file_name %> = <%= file_name %>
@@ -12,6 +12,7 @@ module Versionist
12
12
  raise ArgumentError, "you must pass a configuration Hash to api_version" if config.nil? || !config.is_a?(Hash)
13
13
  raise ArgumentError, "you must specify :module in configuration Hash passed to api_version" if !config.has_key?(:module)
14
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
+ raise ArgumentError, ":defaults must be a Hash" if config.has_key?(:defaults) && !config[:defaults].is_a?(Hash)
15
16
  if config.has_key?(:header)
16
17
  return configure_header(config, &block)
17
18
  elsif config.has_key?(:path)
@@ -26,22 +27,28 @@ module Versionist
26
27
 
27
28
  def configure_header(config, &block)
28
29
  header = Versionist::VersioningStrategy::Header.new(config)
29
- scope({:module => config[:module], :constraints => header}, &block)
30
+ route_hash = {:module => config[:module], :constraints => header}
31
+ route_hash.merge!({:defaults => config[:defaults]}) if config.has_key?(:defaults)
32
+ scope(route_hash, &block)
30
33
  end
31
34
 
32
35
  def configure_path(config, &block)
33
36
  path = Versionist::VersioningStrategy::Path.new(config)
34
37
  # Use the :as option and strip out non-word characters from the path to avoid this:
35
38
  # https://github.com/rails/rails/issues/3224
36
- namespace(config[:path], {:module => config[:module], :as => config[:path].gsub(/\W/, '_')}, &block)
39
+ route_hash = {:module => config[:module], :as => config[:path].gsub(/\W/, '_')}
40
+ route_hash.merge!({:defaults => config[:defaults]}) if config.has_key?(:defaults)
41
+ namespace(config[:path], route_hash, &block)
37
42
  if path.default?
38
- scope({:module => config[:module], :as => config[:path].gsub(/\W/, '_')}, &block)
43
+ scope(route_hash, &block)
39
44
  end
40
45
  end
41
46
 
42
47
  def configure_parameter(config, &block)
43
48
  parameter = Versionist::VersioningStrategy::Parameter.new(config)
44
- scope({:module => config[:module], :constraints => parameter}, &block)
49
+ route_hash = {:module => config[:module], :constraints => parameter}
50
+ route_hash.merge!({:defaults => config[:defaults]}) if config.has_key?(:defaults)
51
+ scope(route_hash, &block)
45
52
  end
46
53
  end
47
54
  end
@@ -1,3 +1,3 @@
1
1
  module Versionist
2
- VERSION = '0.1.3'
2
+ VERSION = '0.2.0'
3
3
  end
data/lib/versionist.rb CHANGED
@@ -5,6 +5,7 @@ module Versionist
5
5
 
6
6
  autoload :Configuration
7
7
  autoload :InflectorFixes, "generators/versionist/inflector_fixes"
8
+ autoload :CopyApiVersionGenerator, "generators/versionist/copy_api_version/copy_api_version_generator"
8
9
  autoload :NewApiVersionGenerator, "generators/versionist/new_api_version/new_api_version_generator"
9
10
  autoload :NewControllerGenerator, "generators/versionist/new_controller/new_controller_generator"
10
11
  autoload :NewPresenterGenerator, "generators/versionist/new_presenter/new_presenter_generator"
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: versionist
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.1.3
5
+ version: 0.2.0
6
6
  platform: ruby
7
7
  authors:
8
8
  - Brian Ploetz
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2012-04-17 00:00:00 Z
13
+ date: 2012-04-25 00:00:00 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rails
@@ -23,6 +23,17 @@ dependencies:
23
23
  version: "3.0"
24
24
  type: :runtime
25
25
  version_requirements: *id001
26
+ - !ruby/object:Gem::Dependency
27
+ name: yard
28
+ prerelease: false
29
+ requirement: &id002 !ruby/object:Gem::Requirement
30
+ none: false
31
+ requirements:
32
+ - - ~>
33
+ - !ruby/object:Gem::Version
34
+ version: "0.7"
35
+ type: :runtime
36
+ version_requirements: *id002
26
37
  description: A plugin for versioning Rails 3 based RESTful APIs.
27
38
  email:
28
39
  executables: []
@@ -32,11 +43,14 @@ extensions: []
32
43
  extra_rdoc_files: []
33
44
 
34
45
  files:
46
+ - lib/generators/versionist/copy_api_version/copy_api_version_generator.rb
47
+ - lib/generators/versionist/copy_api_version/USAGE
35
48
  - lib/generators/versionist/inflector_fixes.rb
36
49
  - lib/generators/versionist/new_api_version/new_api_version_generator.rb
37
50
  - lib/generators/versionist/new_api_version/templates/base_controller.rb
51
+ - lib/generators/versionist/new_api_version/templates/base_controller_functional_test.rb
52
+ - lib/generators/versionist/new_api_version/templates/base_controller_integration_test.rb
38
53
  - lib/generators/versionist/new_api_version/templates/base_controller_spec.rb
39
- - lib/generators/versionist/new_api_version/templates/base_controller_test.rb
40
54
  - lib/generators/versionist/new_api_version/templates/base_presenter.rb
41
55
  - lib/generators/versionist/new_api_version/templates/base_presenter_spec.rb
42
56
  - lib/generators/versionist/new_api_version/templates/base_presenter_test.rb
@@ -45,8 +59,9 @@ files:
45
59
  - lib/generators/versionist/new_api_version/USAGE
46
60
  - lib/generators/versionist/new_controller/new_controller_generator.rb
47
61
  - lib/generators/versionist/new_controller/templates/new_controller.rb
62
+ - lib/generators/versionist/new_controller/templates/new_controller_functional_test.rb
63
+ - lib/generators/versionist/new_controller/templates/new_controller_integration_test.rb
48
64
  - lib/generators/versionist/new_controller/templates/new_controller_spec.rb
49
- - lib/generators/versionist/new_controller/templates/new_controller_test.rb
50
65
  - lib/generators/versionist/new_controller/USAGE
51
66
  - lib/generators/versionist/new_presenter/new_presenter_generator.rb
52
67
  - lib/generators/versionist/new_presenter/templates/new_presenter.rb
@@ -90,6 +105,7 @@ rubyforge_project:
90
105
  rubygems_version: 1.8.17
91
106
  signing_key:
92
107
  specification_version: 3
93
- summary: versionist-0.1.3
108
+ summary: versionist-0.2.0
94
109
  test_files: []
95
110
 
111
+ has_rdoc: