我希望 Rakefile 中的 :default 任务成为一条有用的消息,其中还包括为那些不熟悉 rake 的人提供的可用任务列表(rake -T 的输出)。
如何从任务内部调用 rake -T?
在较新版本的 rake 中,从任务内调用
rake -T
有点复杂。需要设置的选项可能来自方法rake/lib/application.rb
中的standard_rake_options
。基本上这可以归结为
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
请注意,
record_task_metadata
无法在默认任务中设置,因为在执行任务时已经为时已晚(描述不会被收集,因此这些描述为零,因此没有任务与模式匹配)。尝试从任务中重新加载 Rakefile 将导致闭环。我认为在总是收集元数据时存在性能权衡。如果这是一个问题
task :default do
system("rake -sT") # s for silent
end
可能更合适。
两者都适合我使用 rake 0.9.2.2。
没关系。一旦我找到了正确的方法,我就找到了答案。
除了调用 display_tasks_and_comments 之外,您还必须设置正则表达式来过滤要显示的任务,否则默认情况下它将全部过滤掉。
要使默认任务成为 rake -T 的输出,请使用以下命令:
task :default do
Rake.application.options.show_task_pattern = //
Rake.application.display_tasks_and_comments()
end
这比很多人需要的更复杂,但是这个程序将从其他 rake 文件中提取 rake 任务,而不包括其他 rake 文件。我将它用作需要验证其他 rakefiles 的 rake 任务的一部分。
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
desc "Show all the tasks"
task :default do
browser = RakeBrowser.new('common.rake')
browser.tasks.each do |task|
puts " " + task
end
end
完整代码位于
rake = Rake::Application.new
rake.load_rakefile
Rake::Task.tasks # Returns an array of `Rake::Task` objects