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?
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"]