From 097b2101897af447591d00fb2809d91894572b87 Mon Sep 17 00:00:00 2001 From: Stefan Kanev Date: Thu, 31 Jul 2014 12:05:07 +0200 Subject: Add an after_bundle callback in Rails templates MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The template runs before the generation of binstubs – this does not allow to write one, that makes an initial commit to version control. It is solvable by adding an after_bundle callback. --- railties/CHANGELOG.md | 7 +++++++ railties/lib/rails/generators/actions.rb | 11 +++++++++++ railties/lib/rails/generators/rails/app/app_generator.rb | 6 ++++++ railties/test/generators/app_generator_test.rb | 15 +++++++++++++++ 4 files changed, 39 insertions(+) (limited to 'railties') diff --git a/railties/CHANGELOG.md b/railties/CHANGELOG.md index 651f40007e..9a57604f48 100644 --- a/railties/CHANGELOG.md +++ b/railties/CHANGELOG.md @@ -1,3 +1,10 @@ +* Add `after_bundle` callbacks in Rails templates. Useful for allowing the + generated binstubs to be added to version control. + + Fixes #16292. + + *Stefan Kanev* + * Scaffold generator `_form` partial adds `class="field"` for password confirmation fields. diff --git a/railties/lib/rails/generators/actions.rb b/railties/lib/rails/generators/actions.rb index a239874df0..4709914947 100644 --- a/railties/lib/rails/generators/actions.rb +++ b/railties/lib/rails/generators/actions.rb @@ -7,6 +7,7 @@ module Rails def initialize(*) # :nodoc: super @in_group = nil + @after_bundle_callbacks = [] end # Adds an entry into +Gemfile+ for the supplied gem. @@ -232,6 +233,16 @@ module Rails log File.read(find_in_source_paths(path)) end + # Registers a callback to be executed after bundle and spring binstubs + # have run. + # + # after_bundle do + # git add: '.' + # end + def after_bundle(&block) + @after_bundle_callbacks << block + end + protected # Define log for backwards compatibility. If just one argument is sent, diff --git a/railties/lib/rails/generators/rails/app/app_generator.rb b/railties/lib/rails/generators/rails/app/app_generator.rb index 188e62b6c8..9110c129d1 100644 --- a/railties/lib/rails/generators/rails/app/app_generator.rb +++ b/railties/lib/rails/generators/rails/app/app_generator.rb @@ -259,6 +259,12 @@ module Rails public_task :apply_rails_template, :run_bundle public_task :generate_spring_binstubs + def run_after_bundle_callbacks + @after_bundle_callbacks.each do |callback| + callback.call + end + end + protected def self.banner diff --git a/railties/test/generators/app_generator_test.rb b/railties/test/generators/app_generator_test.rb index 184cfc2220..3f31f89473 100644 --- a/railties/test/generators/app_generator_test.rb +++ b/railties/test/generators/app_generator_test.rb @@ -501,6 +501,21 @@ class AppGeneratorTest < Rails::Generators::TestCase end end + def test_after_bundle_callback + path = 'http://example.org/rails_template' + template = %{ after_bundle { run 'echo ran after_bundle' } } + template.instance_eval "def read; self; end" # Make the string respond to read + + generator([destination_root], template: path).expects(:open).with(path, 'Accept' => 'application/x-thor-template').returns(template) + + bundler_first = sequence('bundle, binstubs, after_bundle') + generator.expects(:bundle_command).with('install').once.in_sequence(bundler_first) + generator.expects(:bundle_command).with('exec spring binstub --all').in_sequence(bundler_first) + generator.expects(:run).with('echo ran after_bundle').in_sequence(bundler_first) + + quietly { generator.invoke_all } + end + protected def action(*args, &block) -- cgit v1.2.3 From 53dba73dc17502b3d3f71d4672e86a14b995a732 Mon Sep 17 00:00:00 2001 From: Yves Senn Date: Thu, 24 Jul 2014 14:46:25 +0200 Subject: Revert "Revert "Merge pull request #15394 from morgoth/fix-automatic-maintaining-test-schema-for-sql-format"" This reverts commit 5c87b5c5248154cf8aa76cce9a24a88769de022d. --- railties/test/application/test_test.rb | 91 +++++++++++++++++++++++++++++++++- 1 file changed, 90 insertions(+), 1 deletion(-) (limited to 'railties') diff --git a/railties/test/application/test_test.rb b/railties/test/application/test_test.rb index a223180169..c724c867ec 100644 --- a/railties/test/application/test_test.rb +++ b/railties/test/application/test_test.rb @@ -67,7 +67,7 @@ module ApplicationTests assert_match %r{/app/test/unit/failing_test\.rb}, output end - test "migrations" do + test "ruby schema migrations" do output = script('generate model user name:string') version = output.match(/(\d+)_create_users\.rb/)[1] @@ -104,6 +104,95 @@ module ApplicationTests assert !result.include?("create_table(:users)") end + test "sql structure migrations" do + output = script('generate model user name:string') + version = output.match(/(\d+)_create_users\.rb/)[1] + + app_file 'test/models/user_test.rb', <<-RUBY + require 'test_helper' + + class UserTest < ActiveSupport::TestCase + test "user" do + User.create! name: "Jon" + end + end + RUBY + + app_file 'db/structure.sql', '' + app_file 'config/initializers/enable_sql_schema_format.rb', <<-RUBY + Rails.application.config.active_record.schema_format = :sql + RUBY + + assert_unsuccessful_run "models/user_test.rb", "Migrations are pending" + + app_file 'db/structure.sql', <<-SQL + CREATE TABLE "schema_migrations" ("version" varchar(255) NOT NULL); + CREATE UNIQUE INDEX "unique_schema_migrations" ON "schema_migrations" ("version"); + CREATE TABLE "users" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar(255)); + INSERT INTO schema_migrations (version) VALUES ('#{version}'); + SQL + + app_file 'config/initializers/disable_maintain_test_schema.rb', <<-RUBY + Rails.application.config.active_record.maintain_test_schema = false + RUBY + + assert_unsuccessful_run "models/user_test.rb", "Could not find table 'users'" + + File.delete "#{app_path}/config/initializers/disable_maintain_test_schema.rb" + + assert_successful_test_run('models/user_test.rb') + end + + test "sql structure migrations when adding column to existing table" do + output_1 = script('generate model user name:string') + version_1 = output_1.match(/(\d+)_create_users\.rb/)[1] + + app_file 'test/models/user_test.rb', <<-RUBY + require 'test_helper' + class UserTest < ActiveSupport::TestCase + test "user" do + User.create! name: "Jon" + end + end + RUBY + + app_file 'config/initializers/enable_sql_schema_format.rb', <<-RUBY + Rails.application.config.active_record.schema_format = :sql + RUBY + + app_file 'db/structure.sql', <<-SQL + CREATE TABLE "schema_migrations" ("version" varchar(255) NOT NULL); + CREATE UNIQUE INDEX "unique_schema_migrations" ON "schema_migrations" ("version"); + CREATE TABLE "users" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar(255)); + INSERT INTO schema_migrations (version) VALUES ('#{version_1}'); + SQL + + assert_successful_test_run('models/user_test.rb') + + output_2 = script('generate migration add_email_to_users') + version_2 = output_2.match(/(\d+)_add_email_to_users\.rb/)[1] + + app_file 'test/models/user_test.rb', <<-RUBY + require 'test_helper' + + class UserTest < ActiveSupport::TestCase + test "user" do + User.create! name: "Jon", email: "jon@doe.com" + end + end + RUBY + + app_file 'db/structure.sql', <<-SQL + CREATE TABLE "schema_migrations" ("version" varchar(255) NOT NULL); + CREATE UNIQUE INDEX "unique_schema_migrations" ON "schema_migrations" ("version"); + CREATE TABLE "users" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar(255), "email" varchar(255)); + INSERT INTO schema_migrations (version) VALUES ('#{version_1}'); + INSERT INTO schema_migrations (version) VALUES ('#{version_2}'); + SQL + + assert_successful_test_run('models/user_test.rb') + end + private def assert_unsuccessful_run(name, message) result = run_test_file(name) -- cgit v1.2.3 From d25fe31c40928712b5e08fe0afb567c3bc88eddf Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 6 Aug 2014 18:27:16 -0700 Subject: lazily instantiate application subclasses this means we can meaningfully override methods in the subclass --- railties/lib/rails.rb | 8 +++++++- railties/lib/rails/application.rb | 4 +--- railties/test/engine_test.rb | 10 ++++++++++ 3 files changed, 18 insertions(+), 4 deletions(-) (limited to 'railties') diff --git a/railties/lib/rails.rb b/railties/lib/rails.rb index ecd8c22dd8..e7172e491f 100644 --- a/railties/lib/rails.rb +++ b/railties/lib/rails.rb @@ -29,7 +29,13 @@ module Rails autoload :WelcomeController class << self - attr_accessor :application, :cache, :logger + @application = @app_class = nil + + attr_writer :application + attr_accessor :app_class, :cache, :logger + def application + @application ||= (app_class.instance if app_class) + end delegate :initialize!, :initialized?, to: :application diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb index c5fd08e743..292986b475 100644 --- a/railties/lib/rails/application.rb +++ b/railties/lib/rails/application.rb @@ -87,7 +87,7 @@ module Rails class << self def inherited(base) super - base.instance + Rails.app_class = base end # Makes the +new+ method public. @@ -117,8 +117,6 @@ module Rails @railties = nil @message_verifiers = {} - Rails.application ||= self - add_lib_to_load_path! ActiveSupport.run_load_hooks(:before_configuration, self) diff --git a/railties/test/engine_test.rb b/railties/test/engine_test.rb index 7970913d21..8401494bd2 100644 --- a/railties/test/engine_test.rb +++ b/railties/test/engine_test.rb @@ -11,4 +11,14 @@ class EngineTest < ActiveSupport::TestCase assert !engine.routes? end + + def test_application_can_be_subclassed + klass = Class.new(Rails::Application) do + attr_reader :hello + def initialize + @hello = "world" + end + end + assert_equal "world", klass.instance.hello + end end -- cgit v1.2.3 From 22969898262b8c92bea1ac93b668a817c7511158 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Thu, 7 Aug 2014 15:28:31 -0700 Subject: defer running after_config hooks until after the object is allocated --- railties/lib/rails/application.rb | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) (limited to 'railties') diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb index 292986b475..796c068a10 100644 --- a/railties/lib/rails/application.rb +++ b/railties/lib/rails/application.rb @@ -90,6 +90,10 @@ module Rails Rails.app_class = base end + def instance + super.run_load_hooks! + end + # Makes the +new+ method public. # # Note that Rails::Application inherits from Rails::Engine, which @@ -116,22 +120,33 @@ module Rails @ordered_railties = nil @railties = nil @message_verifiers = {} + @ran_load_hooks = false + + # are these actually used? + @initial_variable_values = initial_variable_values + @block = block add_lib_to_load_path! + end + + # Returns true if the application is initialized. + def initialized? + @initialized + end + + def run_load_hooks! # :nodoc: + return self if @ran_load_hooks + @ran_load_hooks = true ActiveSupport.run_load_hooks(:before_configuration, self) - initial_variable_values.each do |variable_name, value| + @initial_variable_values.each do |variable_name, value| if INITIAL_VARIABLES.include?(variable_name) instance_variable_set("@#{variable_name}", value) end end - instance_eval(&block) if block_given? - end - - # Returns true if the application is initialized. - def initialized? - @initialized + instance_eval(&@block) if @block + self end # Implements call according to the Rack API. It simply -- cgit v1.2.3 From 8121eefc222fbd8979ab70d89725a2e330f5a9b2 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Thu, 7 Aug 2014 15:50:46 -0700 Subject: add a new constructor that runs load hooks --- railties/lib/rails/application.rb | 4 ++++ railties/test/application/multiple_applications_test.rb | 10 +++++----- 2 files changed, 9 insertions(+), 5 deletions(-) (limited to 'railties') diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb index 796c068a10..61639be7c6 100644 --- a/railties/lib/rails/application.rb +++ b/railties/lib/rails/application.rb @@ -94,6 +94,10 @@ module Rails super.run_load_hooks! end + def create(initial_variable_values = {}, &block) + new(initial_variable_values, &block).run_load_hooks! + end + # Makes the +new+ method public. # # Note that Rails::Application inherits from Rails::Engine, which diff --git a/railties/test/application/multiple_applications_test.rb b/railties/test/application/multiple_applications_test.rb index 98707d22e4..9ebf163671 100644 --- a/railties/test/application/multiple_applications_test.rb +++ b/railties/test/application/multiple_applications_test.rb @@ -36,23 +36,23 @@ module ApplicationTests end def test_initialization_of_application_with_previous_config - application1 = AppTemplate::Application.new(config: Rails.application.config) - application2 = AppTemplate::Application.new + application1 = AppTemplate::Application.create(config: Rails.application.config) + application2 = AppTemplate::Application.create assert_equal Rails.application.config, application1.config, "Creating a new application while setting an initial config should result in the same config" assert_not_equal Rails.application.config, application2.config, "New applications without setting an initial config should not have the same config" end def test_initialization_of_application_with_previous_railties - application1 = AppTemplate::Application.new(railties: Rails.application.railties) - application2 = AppTemplate::Application.new + application1 = AppTemplate::Application.create(railties: Rails.application.railties) + application2 = AppTemplate::Application.create assert_equal Rails.application.railties, application1.railties assert_not_equal Rails.application.railties, application2.railties end def test_initialize_new_application_with_all_previous_initialization_variables - application1 = AppTemplate::Application.new( + application1 = AppTemplate::Application.create( config: Rails.application.config, railties: Rails.application.railties, routes_reloader: Rails.application.routes_reloader, -- cgit v1.2.3 From e81453ef92b37156dafc092093106c8e8b87b268 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Thu, 7 Aug 2014 16:03:09 -0700 Subject: need to call super --- railties/test/engine_test.rb | 1 + 1 file changed, 1 insertion(+) (limited to 'railties') diff --git a/railties/test/engine_test.rb b/railties/test/engine_test.rb index 8401494bd2..f46fb748f5 100644 --- a/railties/test/engine_test.rb +++ b/railties/test/engine_test.rb @@ -17,6 +17,7 @@ class EngineTest < ActiveSupport::TestCase attr_reader :hello def initialize @hello = "world" + super end end assert_equal "world", klass.instance.hello -- cgit v1.2.3