From a36505d33f873f8f475a28dc4fc48a913b82e8eb Mon Sep 17 00:00:00 2001 From: Eric Hodel Date: Mon, 24 Nov 2014 16:07:58 -0800 Subject: [PATCH] Stop editing ARGV Previously ARGV was edited by rake when it processed arguments. This made it difficult to re-exec rake within itself as the arguments were gone when rake started. Now rake duplicates ARGV and modifies only the duplicate. Fixes #277 --- History.rdoc | 2 ++ lib/rake/application.rb | 10 ++++++++-- test/test_rake_application.rb | 22 +++++++++++----------- 3 files changed, 21 insertions(+), 13 deletions(-) diff --git a/History.rdoc b/History.rdoc index 2f4e94a0f..cbeb76af5 100644 --- a/History.rdoc +++ b/History.rdoc @@ -7,6 +7,8 @@ Enhancements: Coulman. * Rake now ignores falsy dependencies which allows for easier programmatic creation of tasks. Pull request #273 by Manav. +* Rake no longer edits ARGV. This allows you to re-exec rake from a rake + task. Issue #277 by Matt Palmer. Bug fixes: diff --git a/lib/rake/application.rb b/lib/rake/application.rb index 795b4685d..96f907b07 100644 --- a/lib/rake/application.rb +++ b/lib/rake/application.rb @@ -20,6 +20,9 @@ class Application include TaskManager include TraceOutput + # The command-line arguments rake is using (defaults to ARGV) + attr_reader :argv # :nodoc: + # The name of the application (typically 'rake') attr_reader :name @@ -45,6 +48,7 @@ class Application # Initialize a Rake::Application object. def initialize super + @argv = ARGV.dup @name = 'rake' @rakefiles = DEFAULT_RAKEFILES.dup @rakefile = nil @@ -73,6 +77,8 @@ def initialize # call +top_level+ to run your top level tasks. def run standard_exception_handling do + @argv = argv + init load_rakefile top_level @@ -633,7 +639,7 @@ def handle_options # :nodoc: standard_rake_options.each { |args| opts.on(*args) } opts.environment('RAKEOPT') - end.parse! + end.parse! @argv end # Similar to the regular Ruby +require+ command, but will check @@ -729,7 +735,7 @@ def standard_system_dir #:nodoc: # Environmental assignments are processed at this time as well. def collect_command_line_tasks # :nodoc: @top_level_tasks = [] - ARGV.each do |arg| + @argv.each do |arg| if arg =~ /^(\w+)=(.*)$/m ENV[$1] = $2 else diff --git a/test/test_rake_application.rb b/test/test_rake_application.rb index f52040471..19e500598 100644 --- a/test/test_rake_application.rb +++ b/test/test_rake_application.rb @@ -10,9 +10,9 @@ def setup end def setup_command_line(*options) - ARGV.clear + @app.argv.clear options.each do |option| - ARGV << option + @app.argv << option end end @@ -268,7 +268,7 @@ def test_load_rakefile_doesnt_print_rakefile_directory_from_subdir_if_silent end def test_load_rakefile_not_found - ARGV.clear + @app.argv.clear Dir.chdir @tempdir ENV['RAKE_SYSTEM'] = 'not_exist' @@ -378,7 +378,7 @@ def test_handle_options_should_strip_options_from_argv @app.handle_options - assert !ARGV.include?(valid_option) + assert !@app.argv.include?(valid_option) assert @app.options.trace end @@ -406,14 +406,14 @@ def test_handle_options_trace_does_not_eat_following_task_names setup_command_line("--trace", "sometask") @app.handle_options - assert ARGV.include?("sometask") + assert @app.argv.include?("sometask") assert @app.options.trace end def test_good_run ran = false - ARGV << '--rakelib=""' + @app.argv << '--rakelib=""' @app.options.silent = true @@ -468,7 +468,7 @@ def test_bad_run } assert_match(/see full trace/i, err) ensure - ARGV.clear + @app.argv.clear end def test_bad_run_with_trace @@ -479,7 +479,7 @@ def test_bad_run_with_trace } refute_match(/see full trace/i, err) ensure - ARGV.clear + @app.argv.clear end def test_bad_run_with_backtrace @@ -492,7 +492,7 @@ def test_bad_run_with_backtrace } refute_match(/see full trace/, err) ensure - ARGV.clear + @app.argv.clear end CustomError = Class.new(RuntimeError) @@ -549,7 +549,7 @@ def test_printing_original_exception_cause end assert_match(/Secondary Error/, err) ensure - ARGV.clear + @app.argv.clear end def test_run_with_bad_options @@ -559,7 +559,7 @@ def test_run_with_bad_options capture_io { @app.run } } ensure - ARGV.clear + @app.argv.clear end def test_standard_exception_handling_invalid_option