Add an after_bundle callback in Rails templates #16359

Merged
merged 2 commits into from Aug 6, 2014

Conversation

Projects
None yet
5 participants
@skanev
Contributor

skanev commented Jul 31, 2014

Closes #16292.

The following Rails template (taken from the Rails guides) does not work well with binstubs:

# 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' }

Since it is executed before Bundler and Spring binstub generation, the generated stubs are not added to version control. Executing the templates later wouldn't work either – that way it won't be able to add gems.

Adding an after_bundle callback seems to solve the issue. That way, the version control commands can be postponed after the binstubs have been generated:

# 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

This pull request implements that callback. The test is a mouthful – I'm open to suggestions for improvements 😄

/cc @senny

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

This comment has been minimized.

@robin850

robin850 Jul 31, 2014

Member

Could you avoid using Mocha please ? We are trying to remove it from the test suite. Thanks for the patch so far, it looks great! 👍

@robin850

robin850 Jul 31, 2014

Member

Could you avoid using Mocha please ? We are trying to remove it from the test suite. Thanks for the patch so far, it looks great! 👍

This comment has been minimized.

@skanev

skanev Jul 31, 2014

Contributor

I can try, but I'm not sure how. I arrived at this code by following the style of the surrounding tests. I want to check that:

  1. `bundle gets run
  2. ...then binstubs get generated
  3. ...then the after_bundle callbacks get executed

Surely the test cannot invoke bundle, since it will make them (1) nondeterministic and (2) dependant on internet connection. Also, (3) very slow. Calls to the first two need to get stubbed in some way.

If I'm not allowed to use Mocha, I'm not sure how to handle it. I can define singleton methods on generator, but that will surely get messier and harder to understand.

There is also the business of supplying a template. Since a string containing code cannot be passed to generator, there's this path and template.instance_eval business that I borrowed from a test in the same suite. If I'm to remove Mocha, we should also figure out how to do that.

Finally, if the other tests in the suite can benefit from the same approach. Maybe there are a few nice abstractions that can be extracted and all the tests can benefit from them. This feels like another, larger task. I'd love to do it also (in a separate PR possibly), but I'll definitely need some hints on how to do it :)

@skanev

skanev Jul 31, 2014

Contributor

I can try, but I'm not sure how. I arrived at this code by following the style of the surrounding tests. I want to check that:

  1. `bundle gets run
  2. ...then binstubs get generated
  3. ...then the after_bundle callbacks get executed

Surely the test cannot invoke bundle, since it will make them (1) nondeterministic and (2) dependant on internet connection. Also, (3) very slow. Calls to the first two need to get stubbed in some way.

If I'm not allowed to use Mocha, I'm not sure how to handle it. I can define singleton methods on generator, but that will surely get messier and harder to understand.

There is also the business of supplying a template. Since a string containing code cannot be passed to generator, there's this path and template.instance_eval business that I borrowed from a test in the same suite. If I'm to remove Mocha, we should also figure out how to do that.

Finally, if the other tests in the suite can benefit from the same approach. Maybe there are a few nice abstractions that can be extracted and all the tests can benefit from them. This feels like another, larger task. I'd love to do it also (in a separate PR possibly), but I'll definitely need some hints on how to do it :)

This comment has been minimized.

@senny

senny Jul 31, 2014

Member

@robin850 given that the surrounding tests use the same pattern I don't think we need to tackle this in the same PR. Basically if one does remove Mocha for one of the tests it should be trivial to remove it for the others. They are all doing mostly the same stuff.

@senny

senny Jul 31, 2014

Member

@robin850 given that the surrounding tests use the same pattern I don't think we need to tackle this in the same PR. Basically if one does remove Mocha for one of the tests it should be trivial to remove it for the others. They are all doing mostly the same stuff.

This comment has been minimized.

@rafaelfranca

rafaelfranca Jul 31, 2014

Member

Yes. No bother with mocha. I'll deal with it.

@rafaelfranca

rafaelfranca Jul 31, 2014

Member

Yes. No bother with mocha. I'll deal with it.

This comment has been minimized.

@robin850

robin850 Jul 31, 2014

Member

given that the surrounding tests use the same pattern I don't think we need to tackle this in the same PR

Ah fair point 👍

@robin850

robin850 Jul 31, 2014

Member

given that the surrounding tests use the same pattern I don't think we need to tackle this in the same PR

Ah fair point 👍

@robin850 robin850 added the railties label Jul 31, 2014

@robin850 robin850 added this to the 4.2.0 milestone Jul 31, 2014

@itsNikolay

This comment has been minimized.

Show comment
Hide comment
@itsNikolay

itsNikolay Jul 31, 2014

Contributor

@skanev does git init happen when generator will be run with --skip-bundle option ?

Contributor

itsNikolay commented Jul 31, 2014

@skanev does git init happen when generator will be run with --skip-bundle option ?

@skanev

This comment has been minimized.

Show comment
Hide comment
@skanev

skanev Jul 31, 2014

Contributor

@itsNikolay Yup, the after_bundle callbacks get executed even if --skip-bundle is passed.

Contributor

skanev commented Jul 31, 2014

@itsNikolay Yup, the after_bundle callbacks get executed even if --skip-bundle is passed.

@senny

This comment has been minimized.

Show comment
Hide comment
@senny

senny Jul 31, 2014

Member

@skanev I think the docs should mention that after_bundle runs even if --skip-bundle was passed.

Member

senny commented Jul 31, 2014

@skanev I think the docs should mention that after_bundle runs even if --skip-bundle was passed.

@skanev

This comment has been minimized.

Show comment
Hide comment
@skanev

skanev Jul 31, 2014

Contributor

@senny I've added it to the guide.

Contributor

skanev commented Jul 31, 2014

@senny I've added it to the guide.

Add an after_bundle callback in Rails templates
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.
@skanev

This comment has been minimized.

Show comment
Hide comment
@skanev

skanev Aug 2, 2014

Contributor

I've rebased onto master, squashed the two commits into one and added a reference to the fixed issue in the changelog.

Contributor

skanev commented Aug 2, 2014

I've rebased onto master, squashed the two commits into one and added a reference to the fixed issue in the changelog.

@senny

This comment has been minimized.

Show comment
Hide comment
@senny

senny Aug 4, 2014

Member

As this is a breaking change (well not directly but the user needs to modify his templates) we should include it in the release notes and the upgrading guide.

Member

senny commented Aug 4, 2014

As this is a breaking change (well not directly but the user needs to modify his templates) we should include it in the release notes and the upgrading guide.

@skanev

This comment has been minimized.

Show comment
Hide comment
@skanev

skanev Aug 5, 2014

Contributor

I've added it to the release notes and upgrade guide in c294e91.

Contributor

skanev commented Aug 5, 2014

I've added it to the release notes and upgrade guide in c294e91.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment