未验证 提交 d80c18a3 编写于 作者: Y y-yagi 提交者: GitHub

Merge pull request #38870 from y-yagi/add_after_generate

Add `config.generators.after_generate` for processing to generated files
* 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 @@ def +(other) # :nodoc:
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 @@ def initialize
@colorize_logging = true
@api_only = false
@hidden_namespaces = []
@after_generate_callbacks = []
end
def initialize_copy(source)
......@@ -131,6 +132,10 @@ def hide_namespace(namespace)
@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 @@ def configure!(config) #:nodoc:
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 @@ def options #:nodoc:
@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 @@ 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
else
options = sorted_groups.flat_map(&:last)
suggestion = Rails::Command::Spellchecker.suggest(namespace.to_s, from: options)
......@@ -281,6 +287,11 @@ def invoke(namespace, args = ARGV, config = {})
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 @@ def lookup_paths # :doc:
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 @@ def identical?
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 @@ def migration_template(source, destination, config = {})
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 @@ def initialize(args, *options) #:nodoc:
no_tasks do
def template(source, *args, &block)
inside_template do
super
Rails::Generators.add_generated_file(super)
end
end
......
......@@ -217,5 +217,37 @@ def check_expected
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 @@ def test_invoke_when_exists_identical
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" }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册