Permalink
Browse files

Issue #6: Copy API Generator

  • Loading branch information...
Brian Ploetz
Brian Ploetz committed Apr 13, 2012
1 parent 1439b70 commit c952cf62bec7b4e045aaf5544be8cf880c8863d7
View
@@ -191,6 +191,8 @@ To see the available generators, simply run `rails generate`, and you will see t
The following generators are available:
+### `versionist:new_api_version`
+
`versionist:new_api_version` - creates the infrastructure for a new API version. This will create:
- A new controller namespace, base controller and test
@@ -219,6 +221,8 @@ Example:
create public/docs/v2.0.0/style.css
+### `versionist:new_controller`
+
`versionist:new_controller` - creates a new controller class with the given name under the given version module.
Usage
@@ -232,6 +236,8 @@ Example:
create spec/controllers/v2_0_0/foos_controller_spec.rb
+### `versionist:new_presenter`
+
`versionist:new_presenter` - creates a new presenter class with the given name under the given version module.
Usage
@@ -243,3 +249,28 @@ Example:
rails generate versionist:new_presenter foos V2_0_0
create app/presenters/v2_0_0/foos_presenter.rb
create spec/presenters/v2_0_0/foos_presenter_spec.rb
+
+
+### `versionist:copy_api_version`
+
+`versionist:copy_api_version` - copies an existing API version to a new API version. This will do the following:
+
+- Copy all existing routes in config/routes.rb from the old API version to routes for the new API version in config/routes.rb
+- Copy all existing controllers and tests from the old API version to the new API version
+- Copy all existing presenters and tests from the old API version to the new API version
+- Copy all documentation from the old API version to the new API version
+
+Usage
+
+ rails generate versionist:copy_api_version <old version> <old module namespace> <new version> <new module namespace>
+
+Example:
+
+ rails generate versionist:copy_api_version v2.0.0 V2_0_0 v3.0.0 V3_0_0
+ route api_version(:module => "V3__0__0", :header=>"Accept", :value=>"application/vnd.mycompany.com-v3.0.0") do
+ end
+ Copying all files from app/controllers/v2_0_0 to app/controllers/v3_0_0
+ Copying all files from spec/controllers/v2_0_0 to spec/controllers/v3_0_0
+ Copying all files from app/presenters/v2_0_0 to app/presenters/v3_0_0
+ Copying all files from spec/presenters/v2_0_0 to spec/presenters/v3_0_0
+ Copying all files from public/docs/v2.0.0 to public/docs/v3.0.0
View
@@ -9,7 +9,7 @@ group :development do
gem 'rake', '>= 0.9.2'
gem 'rspec', '2.8.0'
gem 'rspec-rails', '2.8.0'
- gem 'generator_spec', '0.8.4'
+ gem 'generator_spec', '0.8.5'
gem 'rdoc', '>= 3.11'
gem 'simplecov', '0.5.4'
end
View
@@ -3,6 +3,7 @@ PATH
specs:
versionist (0.1.3)
rails (~> 3.0)
+ yard (~> 0.7)
GEM
remote: http://rubygems.org/
@@ -40,7 +41,7 @@ GEM
diff-lcs (1.1.3)
erubis (2.6.6)
abstract (>= 1.0.0)
- generator_spec (0.8.4)
+ generator_spec (0.8.5)
rails (>= 3.0, < 4.0)
rspec-rails
i18n (0.5.0)
@@ -97,13 +98,14 @@ GEM
polyglot
polyglot (>= 0.3.1)
tzinfo (0.3.33)
+ yard (0.7.5)
PLATFORMS
ruby
DEPENDENCIES
awesome_print (= 1.0.2)
- generator_spec (= 0.8.4)
+ generator_spec (= 0.8.5)
rails (~> 3.0.0)
rake (>= 0.9.2)
rdoc (>= 3.11)
View
@@ -9,7 +9,7 @@ group :development do
gem 'rake', '>= 0.9.2'
gem 'rspec', '2.8.0'
gem 'rspec-rails', '2.8.0'
- gem 'generator_spec', '0.8.4'
+ gem 'generator_spec', '0.8.5'
gem 'rdoc', '>= 3.11'
gem 'simplecov', '0.5.4'
end
View
@@ -3,6 +3,7 @@ PATH
specs:
versionist (0.1.3)
rails (~> 3.0)
+ yard (~> 0.7)
GEM
remote: http://rubygems.org/
@@ -40,7 +41,7 @@ GEM
builder (3.0.0)
diff-lcs (1.1.3)
erubis (2.7.0)
- generator_spec (0.8.4)
+ generator_spec (0.8.5)
rails (>= 3.0, < 4.0)
rspec-rails
hike (1.2.1)
@@ -107,13 +108,14 @@ GEM
polyglot
polyglot (>= 0.3.1)
tzinfo (0.3.33)
+ yard (0.7.5)
PLATFORMS
ruby
DEPENDENCIES
awesome_print (= 1.0.2)
- generator_spec (= 0.8.4)
+ generator_spec (= 0.8.5)
rails (~> 3.1.0)
rake (>= 0.9.2)
rdoc (>= 3.11)
View
@@ -9,7 +9,7 @@ group :development do
gem 'rake', '>= 0.9.2'
gem 'rspec', '2.8.0'
gem 'rspec-rails', '2.8.0'
- gem 'generator_spec', '0.8.4'
+ gem 'generator_spec', '0.8.5'
gem 'rdoc', '>= 3.11'
gem 'simplecov', '0.5.4'
end
View
@@ -3,6 +3,7 @@ PATH
specs:
versionist (0.1.3)
rails (~> 3.0)
+ yard (~> 0.7)
GEM
remote: http://rubygems.org/
@@ -39,7 +40,7 @@ GEM
builder (3.0.0)
diff-lcs (1.1.3)
erubis (2.7.0)
- generator_spec (0.8.4)
+ generator_spec (0.8.5)
rails (>= 3.0, < 4.0)
rspec-rails
hike (1.2.1)
@@ -105,13 +106,14 @@ GEM
polyglot
polyglot (>= 0.3.1)
tzinfo (0.3.33)
+ yard (0.7.5)
PLATFORMS
ruby
DEPENDENCIES
awesome_print (= 1.0.2)
- generator_spec (= 0.8.4)
+ generator_spec (= 0.8.5)
rails (~> 3.2.0)
rake (>= 0.9.2)
rdoc (>= 3.11)
@@ -0,0 +1,15 @@
+Description:
+ Copies an existing API version to a new API version.
+
+Example:
+ rails generate versionist:copy_api_version v2.0.0 V2_0_0 v3.0.0 V3_0_0
+
+ This will do the following:
+
+ route api_version(:module => "V3__0__0", :header=>"Accept", :value=>"application/vnd.mycompany.com-v3.0.0") do
+ end
+ Copying all files from app/controllers/v2_0_0 to app/controllers/v3_0_0
+ Copying all files from spec/controllers/v2_0_0 to spec/controllers/v3_0_0
+ Copying all files from app/presenters/v2_0_0 to app/presenters/v3_0_0
+ Copying all files from spec/presenters/v2_0_0 to spec/presenters/v3_0_0
+ Copying all files from public/docs/v2.0.0 to public/docs/v3.0.0
@@ -0,0 +1,130 @@
+require 'yard'
+require 'fileutils'
+
+module Versionist
+ class CopyApiVersionGenerator < Rails::Generators::Base
+ include InflectorFixes
+
+ desc "copies an existing API version a new API version"
+
+ source_root File.expand_path('../templates', __FILE__)
+
+ argument :old_version, :type => :string
+ argument :old_module_name, :type => :string
+ argument :new_version, :type => :string
+ argument :new_module_name, :type => :string
+
+ def validate_old_version
+ in_root do
+ api_version_block = /api_version.*:module\s*(=>|:)\s*("|')#{module_name_for_route(old_module_name)}("|').*do/
+ matching_version_blocks = File.readlines("config/routes.rb").grep(api_version_block)
+ raise "old API version #{old_module_name} not found in config/routes.rb" if matching_version_blocks.empty?
+ 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)}")
+ 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)}")
+ case Versionist.configuration.configured_test_framework
+ when :test_unit
+ 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)}")
+ 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)}")
+ when :rspec
+ 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)}")
+ 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)}")
+ end
+ raise "old API version #{old_version} not found in public/docs" if !File.exists?("public/docs/#{old_version}")
+ end
+ end
+
+ def copy_routes
+ in_root do
+ parser = YARD::Parser::SourceParser.parse_string(File.read("config/routes.rb"))
+ existing_routes = nil
+ parser.enumerator.first.traverse do |node|
+ existing_routes = node.source if node.type == :fcall && node.source =~ /api_version.*:module\s*(=>|:)\s*("|')#{module_name_for_route(old_module_name)}("|')/
+ end
+ copied_routes = String.new(existing_routes)
+ copied_routes.gsub!(/"#{module_name_for_route(old_module_name)}"/, "\"#{module_name_for_route(new_module_name)}\"")
+ copied_routes.gsub!(/#{old_version}/, new_version)
+ route copied_routes
+ end
+ end
+
+ def copy_controllers
+ in_root do
+ log "Copying all files from app/controllers/#{module_name_for_path(old_module_name)} to app/controllers/#{module_name_for_path(new_module_name)}"
+ FileUtils.cp_r "app/controllers/#{module_name_for_path(old_module_name)}", "app/controllers/#{module_name_for_path(new_module_name)}"
+ Dir.glob("app/controllers/#{module_name_for_path(new_module_name)}/*.rb").each do |f|
+ text = File.read(f)
+ File.open(f, 'w') {|f| f << text.gsub(/#{old_module_name}/, new_module_name)}
+ end
+ end
+ end
+
+ # due to the inflector quirks we can't use hook_for :test_framework
+ def copy_controller_tests
+ in_root do
+ case Versionist.configuration.configured_test_framework
+ when :test_unit
+ log "Copying all files from test/functional/#{module_name_for_path(old_module_name)} to test/functional/#{module_name_for_path(new_module_name)}"
+ FileUtils.cp_r "test/functional/#{module_name_for_path(old_module_name)}", "test/functional/#{module_name_for_path(new_module_name)}"
+ Dir.glob("test/functional/#{module_name_for_path(new_module_name)}/*.rb").each do |f|
+ text = File.read(f)
+ File.open(f, 'w') {|f| f << text.gsub(/#{old_module_name}/, new_module_name)}
+ end
+ when :rspec
+ log "Copying all files from spec/controllers/#{module_name_for_path(old_module_name)} to spec/controllers/#{module_name_for_path(new_module_name)}"
+ FileUtils.cp_r "spec/controllers/#{module_name_for_path(old_module_name)}", "spec/controllers/#{module_name_for_path(new_module_name)}"
+ Dir.glob("spec/controllers/#{module_name_for_path(new_module_name)}/*.rb").each do |f|
+ text = File.read(f)
+ File.open(f, 'w') {|f| f << text.gsub(/#{old_module_name}/, new_module_name)}
+ end
+ else
+ say "Unsupported test_framework: #{Versionist.configuration.configured_test_framework}"
+ end
+ end
+ end
+
+ def copy_presenters
+ in_root do
+ log "Copying all files from app/presenters/#{module_name_for_path(old_module_name)} to app/presenters/#{module_name_for_path(new_module_name)}"
+ FileUtils.cp_r "app/presenters/#{module_name_for_path(old_module_name)}", "app/presenters/#{module_name_for_path(new_module_name)}"
+ Dir.glob("app/presenters/#{module_name_for_path(new_module_name)}/*.rb").each do |f|
+ text = File.read(f)
+ File.open(f, 'w') {|f| f << text.gsub(/#{old_module_name}/, new_module_name)}
+ end
+ end
+ end
+
+ def copy_presenter_tests
+ in_root do
+ case Versionist.configuration.configured_test_framework
+ when :test_unit
+ log "Copying all files from test/presenters/#{module_name_for_path(old_module_name)} to test/presenters/#{module_name_for_path(new_module_name)}"
+ FileUtils.cp_r "test/presenters/#{module_name_for_path(old_module_name)}", "test/presenters/#{module_name_for_path(new_module_name)}"
+ Dir.glob("test/presenters/#{module_name_for_path(new_module_name)}/*.rb").each do |f|
+ text = File.read(f)
+ File.open(f, 'w') {|f| f << text.gsub(/#{old_module_name}/, new_module_name)}
+ end
+ when :rspec
+ log "Copying all files from spec/presenters/#{module_name_for_path(old_module_name)} to spec/presenters/#{module_name_for_path(new_module_name)}"
+ FileUtils.cp_r "spec/presenters/#{module_name_for_path(old_module_name)}", "spec/presenters/#{module_name_for_path(new_module_name)}"
+ Dir.glob("spec/presenters/#{module_name_for_path(new_module_name)}/*.rb").each do |f|
+ text = File.read(f)
+ File.open(f, 'w') {|f| f << text.gsub(/#{old_module_name}/, new_module_name)}
+ end
+ else
+ say "Unsupported test_framework: #{Versionist.configuration.configured_test_framework}"
+ end
+ end
+ end
+
+ def copy_documentation
+ in_root do
+ log "Copying all files from public/docs/#{old_version} to public/docs/#{new_version}"
+ FileUtils.cp_r "public/docs/#{old_version}", "public/docs/#{new_version}"
+ Dir.glob("public/docs/#{new_version}/*.html").each do |f|
+ text = File.read(f)
+ File.open(f, 'w') {|f| f << text.gsub(/#{old_version}/, new_version)}
+ end
+ end
+ end
+ end
+end
@@ -12,7 +12,7 @@ class NewApiVersionGenerator < Rails::Generators::Base
def add_routes
in_root do
- api_version_block = /api_version.*:module\s*(=>|:)\s*("|')#{module_name_for_route(module_name)}("|').*do/
+ api_version_block = /api_version.*:module\s*(=>|:)\s*("|')#{module_name_for_route(module_name)}("|')/
matching_version_blocks = File.readlines("config/routes.rb").grep(api_version_block)
raise "API version already exists in config/routes.rb" if !matching_version_blocks.empty?
versioning_strategy.symbolize_keys!
@@ -1,5 +1,5 @@
body {margin: 0; background-color: #fff; color: #000; font-family: Arial,sans-serif;}
-#content {margin-left: 200px;}
-#content h1 {text-align: center;}
-#operations {float: left; width: 200px; border-right: 1px solid #ccc;}
-#operations h3 {text-align: center;}
+content {margin-left: 200px;}
+content h1 {text-align: center;}
+operations {float: left; width: 200px; border-right: 1px solid #ccc;}
+operations h3 {text-align: center;}
@@ -12,7 +12,7 @@ def new_controller
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)}")
template 'new_controller.rb', File.join("app", "controllers", "#{module_name_for_path(module_name)}", "#{file_name}_controller.rb")
- api_version_block = /api_version.*:module\s*(=>|:)\s*("|')#{module_name_for_route(module_name)}("|').*do/
+ api_version_block = /api_version.*:module\s*(=>|:)\s*("|')#{module_name_for_route(module_name)}("|')/
new_route = " resources :#{file_name}\n"
matching_version_blocks = File.readlines("config/routes.rb").grep(api_version_block)
if matching_version_blocks.empty?
View
@@ -5,6 +5,7 @@ module Versionist
autoload :Configuration
autoload :InflectorFixes, "generators/versionist/inflector_fixes"
+ autoload :CopyApiVersionGenerator, "generators/versionist/copy_api_version/copy_api_version_generator"
autoload :NewApiVersionGenerator, "generators/versionist/new_api_version/new_api_version_generator"
autoload :NewControllerGenerator, "generators/versionist/new_controller/new_controller_generator"
autoload :NewPresenterGenerator, "generators/versionist/new_presenter/new_presenter_generator"
Oops, something went wrong.

0 comments on commit c952cf6

Please sign in to comment.