Skip to content

Conversation

y-yagi
Copy link
Member

@y-yagi y-yagi commented Apr 3, 2020

This is useful if users want to process generated files.
For example, can execute an autocorrect of RuboCop for generated files as like following.

config.generators.after_generate do |files|
  system("bundle exec rubocop --auto-correct " + files.join(" "), exception: true)
end

@simi
Copy link
Contributor

simi commented Apr 3, 2020

This covers a little difference use-case than I have seen benefit of in original #32996. I was looking for way to open (for example) migration file every-time I create it using generator, but do not enforce the same for all developers on same project. Also I would welcome to set this once in my "env" and have this enabled for all Rails apps having this capability (compatible version).

If I understand it well currently there's no easy way to achieve this, since (AFAIK) the global file .railsrc works only for rails new command. The only way I can think of for now is to have custom initializer globally git ignored and ensure it is copied in every Rails app I work on.

Thinking of my requirement, I think it should be possible to modify behaviour of rails generator commands when used in "non-interactive"(!$stdout.tty?) way and instead of user friendly output just provide list of generated files. Than it would be possible to do bin/rails g migration my_tiny_winie_migration | xargs gvim. WDYT?

@y-yagi
Copy link
Member Author

y-yagi commented Apr 4, 2020

Thanks for sharing your use-case!

It seems the requirement is different from my requirement.
My requirement is enforcing the style to the same for all developers on the same project.
So I think it's hard to fix all use-case in one fix. I keep this PR as is (to fix my use-case).

bin/rails g migration my_tiny_winie_migration | xargs gvim

This use-case can support by this PR. For example, only run after_generate when some env key.

config.generators.after_generate do |files|
  if ENV["EDITOR_FOR_GENERATOR"]
    system(ENV["EDITOR_FOR_GENERATOR"], *files, exception: true)
  end
end 
$ EDITOR_FOR_GENERATOR=vim ./bin/rails g model user name:string 

Of course, this is a little ugly. That support is out of scope this PR, but being able to pass a list of files to stdout in some way is worth considering in other PR I think.

@simi
Copy link
Contributor

simi commented Apr 4, 2020

only run after_generate when some env key

Yeah, but that should be added to every app just because of me.

I'll think about my use-case a little more and open separate PR if needed. Code changes in here would be beneficial for that as well.

@kaspth
Copy link
Contributor

kaspth commented Apr 5, 2020

Not too fond of the stated use case as justification for adding it. Wouldn't you have to run Rubocop before pushing the files (e.g. after someone's edited it) or run a Rubocop check on CI anyway? But the possibilities that after_generate has are interesting enough, so let's go for it.

I think the --edit (which then uses ENV["EDITOR"]) would be great to have built-in, I've wanted that in the past too.

def run_after_generate_callback
unless self.generated_files.empty?
@after_generate_callbacks.each do |callback|
callback.call(self.generated_files)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Omit the needless self. when calling generated_files.

@@ -19,6 +19,11 @@ def identical?
exists? && File.binread(existing_migration) == render
end

def invoke!
invoked_file = super
File.exist?(@destination) ? invoked_file : relative_existing_migration
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this needed?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CreateMigration keeps an existing file when content is the same with an invoked file. In that case, we need to return an existing file name. If do not, after_generate callback will return a non-existing file name(invoked file name).

@@ -269,6 +275,7 @@ def invoke(namespace, args = ARGV, config = {})
if klass = find_by_namespace(names.pop, names.any? && names.join(":"))
args << "--help" if args.empty? && klass.arguments.any?(&:required?)
klass.start(args, config)
run_after_generate_callback if config[:behavior] == :invoke
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does start return a value that we need to pass on? E.g. should we do start(args, config).tap do?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The start returns all result of all_command. all_command includes methods that do not relate with generating files(e.g. check_class_collision, hook_for). It is a little difficult to extract that only result of generating files.

@@ -29,6 +29,7 @@ module Generators
autoload :TestCase, "rails/generators/test_case"

mattr_accessor :namespace
mattr_reader :generated_files, default: []
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, not liking exposing this here. Can we manage everything entirely within add_generated_file? Maybe via (@@generated_files ||= []) << file or something?

If not, I'd move the _reader above the _accessor since that's the style we follow, iirc.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I fixed that manage everything entirely within add_generated_file.

@y-yagi y-yagi force-pushed the add_after_generate branch from fe2a4ef to 1d14399 Compare April 22, 2020 04:59
@@ -281,6 +287,11 @@ def invoke(namespace, args = ARGV, config = {})
end
end

def add_generated_file(file) # :nodoc:
(@@generated_files ||= []) << file
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It feels a little strange to have this as global state. I'm not sure how it will play with the :inline option added in #37516. If there is no way for this to be instance state on the instantiated generator, what do you think about clearing @@generated_files after all callbacks are run?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, your advice is correct and clearing @@generated_files was needed. I fixed.

@y-yagi y-yagi force-pushed the add_after_generate branch from 1d14399 to 11e8826 Compare May 1, 2020 05:02
Register a callback that will get called right after generators has
finished.

This is useful if users want to process generated files.
For example, can execute an autocorrect of RuboCop for generated files
as like following.

```ruby
config.generators.after_generate do |files|
  system("bundle exec rubocop --auto-correct " + files.join(" "), exception: true)
end
```
@y-yagi y-yagi force-pushed the add_after_generate branch from 11e8826 to fde100d Compare May 8, 2020 12:06
@y-yagi y-yagi merged commit d80c18a into rails:master May 8, 2020
@kaspth
Copy link
Contributor

kaspth commented May 8, 2020

Rad! ❤️💪

@y-yagi y-yagi deleted the add_after_generate branch May 8, 2020 20:43
koic added a commit to koic/rubocop-rails that referenced this pull request Mar 17, 2023
This PR adds a Rails feature introduced by rails/rails#38870 to docs.
koic added a commit to koic/rubocop-rails that referenced this pull request Mar 18, 2023
This PR adds a Rails feature introduced by rails/rails#38870 to docs.
koic added a commit to koic/rubocop-rails that referenced this pull request Mar 18, 2023
This PR adds a Rails feature introduced by rails/rails#38870 to docs.
koic added a commit to koic/rubocop-rails that referenced this pull request Mar 18, 2023
This PR adds a Rails feature introduced by rails/rails#38870 to docs.
koic added a commit to koic/rails that referenced this pull request Dec 31, 2023
…rate`

## Motivation / Background

RuboCop has now been included by default (rails#50456).
By adding the following tip to the default configuration, user can apply RuboCop's autocorrection to
code generated by `bin/rails generate` (e.g., migration file):

https://github.com/rubocop/rubocop-rails#rails-configuration-tip

This means that the generated files will be formatted according to user's .rubocop.yml custom configuration.

## Detail

Since `bin/rails generate` and `bin/rubocop` are used only in the development environment,
the target files are limited to only `config/environments/development.rb`.

## Additional information

This feature was introduced in Rails 6.1 by rails#38870.
dhh pushed a commit that referenced this pull request Jan 1, 2024
…rate` (#50506)

* Apply autocorrection by RuboCop to files generated by `bin/rails generate`

## Motivation / Background

RuboCop has now been included by default (#50456).
By adding the following tip to the default configuration, user can apply RuboCop's autocorrection to
code generated by `bin/rails generate` (e.g., migration file):

https://github.com/rubocop/rubocop-rails#rails-configuration-tip

This means that the generated files will be formatted according to user's .rubocop.yml custom configuration.

## Detail

Since `bin/rails generate` and `bin/rubocop` are used only in the development environment,
the target files are limited to only `config/environments/development.rb`.

## Additional information

This feature was introduced in Rails 6.1 by #38870.
yoones pushed a commit to yoones/rails that referenced this pull request Mar 6, 2025
…rate` (rails#50506)

* Apply autocorrection by RuboCop to files generated by `bin/rails generate`

## Motivation / Background

RuboCop has now been included by default (rails#50456).
By adding the following tip to the default configuration, user can apply RuboCop's autocorrection to
code generated by `bin/rails generate` (e.g., migration file):

https://github.com/rubocop/rubocop-rails#rails-configuration-tip

This means that the generated files will be formatted according to user's .rubocop.yml custom configuration.

## Detail

Since `bin/rails generate` and `bin/rubocop` are used only in the development environment,
the target files are limited to only `config/environments/development.rb`.

## Additional information

This feature was introduced in Rails 6.1 by rails#38870.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants