aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosé Valim <jose.valim@gmail.com>2009-06-28 11:56:44 +0200
committerJosé Valim <jose.valim@gmail.com>2009-06-28 11:56:44 +0200
commit496dde95fbedddad5d04afbe660ff1544229032c (patch)
tree4d6bf2643cd217d1d36a3afff26551480af4c6c5
parentc03585aa8da175888ad0893ef29d887f87fb749b (diff)
downloadrails-496dde95fbedddad5d04afbe660ff1544229032c.tar.gz
rails-496dde95fbedddad5d04afbe660ff1544229032c.tar.bz2
rails-496dde95fbedddad5d04afbe660ff1544229032c.zip
Added migrations and make base generators be lazy loaded.
-rw-r--r--railties/lib/generators.rb3
-rw-r--r--railties/lib/generators/active_record.rb50
-rw-r--r--railties/lib/generators/active_record/model/model_generator.rb11
-rw-r--r--railties/lib/generators/active_record/model/templates/migration.rb4
-rw-r--r--railties/lib/generators/active_record/observer/observer_generator.rb2
-rw-r--r--railties/lib/generators/base.rb19
-rw-r--r--railties/lib/generators/erb/controller/controller_generator.rb2
-rw-r--r--railties/lib/generators/erb/mailer/mailer_generator.rb2
-rw-r--r--railties/lib/generators/test_unit/controller/controller_generator.rb2
-rw-r--r--railties/lib/generators/test_unit/helper/helper_generator.rb2
-rw-r--r--railties/lib/generators/test_unit/mailer/mailer_generator.rb2
-rw-r--r--railties/lib/generators/test_unit/model/model_generator.rb4
-rw-r--r--railties/lib/generators/test_unit/observer/observer_generator.rb2
-rw-r--r--railties/lib/generators/test_unit/plugin/plugin_generator.rb2
-rw-r--r--railties/test/generators/generators_test_helper.rb31
-rw-r--r--railties/test/generators/model_generator_test.rb80
16 files changed, 154 insertions, 64 deletions
diff --git a/railties/lib/generators.rb b/railties/lib/generators.rb
index f1b0d694af..fd7d3c9580 100644
--- a/railties/lib/generators.rb
+++ b/railties/lib/generators.rb
@@ -12,9 +12,6 @@ require 'rails/version' unless defined?(Rails::VERSION)
require 'generators/base'
require 'generators/named_base'
-require 'generators/active_record'
-require 'generators/erb'
-require 'generators/test_unit'
module Rails
module Generators
diff --git a/railties/lib/generators/active_record.rb b/railties/lib/generators/active_record.rb
index be5d033868..2c4c3286d4 100644
--- a/railties/lib/generators/active_record.rb
+++ b/railties/lib/generators/active_record.rb
@@ -1,8 +1,58 @@
require 'generators/named_base'
+require 'active_record'
module ActiveRecord
module Generators
+ module Migration
+
+ # Creates a migration template at the given destination. The difference
+ # to the default template method is that the migration number is appended
+ # to the destination file name.
+ #
+ # The migration number, migration file name, migration class name are
+ # available as instance variables in the template to be rendered.
+ #
+ # ==== Examples
+ #
+ # migration_template "migrate.rb", "db/migrate/add_foo_to_bar"
+ #
+ def migration_template(source, destination=nil, log_status=true)
+ destination = File.expand_path(destination || source, self.destination_root)
+
+ migration_dir = File.dirname(destination)
+ @migration_number = next_migration_number(migration_dir)
+ @migration_file_name = File.basename(destination).sub(/\.rb$/, '')
+ @migration_class_name = @migration_file_name.camelize
+
+ if existing = migration_exists?(migration_dir, @migration_file_name)
+ raise Rails::Generators::Error, "Another migration is already named #{@migration_file_name}: #{existing}"
+ end
+
+ destination = File.join(migration_dir, "#{@migration_number}_#{@migration_file_name}.rb")
+ template(source, destination, log_status)
+ end
+
+ protected
+
+ def migration_exists?(dirname, file_name) #:nodoc:
+ Dir.glob("#{dirname}/[0-9]*_*.rb").grep(/\d+_#{file_name}.rb$/).first
+ end
+
+ def current_migration_number(dirname) #:nodoc:
+ Dir.glob("#{dirname}/[0-9]*_*.rb").collect{ |f| f.split("_").first.to_i }.max
+ end
+
+ def next_migration_number(dirname) #:nodoc:
+ if ActiveRecord::Base.timestamped_migrations
+ Time.now.utc.strftime("%Y%m%d%H%M%S")
+ else
+ "%.3d" % (current_migration_number(dirname) + 1)
+ end
+ end
+ end
+
class Base < Rails::Generators::NamedBase
+ include Migration
end
end
end
diff --git a/railties/lib/generators/active_record/model/model_generator.rb b/railties/lib/generators/active_record/model/model_generator.rb
index 53592c222f..32a2ed15e4 100644
--- a/railties/lib/generators/active_record/model/model_generator.rb
+++ b/railties/lib/generators/active_record/model/model_generator.rb
@@ -1,3 +1,5 @@
+require 'generators/active_record'
+
module ActiveRecord
module Generators
class ModelGenerator < Base
@@ -5,8 +7,7 @@ module ActiveRecord
check_class_collision
- conditional_class_option :timestamps
- conditional_class_option :migration
+ conditional_class_options :migration, :timestamps
class_option :parent, :type => :string,
:desc => "The parent class for the generated model"
@@ -15,12 +16,10 @@ module ActiveRecord
template 'model.rb', File.join('app/models', class_path, "#{file_name}.rb")
end
- # TODO Add migration support
def create_migration_file
if options[:migration] && options[:parent].nil?
-# m.migration_template 'migration.rb', 'db/migrate', :assigns => {
-# :migration_name => "Create#{class_name.pluralize.gsub(/::/, '')}"
-# }, :migration_file_name => "create_#{file_path.gsub(/\//, '_').pluralize}"
+ file_name = "create_#{file_path.gsub(/\//, '_').pluralize}"
+ migration_template "migration.rb", "db/migrate/#{file_name}.rb"
end
end
diff --git a/railties/lib/generators/active_record/model/templates/migration.rb b/railties/lib/generators/active_record/model/templates/migration.rb
index 382fd1156e..542e9db2fc 100644
--- a/railties/lib/generators/active_record/model/templates/migration.rb
+++ b/railties/lib/generators/active_record/model/templates/migration.rb
@@ -1,10 +1,10 @@
-class <%= migration_name %> < ActiveRecord::Migration
+class <%= @migration_class_name %> < ActiveRecord::Migration
def self.up
create_table :<%= table_name %> do |t|
<% for attribute in attributes -%>
t.<%= attribute.type %> :<%= attribute.name %>
<% end -%>
-<% unless options[:skip_timestamps] %>
+<% if options[:timestamps] %>
t.timestamps
<% end -%>
end
diff --git a/railties/lib/generators/active_record/observer/observer_generator.rb b/railties/lib/generators/active_record/observer/observer_generator.rb
index 5bc9da34d1..fa51c23336 100644
--- a/railties/lib/generators/active_record/observer/observer_generator.rb
+++ b/railties/lib/generators/active_record/observer/observer_generator.rb
@@ -1,3 +1,5 @@
+require 'generators/active_record'
+
module ActiveRecord
module Generators
class ObserverGenerator < Base
diff --git a/railties/lib/generators/base.rb b/railties/lib/generators/base.rb
index 2bc6f7ec8a..386013c272 100644
--- a/railties/lib/generators/base.rb
+++ b/railties/lib/generators/base.rb
@@ -145,13 +145,13 @@ module Rails
# "rails:generators:webrat", "webrat:generators:controller", "webrat"
#
def self.invoke_if(*names)
- default_options = names.extract_options!
- verbose = default_options.key?(:verbose) ? default_options[:verbose] : :blue
+ conditional_class_options(*names)
+
+ options = names.extract_options!
+ verbose = options.fetch(:verbose, :blue)
invocations.concat(names)
names.each do |name|
- conditional_class_option name, default_options.dup
-
class_eval <<-METHOD, __FILE__, __LINE__
def invoke_if_#{name}
return unless options[#{name.inspect}]
@@ -236,9 +236,14 @@ module Rails
# Creates a conditional class option with type boolean, default value
# lookup and default description.
#
- def self.conditional_class_option(name, options={})
- options[:desc] ||= "Indicates when to generate #{name.to_s.humanize.downcase}"
- class_option name, options.merge!(:type => :boolean, :default => DEFAULTS[name] || false)
+ def self.conditional_class_options(*names)
+ default_options = names.extract_options!
+
+ names.each do |name|
+ options = default_options.dup
+ options[:desc] ||= "Indicates when to generate #{name.to_s.humanize.downcase}"
+ class_option name, options.merge!(:type => :boolean, :default => DEFAULTS[name] || false)
+ end
end
# Overwrite class options help to allow invoked generators options to be
diff --git a/railties/lib/generators/erb/controller/controller_generator.rb b/railties/lib/generators/erb/controller/controller_generator.rb
index 171ec23b97..706c92cb91 100644
--- a/railties/lib/generators/erb/controller/controller_generator.rb
+++ b/railties/lib/generators/erb/controller/controller_generator.rb
@@ -1,3 +1,5 @@
+require 'generators/erb'
+
module Erb
module Generators
class ControllerGenerator < Base
diff --git a/railties/lib/generators/erb/mailer/mailer_generator.rb b/railties/lib/generators/erb/mailer/mailer_generator.rb
index 73db3d2484..398ab46dd8 100644
--- a/railties/lib/generators/erb/mailer/mailer_generator.rb
+++ b/railties/lib/generators/erb/mailer/mailer_generator.rb
@@ -1,3 +1,5 @@
+require 'generators/erb'
+
module Erb
module Generators
class MailerGenerator < Base
diff --git a/railties/lib/generators/test_unit/controller/controller_generator.rb b/railties/lib/generators/test_unit/controller/controller_generator.rb
index d0d12d79e9..a8cb5cbdbb 100644
--- a/railties/lib/generators/test_unit/controller/controller_generator.rb
+++ b/railties/lib/generators/test_unit/controller/controller_generator.rb
@@ -1,3 +1,5 @@
+require 'generators/test_unit'
+
module TestUnit
module Generators
class ControllerGenerator < Base
diff --git a/railties/lib/generators/test_unit/helper/helper_generator.rb b/railties/lib/generators/test_unit/helper/helper_generator.rb
index 866556f6a1..9ecfaa45ab 100644
--- a/railties/lib/generators/test_unit/helper/helper_generator.rb
+++ b/railties/lib/generators/test_unit/helper/helper_generator.rb
@@ -1,3 +1,5 @@
+require 'generators/test_unit'
+
module TestUnit
module Generators
class HelperGenerator < Base
diff --git a/railties/lib/generators/test_unit/mailer/mailer_generator.rb b/railties/lib/generators/test_unit/mailer/mailer_generator.rb
index 84e3024427..bd1906516c 100644
--- a/railties/lib/generators/test_unit/mailer/mailer_generator.rb
+++ b/railties/lib/generators/test_unit/mailer/mailer_generator.rb
@@ -1,3 +1,5 @@
+require 'generators/test_unit'
+
module TestUnit
module Generators
class MailerGenerator < Base
diff --git a/railties/lib/generators/test_unit/model/model_generator.rb b/railties/lib/generators/test_unit/model/model_generator.rb
index dc53c7cf2f..74440d93d3 100644
--- a/railties/lib/generators/test_unit/model/model_generator.rb
+++ b/railties/lib/generators/test_unit/model/model_generator.rb
@@ -1,10 +1,12 @@
+require 'generators/test_unit'
+
module TestUnit
module Generators
class ModelGenerator < Base
argument :attributes, :type => :hash, :default => {}, :banner => "field:type, field:type"
check_class_collision :suffix => "Test"
- conditional_class_option :fixture
+ conditional_class_options :fixture
def create_test_file
template 'unit_test.rb', File.join('test/unit', class_path, "#{file_name}_test.rb")
diff --git a/railties/lib/generators/test_unit/observer/observer_generator.rb b/railties/lib/generators/test_unit/observer/observer_generator.rb
index adfd90a086..48742f4b70 100644
--- a/railties/lib/generators/test_unit/observer/observer_generator.rb
+++ b/railties/lib/generators/test_unit/observer/observer_generator.rb
@@ -1,3 +1,5 @@
+require 'generators/test_unit'
+
module TestUnit
module Generators
class ObserverGenerator < Base
diff --git a/railties/lib/generators/test_unit/plugin/plugin_generator.rb b/railties/lib/generators/test_unit/plugin/plugin_generator.rb
index 427a7bd8f5..9c08dc4d50 100644
--- a/railties/lib/generators/test_unit/plugin/plugin_generator.rb
+++ b/railties/lib/generators/test_unit/plugin/plugin_generator.rb
@@ -1,3 +1,5 @@
+require 'generators/test_unit'
+
module TestUnit
module Generators
class PluginGenerator < Base
diff --git a/railties/test/generators/generators_test_helper.rb b/railties/test/generators/generators_test_helper.rb
index 29ff306551..662646fbff 100644
--- a/railties/test/generators/generators_test_helper.rb
+++ b/railties/test/generators/generators_test_helper.rb
@@ -36,20 +36,41 @@ class GeneratorsTestCase < Test::Unit::TestCase
def assert_file(relative, *contents)
absolute = File.join(destination_root, relative)
- assert File.exists?(absolute)
+ assert File.exists?(absolute), "Expected file #{relative.inspect} to exist, but does not"
+ read = File.read(absolute) unless File.directory?(absolute)
contents.each do |content|
case content
when String
- assert_equal content, File.read(absolute)
+ assert_equal content, read
when Regexp
- assert_match content, File.read(absolute)
+ assert_match content, read
end
end
+ read
end
- def assert_no_file(relative, content=nil)
+ def assert_no_file(relative)
absolute = File.join(destination_root, relative)
- assert !File.exists?(absolute)
+ assert !File.exists?(absolute), "Expected file #{relative.inspect} to not exist, but does"
+ end
+
+ def assert_migration(relative, *contents)
+ file_name = migration_file_name(relative)
+ assert file_name, "Expected migration #{relative} to exist, but was not found"
+ assert_file File.join(File.dirname(relative), file_name), *contents
+ end
+
+ def assert_no_migration(relative)
+ file_name = migration_file_name(relative)
+ assert_nil file_name, "Expected migration #{relative} to not exist, but found #{file_name}"
+ end
+
+ def migration_file_name(relative)
+ absolute = File.join(destination_root, relative)
+ dirname, file_name = File.dirname(absolute), File.basename(absolute).sub(/\.rb$/, '')
+
+ migration = Dir.glob("#{dirname}/[0-9]*_*.rb").grep(/\d+_#{file_name}.rb$/).first
+ File.basename(migration) if migration
end
end
diff --git a/railties/test/generators/model_generator_test.rb b/railties/test/generators/model_generator_test.rb
index 8a9c081cd9..212f0f3691 100644
--- a/railties/test/generators/model_generator_test.rb
+++ b/railties/test/generators/model_generator_test.rb
@@ -17,28 +17,64 @@ class ModelGeneratorTest < GeneratorsTestCase
assert_file "app/models/account.rb", /class Account < ActiveRecord::Base/
end
- def test_orm_with_parent_option
+ def test_model_with_parent_option
run_generator ["account", "--parent", "Admin::Account"]
assert_file "app/models/account.rb", /class Account < Admin::Account/
end
- def test_orm_with_underscored_parent_option
+ def test_model_with_underscored_parent_option
run_generator ["account", "--parent", "admin/account"]
assert_file "app/models/account.rb", /class Account < Admin::Account/
end
+ def test_migration
+ run_generator
+ assert_migration "db/migrate/create_accounts.rb", /class CreateAccounts < ActiveRecord::Migration/
+ end
+
+ def test_migration_is_skipped
+ run_generator ["account", "--no-migration"]
+ assert_no_migration "db/migrate/create_accounts.rb"
+ end
+
+ def test_migration_with_attributes
+ run_generator ["product", "name:string", "supplier_id:integer"]
+ assert_migration "db/migrate/create_products.rb", /t\.string :name/, /t\.integer :supplier_id/
+ end
+
+ def test_model_with_references_attribute_generates_belongs_to_associations
+ run_generator ["product", "name:string", "supplier_id:references"]
+ assert_file "app/models/product.rb", /belongs_to :supplier/
+ end
+
+ def test_model_with_belongs_to_attribute_generates_belongs_to_associations
+ run_generator ["product", "name:string", "supplier_id:belongs_to"]
+ assert_file "app/models/product.rb", /belongs_to :supplier/
+ end
+
+ def test_migration_with_timestamps
+ run_generator
+ assert_migration "db/migrate/create_accounts.rb", /t.timestamps/
+ end
+
+ def test_migration_timestamps_are_skipped
+ run_generator ["account", "--no-timestamps"]
+ content = assert_migration "db/migrate/create_accounts.rb"
+ assert_no_match /t.timestamps/, content
+ end
+
def test_invokes_default_test_framework
run_generator
assert_file "test/unit/account_test.rb", /class AccountTest < ActiveSupport::TestCase/
assert_file "test/fixtures/accounts.yml", /name: MyString/, /age: 1/
end
- def test_fixtures_are_skipped
+ def test_fixture_is_skipped
run_generator ["account", "--skip-fixture"]
assert_no_file "test/fixtures/accounts.yml"
end
- def test_fixtures_are_skipped_if_fixture_replacement_is_given
+ def test_fixture_is_skipped_if_fixture_replacement_is_given
content = run_generator ["account", "-r", "fixjour"]
assert_match /Could not find and invoke 'fixjour'/, content
assert_no_file "test/fixtures/accounts.yml"
@@ -49,42 +85,6 @@ class ModelGeneratorTest < GeneratorsTestCase
assert_match /The name 'Object' is either already used in your application or reserved/, content
end
-# def test_model_skip_migration_skips_migration
-# run_generator('model', %w(Product name:string --skip-migration))
-
-# assert_generated_model_for :product
-# assert_generated_fixtures_for :products
-# assert_skipped_migration :create_products
-# end
-
-# def test_model_with_attributes_generates_resources_with_attributes
-# run_generator('model', %w(Product name:string supplier_id:integer created_at:timestamp))
-
-# assert_generated_model_for :product
-# assert_generated_fixtures_for :products
-# assert_generated_migration :create_products do |t|
-# assert_generated_column t, :name, :string
-# assert_generated_column t, :supplier_id, :integer
-# assert_generated_column t, :created_at, :timestamp
-# end
-# end
-
-# def test_model_with_reference_attributes_generates_belongs_to_associations
-# run_generator('model', %w(Product name:string supplier:references))
-
-# assert_generated_model_for :product do |body|
-# assert body =~ /^\s+belongs_to :supplier/, "#{body.inspect} should contain 'belongs_to :supplier'"
-# end
-# end
-
-# def test_model_with_belongs_to_attributes_generates_belongs_to_associations
-# run_generator('model', %w(Product name:string supplier:belongs_to))
-
-# assert_generated_model_for :product do |body|
-# assert body =~ /^\s+belongs_to :supplier/, "#{body.inspect} should contain 'belongs_to :supplier'"
-# end
-# end
-
protected
def run_generator(args=["Account", "name:string", "age:integer"])