Add `config.generators.after_generate` for processing to generated files
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 ```
This commit is contained in:
parent
e61bdbf315
commit
fde100d18e
|
@ -1,3 +1,9 @@
|
|||
* Add `config.generators.after_generate` for processing to generated files.
|
||||
|
||||
Register a callback that will get called right after generators has finished.
|
||||
|
||||
*Yuji Yaginuma*
|
||||
|
||||
* Make test file patterns configurable via Environment variables
|
||||
|
||||
This makes test file patterns configurable via two environment variables:
|
||||
|
|
|
@ -108,7 +108,7 @@ module Rails
|
|||
|
||||
class Generators #:nodoc:
|
||||
attr_accessor :aliases, :options, :templates, :fallbacks, :colorize_logging, :api_only
|
||||
attr_reader :hidden_namespaces
|
||||
attr_reader :hidden_namespaces, :after_generate_callbacks
|
||||
|
||||
def initialize
|
||||
@aliases = Hash.new { |h, k| h[k] = {} }
|
||||
|
@ -118,6 +118,7 @@ module Rails
|
|||
@colorize_logging = true
|
||||
@api_only = false
|
||||
@hidden_namespaces = []
|
||||
@after_generate_callbacks = []
|
||||
end
|
||||
|
||||
def initialize_copy(source)
|
||||
|
@ -131,6 +132,10 @@ module Rails
|
|||
@hidden_namespaces << namespace
|
||||
end
|
||||
|
||||
def after_generate(&block)
|
||||
@after_generate_callbacks << block
|
||||
end
|
||||
|
||||
def method_missing(method, *args)
|
||||
method = method.to_s.sub(/=$/, "").to_sym
|
||||
|
||||
|
|
|
@ -80,6 +80,7 @@ module Rails
|
|||
templates_path.concat config.templates
|
||||
templates_path.uniq!
|
||||
hide_namespaces(*config.hidden_namespaces)
|
||||
after_generate_callbacks.replace config.after_generate_callbacks
|
||||
end
|
||||
|
||||
def templates_path #:nodoc:
|
||||
|
@ -94,6 +95,10 @@ module Rails
|
|||
@options ||= DEFAULT_OPTIONS.dup
|
||||
end
|
||||
|
||||
def after_generate_callbacks # :nodoc:
|
||||
@after_generate_callbacks ||= []
|
||||
end
|
||||
|
||||
# Hold configured generators fallbacks. If a plugin developer wants a
|
||||
# generator group to fallback to another group in case of missing generators,
|
||||
# they can add a fallback.
|
||||
|
@ -269,6 +274,7 @@ module Rails
|
|||
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
|
||||
else
|
||||
options = sorted_groups.flat_map(&:last)
|
||||
suggestion = Rails::Command::Spellchecker.suggest(namespace.to_s, from: options)
|
||||
|
@ -281,6 +287,11 @@ module Rails
|
|||
end
|
||||
end
|
||||
|
||||
def add_generated_file(file) # :nodoc:
|
||||
(@@generated_files ||= []) << file
|
||||
file
|
||||
end
|
||||
|
||||
private
|
||||
def print_list(base, namespaces) # :doc:
|
||||
namespaces = namespaces.reject { |n| hidden_namespaces.include?(n) }
|
||||
|
@ -314,6 +325,15 @@ module Rails
|
|||
def file_lookup_paths # :doc:
|
||||
@file_lookup_paths ||= [ "{#{lookup_paths.join(',')}}", "**", "*_generator.rb" ]
|
||||
end
|
||||
|
||||
def run_after_generate_callback
|
||||
if defined?(@@generated_files) && !@@generated_files.empty?
|
||||
@after_generate_callbacks.each do |callback|
|
||||
callback.call(@@generated_files)
|
||||
end
|
||||
@@generated_files = []
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -19,6 +19,11 @@ module Rails
|
|||
exists? && File.binread(existing_migration) == render
|
||||
end
|
||||
|
||||
def invoke!
|
||||
invoked_file = super
|
||||
File.exist?(@destination) ? invoked_file : relative_existing_migration
|
||||
end
|
||||
|
||||
def revoke!
|
||||
say_destination = exists? ? relative_existing_migration : relative_destination
|
||||
say_status :remove, :red, say_destination
|
||||
|
|
|
@ -62,13 +62,14 @@ module Rails
|
|||
dir, base = File.split(destination)
|
||||
numbered_destination = File.join(dir, ["%migration_number%", base].join("_"))
|
||||
|
||||
create_migration numbered_destination, nil, config do
|
||||
file = create_migration numbered_destination, nil, config do
|
||||
if ERB.instance_method(:initialize).parameters.assoc(:key) # Ruby 2.6+
|
||||
ERB.new(::File.binread(source), trim_mode: "-", eoutvar: "@output_buffer").result(context)
|
||||
else
|
||||
ERB.new(::File.binread(source), nil, "-", "@output_buffer").result(context)
|
||||
end
|
||||
end
|
||||
Rails::Generators.add_generated_file(file)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -22,7 +22,7 @@ module Rails
|
|||
no_tasks do
|
||||
def template(source, *args, &block)
|
||||
inside_template do
|
||||
super
|
||||
Rails::Generators.add_generated_file(super)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -217,5 +217,37 @@ module ApplicationTests
|
|||
output = rails("generate", "model", "post", "title:string", "body:string", "--force")
|
||||
assert_no_match(/The name 'Post' is either already used in your application or reserved/, output)
|
||||
end
|
||||
|
||||
test "generators with after_generate callback" do
|
||||
model_file = File.join(app_path, "app/models/post.rb")
|
||||
with_config do |c|
|
||||
c.generators.after_generate do |files|
|
||||
expected = %w(
|
||||
db/migrate/20000101000000_create_posts.rb
|
||||
app/models/post.rb
|
||||
test/models/post_test.rb
|
||||
test/fixtures/posts.yml
|
||||
app/controllers/posts_controller.rb
|
||||
app/views/posts/index.html.erb
|
||||
app/views/posts/edit.html.erb
|
||||
app/views/posts/show.html.erb
|
||||
app/views/posts/new.html.erb
|
||||
app/views/posts/_form.html.erb
|
||||
test/controllers/posts_controller_test.rb
|
||||
test/system/posts_test.rb
|
||||
app/helpers/posts_helper.rb
|
||||
)
|
||||
assert_equal expected, files
|
||||
|
||||
File.open(model_file, "a") { |f| f.write("# Add comment to model") }
|
||||
end
|
||||
end
|
||||
|
||||
travel_to Time.utc(2000, 1, 1) do
|
||||
rails("generate", "scaffold", "post", "title:string")
|
||||
end
|
||||
|
||||
assert_match(/# Add comment to model/, File.read(model_file))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -73,6 +73,15 @@ class CreateMigrationTest < Rails::Generators::TestCase
|
|||
assert_predicate @migration, :identical?
|
||||
end
|
||||
|
||||
def test_invoke_return_existing_file_when_exists_identical
|
||||
migration_exists!
|
||||
create_migration
|
||||
|
||||
invoked_file = nil
|
||||
quietly { invoked_file = @migration.invoke! }
|
||||
assert_equal @existing_migration.relative_existing_migration, invoked_file
|
||||
end
|
||||
|
||||
def test_invoke_when_exists_not_identical
|
||||
migration_exists!
|
||||
create_migration { "different content" }
|
||||
|
|
Loading…
Reference in New Issue