I'd like my :default task in a Rakefile to be a helpful message that also includes the list of available tasks (the output of rake -T) for people who are not as familiar with rake.
How do you invoke rake -T fro开发者_Go百科m inside a task?
Invoking rake -T
from within tasks is a bit more complicated in newer versions of rake. The options that need to be set may be derived from rake/lib/application.rb
in method standard_rake_options
. Basically this boils down to
Rake::TaskManager.record_task_metadata = true
task :default do
Rake::application.options.show_tasks = :tasks # this solves sidewaysmilk problem
Rake::application.options.show_task_pattern = //
Rake::application.display_tasks_and_comments
end
Note that record_task_metadata
cannot be set from within the default task, as it will already be too late when the task is executed (descriptions won’t have been collected, thus those are nil and therefore no task matches the pattern). Trying to reload the Rakefile from within a task will lead to a closed loop. I assume there are performance trade ofs when always collecting metadata. If that’s an issue
task :default do
system("rake -sT") # s for silent
end
might be more suitable.
Both work for me using rake 0.9.2.2.
Nevermind. I found the answer once I found the right method.
In addition to calling display_tasks_and_comments you also have to set the regexp to filter the tasks you want to show or by default it will filter them all out.
To make your default task the output of rake -T use the following:
task :default do
Rake.application.options.show_task_pattern = //
Rake.application.display_tasks_and_comments()
end
This is more complicated than a lot of people need, but this program will extract rake tasks from other rake files WITHOUT including those other rakefiles. I used it as part of a rake task that needed to validate other rakefiles.
Main class
class RakeBrowser
attr_reader :tasks
attr_reader :variables
attr_reader :loads
@last_description = ''
@namespace = ''
include Rake::DSL
def desc(description)
@last_description = description
end
def namespace(name=nil, &block) # :doc:
old = @namespace
@namespace = "#{name}:#{@namespace}"
yield(block)
@namespace = old
end
def task(*args, &block)
if args.first.respond_to?(:id2name)
@tasks << "#{@namespace}" + args.first.id2name
elsif args.first.keys.first.respond_to?(:id2name)
@tasks << "#{@namespace}" + args.first.keys.first.id2name
end
end
def load(filename)
@loads << filename
end
def initialize(file)
@tasks = []
@loads = []
Dir.chdir(File.dirname(file)) do
eval(File.read(File.basename(file)))
end
@variables = Hash.new
instance_variables.each do |name|
@variables[name] = instance_variable_get(name)
end
end
end
Implementation
desc "Show all the tasks"
task :default do
browser = RakeBrowser.new('common.rake')
browser.tasks.each do |task|
puts " " + task
end
end
Complete code is at
- https://raw.githubusercontent.com/fulldecent/Sites/master/Rakefile
- https://raw.githubusercontent.com/fulldecent/Sites/765895e9ad6e6ebc38f6925b4c407fcd8eb5e3d6/Rakefile
精彩评论