jimweirich / rake

A make-like build utility for Ruby.
http://rake.rubyforge.org/
1.1k stars 10 forks source link

Return true/false from Task#invoke / #execute / ... #257

Closed nixpulvis closed 10 years ago

nixpulvis commented 10 years ago

I'm currently building a rake task that needs to call a few other rake tasks at specific times in the middle of itself. There is a bit of logic around what tasks to run based on the success of the former tasks. Right now I don't have access to information about the success of tasks run with Rake::Task['name'].invoke. I'd love to see this functionality added.

drbrain commented 10 years ago

Why don't you use the task's dependencies?

A task can choose to run or not (such as a FileTask) and dependencies maintain ordering.

drbrain commented 10 years ago

Also, if you need to run tasks "in the middle" of another task it sounds like your tasks are too big and should be broken up into smaller pieces.

nixpulvis commented 10 years ago

Well I don't have control of the other tasks. To give you a better idea, here's what I'm trying to do. It's within a rails app.

I'm writing something that drops my database using rake db:drop then rake db:create and rake db:migrate then goes off and loads production data from S3 backup.

Thing is I want to wait on the loading of the production database if dropping fails.

drbrain commented 10 years ago

This doesn't work?


task 'db:load_production' => %w[db:drop db:create db:migrate] do
  # …
end
nixpulvis commented 10 years ago

I want to backup my local database first. I guess you could argue I should make a task for that. So that's what I'm doing now. But I still feel this is something worth doing possibly, considering the return value of these methods is pretty useless right now.

drbrain commented 10 years ago

Yes, you should use a task for that:

task 'db:load_production' => %w[db:backup db:drop db:create db:migrate] do
  # …
end

Returning status information from rake's internals seems like it encourages incorrect creation of rake tasks. I'm not convinced this is a good feature yet, especially when it seems "use tasks" fixes the problem and is more flexible overall.

damphyr commented 10 years ago

You have to keep in mind that a task that does not succeed raises an exception. At least that's how it should be. This means that an unsuccessful task will interrupt your rake run anyway.

What I usually do if I want to for example run a bunch of tasks and at the end report on any errors is to loop the invoke calls with a begin/rescue block and collect any failures.

A sequence of

Task['bar'].invoke
Task['bas'].invoke
Task['foo'].invoke

is equivalent to

task :foo =>['bar','bas']

actually, not quite - if bar or bas have prerequisites then the task version might reorder the prerequisite execution)

nixpulvis commented 10 years ago

I guess I'm more in favor of the "UNIX" way. What with return codes and all.

drbrain commented 10 years ago

I am going to reject this since it allows you to use tasks in non-rake-like ways.