diff --git a/lib/rake/application.rb b/lib/rake/application.rb index ae594e098..8c896888f 100644 --- a/lib/rake/application.rb +++ b/lib/rake/application.rb @@ -62,6 +62,8 @@ def initialize add_loader("rake", DefaultLoader.new) @tty_output = STDOUT.tty? @terminal_columns = ENV["RAKE_COLUMNS"].to_i + + set_default_options end # Run the Rake application. The run method performs the following @@ -74,19 +76,19 @@ def initialize # If you wish to build a custom rake command, you should call # +init+ on your application. Then define any tasks. Finally, # call +top_level+ to run your top level tasks. - def run + def run(argv = ARGV) standard_exception_handling do - init + init 'rake', argv load_rakefile top_level end end # Initialize the command line parameters and app name. - def init(app_name="rake") + def init(app_name="rake", argv = ARGV) standard_exception_handling do @name = app_name - args = handle_options + args = handle_options argv collect_command_line_tasks(args) end end @@ -618,9 +620,8 @@ def select_trace_output(options, trace_option, value) # :nodoc: # Read and handle the command line options. Returns the command line # arguments that we didn't understand, which should (in theory) be just # task names and env vars. - def handle_options # :nodoc: - options.rakelib = ["rakelib"] - options.trace_output = $stderr + def handle_options(argv) # :nodoc: + set_default_options OptionParser.new do |opts| opts.banner = "#{Rake.application.name} [-f rakefile] {options} targets..." @@ -634,7 +635,7 @@ def handle_options # :nodoc: standard_rake_options.each { |args| opts.on(*args) } opts.environment("RAKEOPT") - end.parse(ARGV) + end.parse(argv) end # Similar to the regular Ruby +require+ command, but will check @@ -782,5 +783,28 @@ def rakefile_location(backtrace=caller) # :nodoc: backtrace.find { |str| str =~ re } || "" end + def set_default_options + options.always_multitask = false + options.backtrace = false + options.build_all = false + options.dryrun = false + options.ignore_deprecate = false + options.ignore_system = false + options.job_stats = false + options.load_system = false + options.nosearch = false + options.rakelib = %w[rakelib] + options.show_all_tasks = false + options.show_prereqs = false + options.show_task_pattern = nil + options.show_tasks = nil + options.silent = false + options.suppress_backtrace_pattern = nil + options.thread_pool_size = Rake.suggested_thread_count + options.trace = false + options.trace_output = $stderr + options.trace_rules = false + end + end end diff --git a/lib/rake/rake_module.rb b/lib/rake/rake_module.rb index f5cfde58a..03c295624 100644 --- a/lib/rake/rake_module.rb +++ b/lib/rake/rake_module.rb @@ -34,6 +34,34 @@ def add_rakelib(*files) application.options.rakelib ||= [] application.options.rakelib.concat(files) end + + # Make +block_application+ the default rake application inside a block so + # you can load rakefiles into a different application. + # + # This is useful when you want to run rake tasks inside a library without + # running rake in a sub-shell. + # + # Example: + # + # Dir.chdir 'other/directory' + # + # other_rake = Rake.with_application do |rake| + # rake.load_rakefile + # end + # + # puts other_rake.tasks + + def with_application(block_application = Rake::Application.new) + orig_application = Rake.application + + Rake.application = block_application + + yield block_application + + block_application + ensure + Rake.application = orig_application + end end end diff --git a/test/test_rake_application.rb b/test/test_rake_application.rb index 141dd576f..456f7d878 100644 --- a/test/test_rake_application.rb +++ b/test/test_rake_application.rb @@ -10,11 +10,34 @@ def setup @app.options.rakelib = [] end - def setup_command_line(*options) - ARGV.clear - options.each do |option| - ARGV << option + def test_class_with_application + orig_app = Rake.application + + return_app = Rake.with_application do |yield_app| + refute_equal orig_app, yield_app, 'new application must be yielded' + + assert_equal yield_app, Rake.application, + 'new application must be default in block' + end + + refute_equal orig_app, return_app, 'new application not returned' + assert_equal orig_app, Rake.application, 'original application not default' + end + + def test_class_with_application_user_defined + orig_app = Rake.application + + user_app = Rake::Application.new + + return_app = Rake.with_application user_app do |yield_app| + assert_equal user_app, yield_app, 'user application must be yielded' + + assert_equal user_app, Rake.application, + 'user application must be default in block' end + + assert_equal user_app, return_app, 'user application not returned' + assert_equal orig_app, Rake.application, 'original application not default' end def test_display_exception_details @@ -26,6 +49,8 @@ def test_display_exception_details end out, err = capture_io do + @app.set_default_options # reset trace output IO + @app.display_error_message ex end @@ -42,6 +67,8 @@ def test_display_exception_details_bad_encoding end out, err = capture_io do + @app.set_default_options # reset trace output IO + @app.display_error_message ex end @@ -63,6 +90,8 @@ def test_display_exception_details_cause end out, err = capture_io do + @app.set_default_options # reset trace output IO + @app.display_error_message ex end @@ -187,7 +216,7 @@ def test_load_rakefile rakefile_unittest @app.instance_eval do - handle_options + handle_options [] options.silent = true load_rakefile end @@ -215,7 +244,7 @@ def test_load_rakefile_from_subdir Dir.chdir "subdir" @app.instance_eval do - handle_options + handle_options [] options.silent = true load_rakefile end @@ -246,7 +275,7 @@ def test_load_rakefile_doesnt_print_rakefile_directory_from_subdir_if_silent _, err = capture_io do @app.instance_eval do - handle_options + handle_options [] options.silent = true raw_load_rakefile end @@ -258,12 +287,11 @@ def test_load_rakefile_doesnt_print_rakefile_directory_from_subdir_if_silent def test_load_rakefile_not_found skip if jruby9? - ARGV.clear Dir.chdir @tempdir ENV["RAKE_SYSTEM"] = "not_exist" @app.instance_eval do - handle_options + handle_options [] options.silent = true end @@ -280,7 +308,7 @@ def test_load_from_system_rakefile rake_system_dir @app.instance_eval do - handle_options + handle_options [] options.silent = true options.load_system = true options.rakelib = [] @@ -302,7 +330,7 @@ def @app.standard_system_dir ENV["RAKE_SYSTEM"] = nil @app.instance_eval do - handle_options + handle_options [] options.silent = true options.load_system = true options.rakelib = [] @@ -362,28 +390,22 @@ def test_building_imported_files_on_demand def test_handle_options_should_not_strip_options_from_argv assert !@app.options.trace - valid_option = "--trace" - setup_command_line(valid_option) - - @app.handle_options + argv = %w[--trace] + @app.handle_options argv - assert ARGV.include?(valid_option) + assert_includes argv, '--trace' assert @app.options.trace end def test_handle_options_trace_default_is_stderr - setup_command_line("--trace") - - @app.handle_options + @app.handle_options %w[--trace] assert_equal STDERR, @app.options.trace_output assert @app.options.trace end def test_handle_options_trace_overrides_to_stdout - setup_command_line("--trace=stdout") - - @app.handle_options + @app.handle_options %w[--trace=stdout] assert_equal STDOUT, @app.options.trace_output assert @app.options.trace @@ -392,18 +414,16 @@ def test_handle_options_trace_overrides_to_stdout def test_handle_options_trace_does_not_eat_following_task_names assert !@app.options.trace - setup_command_line("--trace", "sometask") + argv = %w[--trace sometask] + @app.handle_options argv - @app.handle_options - assert ARGV.include?("sometask") + assert argv.include?("sometask") assert @app.options.trace end def test_good_run ran = false - ARGV << '--rakelib=""' - @app.options.silent = true @app.instance_eval do @@ -413,7 +433,7 @@ def test_good_run rakefile_default out, err = capture_io do - @app.run + @app.run %w[--rakelib=""] end assert ran @@ -423,10 +443,9 @@ def test_good_run def test_display_task_run ran = false - setup_command_line("-f", "-s", "--tasks", '--rakelib=""') @app.last_description = "COMMENT" @app.define_task(Rake::Task, "default") - out, = capture_io { @app.run } + out, = capture_io { @app.run %w[-f -s --tasks --rakelib=""] } assert @app.options.show_tasks assert ! ran assert_match(/rake default/, out) @@ -435,13 +454,12 @@ def test_display_task_run def test_display_prereqs ran = false - setup_command_line("-f", "-s", "--prereqs", '--rakelib=""') @app.last_description = "COMMENT" t = @app.define_task(Rake::Task, "default") t.enhance([:a, :b]) @app.define_task(Rake::Task, "a") @app.define_task(Rake::Task, "b") - out, = capture_io { @app.run } + out, = capture_io { @app.run %w[-f -s --prereqs --rakelib=""] } assert @app.options.show_prereqs assert ! ran assert_match(/rake a$/, out) @@ -451,37 +469,29 @@ def test_display_prereqs def test_bad_run @app.intern(Rake::Task, "default").enhance { fail } - setup_command_line("-f", "-s", '--rakelib=""') _, err = capture_io { - assert_raises(SystemExit) { @app.run } + assert_raises(SystemExit) { @app.run %w[-f -s --rakelib=""]} } assert_match(/see full trace/i, err) - ensure - ARGV.clear end def test_bad_run_with_trace @app.intern(Rake::Task, "default").enhance { fail } - setup_command_line("-f", "-s", "-t") _, err = capture_io { - assert_raises(SystemExit) { @app.run } + @app.set_default_options + assert_raises(SystemExit) { @app.run %w[-f -s -t] } } refute_match(/see full trace/i, err) - ensure - ARGV.clear end def test_bad_run_with_backtrace @app.intern(Rake::Task, "default").enhance { fail } - setup_command_line("-f", "-s", "--backtrace") _, err = capture_io { assert_raises(SystemExit) { - @app.run + @app.run %w[-f -s --backtrace] } } refute_match(/see full trace/, err) - ensure - ARGV.clear end CustomError = Class.new(RuntimeError) @@ -490,10 +500,9 @@ def test_bad_run_includes_exception_name @app.intern(Rake::Task, "default").enhance { raise CustomError, "intentional" } - setup_command_line("-f", "-s") _, err = capture_io { assert_raises(SystemExit) { - @app.run + @app.run %w[-f -s] } } assert_match(/CustomError: intentional/, err) @@ -503,10 +512,9 @@ def test_rake_error_excludes_exception_name @app.intern(Rake::Task, "default").enhance { fail "intentional" } - setup_command_line("-f", "-s") _, err = capture_io { assert_raises(SystemExit) { - @app.run + @app.run %w[-f -s] } } refute_match(/RuntimeError/, err) @@ -527,28 +535,22 @@ def test_printing_original_exception_cause raise custom_error, "Secondary Error" end } - setup_command_line("-f", "-s") _ ,err = capture_io { assert_raises(SystemExit) { - @app.run + @app.run %w[-f -s] } } if cause_supported? assert_match(/Original Error/, err) end assert_match(/Secondary Error/, err) - ensure - ARGV.clear end def test_run_with_bad_options @app.intern(Rake::Task, "default").enhance { fail } - setup_command_line("-f", "-s", "--xyzzy") assert_raises(SystemExit) { - capture_io { @app.run } + capture_io { @app.run %w[-f -s --xyzzy] } } - ensure - ARGV.clear end def test_standard_exception_handling_invalid_option @@ -568,6 +570,8 @@ def test_standard_exception_handling_invalid_option def test_standard_exception_handling_other out, err = capture_io do + @app.set_default_options # reset trace output IO + e = assert_raises SystemExit do @app.standard_exception_handling do raise "blah" diff --git a/test/test_rake_application_options.rb b/test/test_rake_application_options.rb index b34c2f634..d774678b6 100644 --- a/test/test_rake_application_options.rb +++ b/test/test_rake_application_options.rb @@ -9,7 +9,6 @@ def setup super @testkey = ENV["TESTKEY"] - clear_argv Rake::FileUtilsExt.verbose_flag = false Rake::FileUtilsExt.nowrite_flag = false TESTING_REQUIRE.clear @@ -17,32 +16,27 @@ def setup def teardown ENV["TESTKEY"] = @testkey - clear_argv Rake::FileUtilsExt.verbose_flag = false Rake::FileUtilsExt.nowrite_flag = false super end - def clear_argv - ARGV.pop until ARGV.empty? - end - def test_default_options opts = command_line - assert_nil opts.backtrace - assert_nil opts.dryrun - assert_nil opts.ignore_system - assert_nil opts.load_system - assert_nil opts.always_multitask - assert_nil opts.nosearch + assert_equal false, opts.backtrace + assert_equal false, opts.dryrun + assert_equal false, opts.ignore_system + assert_equal false, opts.load_system + assert_equal false, opts.always_multitask + assert_equal false, opts.nosearch assert_equal ["rakelib"], opts.rakelib - assert_nil opts.show_prereqs + assert_equal false, opts.show_prereqs assert_nil opts.show_task_pattern assert_nil opts.show_tasks - assert_nil opts.silent - assert_nil opts.trace - assert_nil opts.thread_pool_size + assert_equal false, opts.silent + assert_equal false, opts.trace + assert_equal Rake.suggested_thread_count, opts.thread_pool_size assert_equal ["rakelib"], opts.rakelib assert ! Rake::FileUtilsExt.verbose_flag assert ! Rake::FileUtilsExt.nowrite_flag @@ -115,7 +109,7 @@ def test_help def test_jobs flags([]) do |opts| - assert_nil opts.thread_pool_size + assert_equal Rake.suggested_thread_count, opts.thread_pool_size end flags(["--jobs", "0"], ["-j", "0"]) do |opts| assert_equal 0, opts.thread_pool_size @@ -329,12 +323,12 @@ def test_tasks flags("--tasks", "-T") do |opts| assert_equal :tasks, opts.show_tasks assert_equal(//.to_s, opts.show_task_pattern.to_s) - assert_nil opts.show_all_tasks + assert_equal false, opts.show_all_tasks end flags(["--tasks", "xyz"], ["-Txyz"]) do |opts| assert_equal :tasks, opts.show_tasks assert_equal(/xyz/.to_s, opts.show_task_pattern.to_s) - assert_nil opts.show_all_tasks + assert_equal false, opts.show_all_tasks end flags(["--tasks", "xyz", "--comments"]) do |opts| assert_equal :tasks, opts.show_tasks @@ -445,8 +439,6 @@ def test_rake_explicit_task_library def flags(*sets) sets.each do |set| - ARGV.clear - @exit = catch(:system_exit) { command_line(*set) } yield(@app.options) if block_given? @@ -454,13 +446,12 @@ def flags(*sets) end def command_line(*options) - options.each do |opt| ARGV << opt end @app = Rake::Application.new def @app.exit(*args) throw :system_exit, :exit end @app.instance_eval do - args = handle_options + args = handle_options options collect_command_line_tasks(args) end @tasks = @app.top_level_tasks diff --git a/test/test_rake_task.rb b/test/test_rake_task.rb index b2bbb6d95..8bfdedb4e 100644 --- a/test/test_rake_task.rb +++ b/test/test_rake_task.rb @@ -62,10 +62,14 @@ def test_invoke_with_circular_dependencies end def test_dry_run_prevents_actions - Rake.application.options.dryrun = true runlist = [] t1 = task(:t1) { |t| runlist << t.name; 3321 } - _, err = capture_io { t1.invoke } + _, err = capture_io { + Rake.application.set_default_options # reset trace output IO + Rake.application.options.dryrun = true + + t1.invoke + } assert_match(/execute .*t1/i, err) assert_match(/dry run/i, err) refute_match(/invoke/i, err) @@ -75,9 +79,11 @@ def test_dry_run_prevents_actions end def test_tasks_can_be_traced - Rake.application.options.trace = true t1 = task(:t1) _, err = capture_io { + Rake.application.set_default_options # reset trace output IO + Rake.application.options.trace = true + t1.invoke } assert_match(/invoke t1/i, err) diff --git a/test/test_rake_task_argument_parsing.rb b/test/test_rake_task_argument_parsing.rb index e34126591..fc494a463 100644 --- a/test/test_rake_task_argument_parsing.rb +++ b/test/test_rake_task_argument_parsing.rb @@ -96,16 +96,14 @@ def @app.unix?() raise end end def test_no_rakeopt - ARGV << "--trace" app = Rake::Application.new - app.init + app.init %w[--trace] assert !app.options.silent end def test_rakeopt_with_blank_options - ARGV << "--trace" app = Rake::Application.new - app.init + app.init %w[--trace] assert !app.options.silent end diff --git a/test/test_rake_win32.rb b/test/test_rake_win32.rb index 292af4715..6c341f486 100644 --- a/test/test_rake_win32.rb +++ b/test/test_rake_win32.rb @@ -65,7 +65,11 @@ def test_win32_backtrace_with_different_case rake.options.trace = true rake.instance_variable_set(:@rakefile, "Rakefile") - _, err = capture_io { rake.display_error_message(ex) } + _, err = capture_io { + rake.set_default_options # reset trace output IO + + rake.display_error_message(ex) + } assert_match(/rakefile/, err) end