From 0824cce3fb8f31b55c990d71d9f0c0d19fc11926 Mon Sep 17 00:00:00 2001 From: Jean Boussier Date: Tue, 9 Feb 2021 15:45:52 +0100 Subject: [PATCH] Add safe invocation CLI syntax SUch syntax is useful for projects like buildpacks and other automated CI/CD tools. It would allow these tools to very easily invoke a task if it exists, without failing if it doesn't. --- lib/rake/application.rb | 14 ++++++++------ test/test_rake_application.rb | 20 ++++++++++++++++++++ 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/lib/rake/application.rb b/lib/rake/application.rb index 9ac9b2130..b8e844e6d 100644 --- a/lib/rake/application.rb +++ b/lib/rake/application.rb @@ -155,19 +155,21 @@ def thread_pool # :nodoc: # Invokes a task with arguments that are extracted from +task_string+ def invoke_task(task_string) # :nodoc: - name, args = parse_task_string(task_string) + name, args, safe_call = parse_task_string(task_string) + return if safe_call && !lookup(name) + t = self[name] t.invoke(*args) end def parse_task_string(string) # :nodoc: - /^([^\[]+)(?:\[(.*)\])$/ =~ string.to_s - + /^([^\[]+)(?:\[(.*)\])(\?)?$/ =~ string.to_s name = $1 remaining_args = $2 + safe_call = !!$~.begin(3) - return string, [] unless name - return name, [] if remaining_args.empty? + return string, [], safe_call unless name + return name, [], safe_call if remaining_args.empty? args = [] @@ -178,7 +180,7 @@ def parse_task_string(string) # :nodoc: args << $1.gsub(/\\(.)/, '\1') end while remaining_args - return name, args + return name, args, safe_call end # Provide standard exception handling for the given block. diff --git a/test/test_rake_application.rb b/test/test_rake_application.rb index 8514da354..89966c737 100644 --- a/test/test_rake_application.rb +++ b/test/test_rake_application.rb @@ -439,6 +439,26 @@ def test_good_run assert_equal "DEFAULT\n", out end + def test_safe_run + ran = false + + @app.options.silent = true + + @app.instance_eval do + intern(Rake::Task, "default").enhance { ran = true } + end + + rakefile_default + + out, err = capture_io do + @app.run %w[--rakelib="" default missing?] + end + + assert ran + assert_empty err + assert_equal "DEFAULT\n", out + end + def test_display_task_run ran = false @app.last_description = "COMMENT"