Merge pull request #16359 from skanev/after-bundle-in-rails-templates

Add an after_bundle callback in Rails templates

Conflicts:
	railties/CHANGELOG.md
This commit is contained in:
Yves Senn 2014-08-06 08:49:00 +02:00
commit a819211984
7 changed files with 95 additions and 3 deletions

View File

@ -85,6 +85,9 @@ Please refer to the [Changelog][railties] for detailed changes.
* Introduced `Rails.gem_version` as a convenience method to return `Gem::Version.new(Rails.version)`.
([Pull Request](https://github.com/rails/rails/pull/14101))
* Introduced an `after_bundle` callback in the Rails templates.
([Pull Request](https://github.com/rails/rails/pull/16359))
Action Pack
-----------

View File

@ -38,9 +38,11 @@ generate(:scaffold, "person name:string")
route "root to: 'people#index'"
rake("db:migrate")
git :init
git add: "."
git commit: %Q{ -m 'Initial commit' }
after_bundle do
git :init
git add: "."
git commit: %Q{ -m 'Initial commit' }
end
```
The following sections outline the primary methods provided by the API:
@ -228,6 +230,22 @@ git add: "."
git commit: "-a -m 'Initial commit'"
```
### after_bundle(&block)
Registers a callback to be executed after the gems are bundled and binstubs
are generated. Useful for all generated files to version control:
```ruby
after_bundle do
git :init
git add: '.'
git commit: "-a -m 'Initial commit'"
end
```
The callbacks gets executed even if `--skip-bundle` and/or `--skip-spring` has
been passed.
Advanced Usage
--------------

View File

@ -58,6 +58,38 @@ When assigning `nil` to a serialized attribute, it will be saved to the database
as `NULL` instead of passing the `nil` value through the coder (e.g. `"null"`
when using the `JSON` coder).
### `after_bundle` in Rails templates
If you have a Rails template that adds all the files in version control, it
fails to add the generated binstubs because it gets executed before Bundler:
```ruby
# template.rb
generate(:scaffold, "person name:string")
route "root to: 'people#index'"
rake("db:migrate")
git :init
git add: "."
git commit: %Q{ -m 'Initial commit' }
```
You can now wrap the `git` calls in an `after_bundle` block. It will be run
after the binstubs have been generated.
```ruby
# template.rb
generate(:scaffold, "person name:string")
route "root to: 'people#index'"
rake("db:migrate")
after_bundle do
git :init
git add: "."
git commit: %Q{ -m 'Initial commit' }
end
```
Upgrading from Rails 4.0 to Rails 4.1
-------------------------------------

View File

@ -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*
* Pull in the custom configuration concept from dhh/custom_configuration, which allows you to
configure your own code through the Rails configuration object with custom configuration:

View File

@ -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,

View File

@ -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

View File

@ -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)