From a04a55f32739321593ff3daab427c37c80012e16 Mon Sep 17 00:00:00 2001 From: Guilherme Carreiro Date: Sun, 8 May 2022 19:06:45 +0200 Subject: [PATCH] Fix issues #173 and #192 by introducing the `Rake::Task#results` --- lib/rake.rb | 1 + lib/rake/task.rb | 15 +++++--- lib/rake/task_action.rb | 32 ++++++++++++++++ rake.gemspec | 1 + test/test_rake_task_results.rb | 69 ++++++++++++++++++++++++++++++++++ 5 files changed, 112 insertions(+), 6 deletions(-) create mode 100644 lib/rake/task_action.rb create mode 100644 test/test_rake_task_results.rb diff --git a/lib/rake.rb b/lib/rake.rb index 0dfd05315..43e97a98a 100644 --- a/lib/rake.rb +++ b/lib/rake.rb @@ -39,6 +39,7 @@ module Rake; end require "rake/linked_list" require "rake/cpu_counter" require "rake/scope" +require "rake/task_action" require "rake/task_argument_error" require "rake/rule_recursion_overflow_error" require "rake/rake_module" diff --git a/lib/rake/task.rb b/lib/rake/task.rb index a8ed24ddf..6f474cc54 100644 --- a/lib/rake/task.rb +++ b/lib/rake/task.rb @@ -114,7 +114,7 @@ def initialize(task_name, app) # Enhance a task with prerequisites or actions. Returns self. def enhance(deps=nil, &block) @prerequisites |= deps if deps - @actions << block if block_given? + @actions << TaskAction.new(&block) if block_given? self end @@ -182,6 +182,11 @@ def clear_args self end + # List of results for all invocations of a rake task. + def results + @actions.flat_map { |act| act.results } + end + # Invoke the task if it is needed. Prerequisites are invoked first. def invoke(*args) task_args = TaskArguments.new(arg_names, args) @@ -275,11 +280,9 @@ def execute(args=nil) end application.trace "** Execute #{name}" if application.options.trace application.enhance_with_matching_rule(name) if @actions.empty? - if opts = Hash.try_convert(args) and !opts.empty? - @actions.each { |act| act.call(self, args, **opts) } - else - @actions.each { |act| act.call(self, args) } - end + opts = Hash.try_convert(args) + + @actions.each { |act| act.call(self, args, opts) } end # Is this task needed? diff --git a/lib/rake/task_action.rb b/lib/rake/task_action.rb new file mode 100644 index 000000000..2079de772 --- /dev/null +++ b/lib/rake/task_action.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true +module Rake + + ## + # A TaskAction represents each action of a task. + # + class TaskAction + attr_reader :results + + def initialize(&block) + @block = block + @results = [] + end + + def call(argc, argv, opts) + results << call_block(argc, argv, opts) + rescue => error + results << error + raise error + end + + private + + def call_block(argc, argv, opts) + if opts && !opts.empty? + @block.call(argc, argv, **opts) + else + @block.call(argc, argv) + end + end + end +end diff --git a/rake.gemspec b/rake.gemspec index 20a1db423..933282357 100644 --- a/rake.gemspec +++ b/rake.gemspec @@ -79,6 +79,7 @@ Rake has the following features: "lib/rake/rule_recursion_overflow_error.rb", "lib/rake/scope.rb", "lib/rake/task.rb", + "lib/rake/task_action.rb", "lib/rake/task_argument_error.rb", "lib/rake/task_arguments.rb", "lib/rake/task_manager.rb", diff --git a/test/test_rake_task_results.rb b/test/test_rake_task_results.rb new file mode 100644 index 000000000..34593efa6 --- /dev/null +++ b/test/test_rake_task_results.rb @@ -0,0 +1,69 @@ +# frozen_string_literal: true +require File.expand_path("../helper", __FILE__) + +class TestRakeTaskArgumentParsing < Rake::TestCase # :nodoc: + def setup + super + + @app = Rake::Application.new + end + + def test_results_with_a_simple_task_and_a_single_invocation + task = Rake::Task.new("simple", @app) + + task.enhance(nil) { "result" } + task.invoke + + assert_equal ["result"], task.results + end + + def test_results_with_a_simple_task_and_multiple_invocations + task = Rake::Task.new("simple", @app) + + task.enhance(nil) { "result" } + task.invoke + task.reenable + task.invoke + + assert_equal ["result", "result"], task.results + end + + def test_results_with_a_composite_task_and_a_single_invocation + task = Rake::Task.new("composite", @app) + + task.enhance(nil) { "result1" } + task.enhance(nil) { "result2" } + task.invoke + + assert_equal ["result1", "result2"], task.results + end + + def test_results_with_a_composite_task_and_multiple_invocations + task = Rake::Task.new("composite", @app) + + task.enhance(nil) { "result1" } + task.enhance(nil) { "result2" } + + task.invoke + task.reenable + task.invoke + + assert_equal ["result1", "result1", "result2", "result2"], task.results + end + + def test_results_with_an_empty_task + task = Rake::Task.new("empty", @app) + task.invoke + + assert task.results.empty? + end + + def test_results_with_a_composite_task_and_no_invocations + task = Rake::Task.new("composite", @app) + + task.enhance(nil) { "result1" } + task.enhance(nil) { "result2" } + + assert task.results.empty? + end +end