10

I'm looking for a way to be able to check if a certain rake task exists from within the Rakefile. I have a task dependency that I only want to include as a dependency if that task is available. In this particular case, the task is only available in a Rails project, but I want my rake tasks to work in a more general Ruby application environment too (not just Rails).

I want to do something like this:

if tasks.includes?('assets:precompile')
  task :archive => [:clean, :vendor_deps, 'assets:precompile']
    ...
  end
else
  task :archive => [:clean, :vendor_deps]
    ...
  end
end

What is the best way to conditionally include a task dependency in a rake task?

Bryan Ash
  • 4,385
  • 3
  • 41
  • 57
Conor Livingston
  • 905
  • 1
  • 8
  • 17

2 Answers2

15

what about doing something like this? Invoke the task if it exists, as opposed to making it an explicit dependency?

 task :archive => [:clean, :vendor_deps] do 
  Rake.application["assets:precompile"].invoke if Rake::Task.task_defined?('assets:precompile')
   .... 
  end

or even easier. Since specifying the task again allows you to add to it, something like this appears to work as well.

task :archive => [:clean, :vendor_deps] do
    ...
  end
task :archive => "assets:precompile" if  Rake::Task.task_defined?("assets:precompile")

which will conditionally add the dependency on assets:precompile if it is defined.

Doon
  • 19,719
  • 3
  • 40
  • 44
  • 1
    Chose @Doon's answer because of the more thorough explanation. – Conor Livingston Apr 23 '15 at 16:24
  • 1
    Fair enough. Just be slightly careful with `invoke` as it doesn't work quite the same as dependencies. It will always run the rake task whereas with a dependency it will only run the rake task if it hasn't already been run. – Shadwell Apr 24 '15 at 07:48
  • 2
    @Shadwell, Doesn't invoke do only if needed whereas execute runs it regardless? In the first example it should invoke it it, and if it hasn't been executed already, it will execute. If it has been it will still invoke but not execute.. If I needed this I would probably just the latter example it is more useful/general, I think. – Doon Apr 24 '15 at 11:58
  • 1
    @Doon You're absolutely right - I was getting it muddled with `execute`. `invoke` does indeed only call it if it hasn't already. Sorry for the confusion. I agree with you in preferring the second solution too. – Shadwell Apr 24 '15 at 12:22
6

You should be able to use task_defined?:

Rake::Task.task_defined?('assets:precompile')
Shadwell
  • 34,314
  • 14
  • 94
  • 99