Skip to content

Commit

Permalink
Skip unnecessary invokes to nested task of not needed tasks
Browse files Browse the repository at this point in the history
When a task is no needed (because `needed?` is false), running it with `--trace` still report all it dependencies.

Rake is still calling `invoke_prerequisites` in a task not `needed`.

This change simply avoid that call.
  • Loading branch information
Jesús Gómez committed Jun 21, 2022
1 parent 73a2116 commit a88bf7d
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 2 deletions.
6 changes: 4 additions & 2 deletions lib/rake/task.rb
Original file line number Diff line number Diff line change
Expand Up @@ -215,8 +215,10 @@ def invoke_with_call_chain(task_args, invocation_chain)

@already_invoked = true

invoke_prerequisites(task_args, new_chain)
execute(task_args) if needed?
if needed?
invoke_prerequisites(task_args, new_chain)
execute(task_args)
end
rescue Exception => ex
add_chain_to(ex, new_chain)
@invocation_exception = ex
Expand Down
29 changes: 29 additions & 0 deletions test/test_rake_task.rb
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,35 @@ def test_tasks_can_be_traced
Rake.application.options.trace = false
end

def test_no_unnecesary_nested_invokes
test_no_unnecesary_nested_invokes__trace = [] # "Namespaced" array name

# Overwrite "invoke_with_call_chain" to trace the tasks being _invoked_
Rake::Task.alias_method :old_invoke_with_call_chain, :invoke_with_call_chain
Rake::Task.define_method(:invoke_with_call_chain) do |task_args, invocation_chain|
test_no_unnecesary_nested_invokes__trace << name
old_invoke_with_call_chain(task_args, invocation_chain)
end

# Create the dependency graph t1 -> t2 -> t3
t1 = task(t1: [:t2])
t2 = task(t2: [:t3])
t3 = task(:t3)

# Force t2 to be not needed
t2.define_singleton_method(:needed?) { false }

t1.invoke

# Restore the original "invoke_with_call_chain" method, so other
# tests don't use the patched one.
Rake::Task.alias_method :invoke_with_call_chain, :old_invoke_with_call_chain
Rake::Task.remove_method :old_invoke_with_call_chain

# Because t2 was not needed, there is no need to "invoke" t3 neither.
refute_includes test_no_unnecesary_nested_invokes__trace, "t3"
end

def test_no_double_invoke
runlist = []
t1 = task(t1: [:t2, :t3]) { |t| runlist << t.name; 3321 }
Expand Down

0 comments on commit a88bf7d

Please sign in to comment.