Lorin
Lorin

Reputation: 1022

Rake: how to output a list of tasks from inside a task?

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 from inside a task?

Upvotes: 18

Views: 2731

Answers (4)

Artur INTECH
Artur INTECH

Reputation: 7246

April 2024 update:

rake = Rake::Application.new
rake.load_rakefile
Rake::Task.tasks # Returns an array of `Rake::Task` objects

Upvotes: 0

William Entriken
William Entriken

Reputation: 39243

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

Upvotes: 0

Stefan
Stefan

Reputation: 144

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.

Upvotes: 12

Lorin
Lorin

Reputation: 1022

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

Upvotes: 2

Related Questions