The issue is that invoke only invokes the task if it is needed. Running rake --trace shows:
(in /tmp/ruby) ** Invoke default (first_time) ** Execute default ** Invoke list (first_time) ** Execute list Hello level 1 ** Invoke list ** Invoke list
So you can see it’s trying to invoke the task :list two more times. But one thing you can do is to change the body of the main task to:
task :default => [] do
Rake::Task[:list].invoke 1
Rake::Task[:list].reenable
Rake::Task[:list].invoke 2
Rake::Task[:list].reenable
Rake::Task[:list].invoke 3
end
then the :list task is needed again and it correctly prints out all 3 statements.
The cleaner way to do it is to use execute rather than invoke:
task :default => [] do
Rake::Task[:list].execute 1
Rake::Task[:list].execute 2
Rake::Task[:list].execute 3
end
task :list, [:level] => [] do |t, args|
puts "Hello level #{args}"
end
That changes your puts statement to use just args rather than args.level for some reason. There are some other caveats with using execute over invoke described in the link above.