Rake: как выводить список задач изнутри задачи?

Мне бы хотелось, чтобы моя задача по умолчанию в Rakefile была полезным сообщением, которое также включает список доступных задач (выход rake -T) для людей, которые не знакомы с rake.

Как вы вызываете rake -T из задачи?

Ответы

Ответ 1

Вызов rake -T изнутри задач немного сложнее в новых версиях rake. Параметры, которые необходимо установить, могут быть получены из 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.

Ответ 2

Nevermind. Я нашел ответ, как только нашел правильный метод.

В дополнение к вызову display_tasks_and_comments вам также нужно настроить regexp для фильтрации задач, которые вы хотите показать, или по умолчанию они будут отфильтровывать их все.

Чтобы выполнить свою задачу по умолчанию, выход rake -T использует следующее:

task :default do
  Rake.application.options.show_task_pattern = //
  Rake.application.display_tasks_and_comments()
end

Ответ 3

Это сложнее, чем нужно многим людям, но эта программа будет извлекать задачи рейка из других файлов rake БЕЗ, включая другие rakefiles. Я использовал его как часть задачи рейка, которая необходима для проверки других файлов rakefiles.

Основной класс

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

Полный код находится в