Skip to content

Commit e807099

Browse files
authored
Merge pull request rails#37516 from jonathanhefner/generator-generate-avoid-shell-out
Avoid shelling out for generator `generate` action
2 parents 5bd61a2 + dcc3c85 commit e807099

File tree

2 files changed

+68
-10
lines changed

2 files changed

+68
-10
lines changed

railties/lib/rails/generators/actions.rb

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# frozen_string_literal: true
22

3+
require "shellwords"
34
require "active_support/core_ext/string/strip"
45

56
module Rails
@@ -225,9 +226,9 @@ def generate(what, *args)
225226
log :generate, what
226227

227228
options = args.extract_options!
228-
argument = args.flat_map(&:to_s).join(" ")
229+
options[:abort_on_failure] = !options[:inline]
229230

230-
execute_command :rails, "generate #{what} #{argument}", options
231+
rails_command "generate #{what} #{args.join(" ")}", options
231232
end
232233

233234
# Runs the supplied rake task (invoked with 'rake ...')
@@ -247,7 +248,17 @@ def rake(command, options = {})
247248
# rails_command("gems:install", sudo: true)
248249
# rails_command("gems:install", capture: true)
249250
def rails_command(command, options = {})
250-
execute_command :rails, command, options
251+
if options[:inline]
252+
log :rails, command
253+
command, *args = Shellwords.split(command)
254+
in_root do
255+
silence_warnings do
256+
::Rails::Command.invoke(command, args, options)
257+
end
258+
end
259+
else
260+
execute_command :rails, command, options
261+
end
251262
end
252263

253264
# Make an entry in Rails routing file <tt>config/routes.rb</tt>

railties/test/generators/actions_test.rb

Lines changed: 54 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -378,22 +378,36 @@ def test_initializer_should_write_date_to_file_with_block_in_config_initializers
378378
assert_file "config/initializers/constants.rb", code.strip_heredoc
379379
end
380380

381-
def test_generate_should_run_script_generate_with_argument_and_options
381+
test "generate" do
382382
run_generator
383383
action :generate, "model", "MyModel"
384384
assert_file "app/models/my_model.rb", /MyModel/
385385
end
386386

387-
def test_generate_aborts_when_subprocess_fails_if_requested
387+
test "generate should raise on failure" do
388388
run_generator
389-
content = capture(:stderr) do
389+
message = capture(:stderr) do
390390
assert_raises SystemExit do
391-
action :generate, "model", "MyModel:ADsad", abort_on_failure: true
392-
action :generate, "model", "MyModel"
391+
action :generate, "model", "1234567890"
393392
end
394393
end
395-
assert_match(/wrong constant name MyModel:aDsad/, content)
396-
assert_no_file "app/models/my_model.rb"
394+
assert_match(/1234567890/, message)
395+
end
396+
397+
test "generate with inline option" do
398+
run_generator
399+
assert_not_called(generator, :run) do
400+
action :generate, "model", "MyModel", inline: true
401+
end
402+
assert_file "app/models/my_model.rb", /MyModel/
403+
end
404+
405+
test "generate with inline option should raise on failure" do
406+
run_generator
407+
error = assert_raises do
408+
action :generate, "model", "1234567890", inline: true
409+
end
410+
assert_match(/1234567890/, error.message)
397411
end
398412

399413
test "rake should run rake with the default environment" do
@@ -438,6 +452,14 @@ def test_generate_aborts_when_subprocess_fails_if_requested
438452
end
439453
end
440454

455+
test "rake with abort_on_failure option should raise on failure" do
456+
capture(:stderr) do
457+
assert_raises SystemExit do
458+
action :rake, "invalid", abort_on_failure: true
459+
end
460+
end
461+
end
462+
441463
test "rails_command should run rails with the default environment" do
442464
assert_runs "rails log:clear", env: { "RAILS_ENV" => "development" } do
443465
with_rails_env nil do
@@ -484,6 +506,31 @@ def test_generate_aborts_when_subprocess_fails_if_requested
484506
end
485507
end
486508

509+
test "rails_command with abort_on_failure option should raise on failure" do
510+
run_generator
511+
capture(:stderr) do
512+
assert_raises SystemExit do
513+
action :rails_command, "invalid", abort_on_failure: true
514+
end
515+
end
516+
end
517+
518+
test "rails_command with inline option" do
519+
run_generator
520+
assert_not_called(generator, :run) do
521+
action :rails_command, "generate model MyModel", inline: true
522+
end
523+
assert_file "app/models/my_model.rb", /MyModel/
524+
end
525+
526+
test "rails_command with inline option should raise on failure" do
527+
run_generator
528+
error = assert_raises do
529+
action :rails_command, "generate model 1234567890", inline: true
530+
end
531+
assert_match(/1234567890/, error.message)
532+
end
533+
487534
test "route should add route" do
488535
run_generator
489536
route_commands = ["get 'foo'", "get 'bar'", "get 'baz'"]

0 commit comments

Comments
 (0)