From 0c61366844d37bd424637cadb05bb749e2a0774d 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 | 15 ++++++++++----- test/test_rake_application.rb | 20 ++++++++++++++++++++ 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/lib/rake/application.rb b/lib/rake/application.rb index 9ac9b2130..a1b61871a 100644 --- a/lib/rake/application.rb +++ b/lib/rake/application.rb @@ -155,19 +155,24 @@ 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 = string.to_s.dup + safe_call = !!string.chomp!('?') + + /^([^\[]+)(?:\[(.*)\])$/ =~ string name = $1 remaining_args = $2 - 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 +183,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"