rubytaskrakerakefile

Remove duplication from rake tasks


I have three rake tasks that modify an instance variable and then call the task :find, This is the Rakefile:

@tags = ['OPTIMIZE', 'TODO', 'FIXME']

task :optimize do
   @tags = ['OPTIMIZE']
   Rake::Task["find"].invoke
end

task :todo do
   @tags = ['TODO']
   Rake::Task["find"].invoke
end

task :fixme do
   @tags = ['FIXME']
   Rake::Task["find"].invoke
end

task :find do
   # finds words depending on @tags
end

I would like to remove duplication from the Rakefile and make it more concise. How can I simplify (or combine) the :optimize, :todo, :fixme tasks in this Rakefile?


Solution

  • Rake tasks can take arguments, so instead of relying on an instance variable you can pass the tags in:

    TAGS = ['OPTIMIZE', 'TODO', 'FIXME']
    
    task :find, [:tags] do |task, args|
      # command lines can't pass an array, afaik; so if we pass the
      # tags in, we'll need them as a space separated list
      tags = if args[:tags]
               args[:tags].split(' ')
             else
               TAGS
             end
    
      puts "finding all tags marked: #{tags.inspect}"
    end
    

    and then on the command line:

    % rake find[TODO OPTIMIZE] # may need escaped: rake find\[TODO\ OPTIMIZE\]
    finding all tags marked: ["TODO", "OPTIMIZE"]
    % rake find                  
    finding all tags marked: ["OPTIMIZE", "TODO", "FIXME"]
    

    and then, if you still want named tasks as aliases, passing certain arguments, you can pass them in through invoke:

    TAGS.each do |tag|
      task tag.downcase.to_sym do
        Rake::Task["find"].invoke(tag)
      end
    end
    

    and calling them:

    % rake todo
    finding all tags marked: ["TODO"]
    % rake fixme   
    finding all tags marked: ["FIXME"]
    % rake optimize
    finding all tags marked: ["OPTIMIZE"]