Как запускать задачи Rake из задач Rake?

У меня есть Rakefile, который компилирует проект двумя способами, в соответствии с глобальной переменной $build_type, которая может быть :debug или :release (результаты идут в отдельных каталогах):

task :build => [:some_other_tasks] do
end

Я хочу создать задачу, которая в свою очередь компилирует проект с обеих конфигураций:

task :build_all do
  [ :debug, :release ].each do |t|
    $build_type = t
    # call task :build with all the tasks it depends on (?)
  end
end

Есть ли способ вызвать задачу, как если бы это был метод? Или как я могу достичь чего-то подобного?

Ответ 1

Если вам нужна задача, чтобы вести себя как метод, как насчет использования фактического метода?

task :build => [:some_other_tasks] do
  build
end

task :build_all do
  [:debug, :release].each { |t| build t }
end

def build(type = :debug)
  # ...
end

Если вы предпочитаете придерживаться rake идиом, вот ваши возможности, составленные из прошлых ответов:

  • Это всегда выполняет задачу, но не выполняет ее зависимости:

    Rake::Task["build"].execute
    
  • Выполняется эта зависимость, но выполняется только эта задача, если он еще не был вызван:

    Rake::Task["build"].invoke
    
  • Это сначала сбрасывает задание is_invoked state, позволяя задаче затем выполняются снова, зависимости и все:

    Rake::Task["build"].reenable
    Rake::Task["build"].invoke
    

    (Обратите внимание, что уже запущенные зависимые функции не выполняются повторно)

Ответ 2

например:

Rake::Task["db:migrate"].invoke

Ответ 3

task :build_all do
  [ :debug, :release ].each do |t|
    $build_type = t
    Rake::Task["build"].reenable
    Rake::Task["build"].invoke
  end
end

Это должно вас разобраться, просто нужно было то же самое.

Ответ 4

task :build_all do
  [ :debug, :release ].each do |t|
    $build_type = t
    Rake::Task["build"].execute
  end
end

Ответ 5

Если вы хотите, чтобы каждая задача запускалась независимо от любых сбоев, вы можете сделать что-то вроде:

task :build_all do
  [:debug, :release].each do |t| 
    ts = 0
    begin  
      Rake::Task["build"].invoke(t)
    rescue
      ts = 1
      next
    ensure
      Rake::Task["build"].reenable # If you need to reenable
    end
    return ts # Return exit code 1 if any failed, 0 if all success
  end
end

Ответ 6

Я бы предложил не создавать общие задачи отладки и выпуска, если проект действительно является компилятором и поэтому приводит к файлам. Вы должны пойти с файловыми задачами, которые вполне применимы в вашем примере, как вы заявляете, что ваш вывод идет в разные каталоги. Скажем, ваш проект просто компилирует файл test.c для out/debug/test.out и out/release/test.out с помощью gcc вы можете настроить свой проект следующим образом:

WAYS = ['debug', 'release']
FLAGS = {}
FLAGS['debug'] = '-g'
FLAGS['release'] = '-O'
def out_dir(way)
  File.join('out', way)
end
def out_file(way)
  File.join(out_dir(way), 'test.out')
end
WAYS.each do |way|
  desc "create output directory for #{way}"
  directory out_dir(way)

  desc "build in the #{way}-way"
  file out_file(way) => [out_dir(way), 'test.c'] do |t|
    sh "gcc #{FLAGS[way]} -c test.c -o #{t.name}"
  end
end
desc 'build all ways'
task :all => WAYS.map{|way|out_file(way)}

task :default => [:all]

Эта настройка может быть использована как:

rake all # (builds debug and release)
rake debug # (builds only debug)
rake release # (builds only release)

Это немного больше, как просили, но показывает мои очки:

  • При необходимости создаются каталоги вывода
  • .
  • файлы при необходимости перекомпилируются (этот пример является правильным только для простейших файлов test.c).
  • У вас есть все задачи с готовностью, если вы хотите запустить сборку релизов или сборку отладки.
  • Этот пример включает также способ определения небольших различий между debug и release-сборками.
  • Не нужно повторно устанавливать задачу сборки, параметризованную глобальной переменной, поскольку теперь разные сборки имеют разные задачи. codereuse задачи build выполняется путем повторного использования кода для определения задач сборки. см., как цикл не выполняет одну и ту же задачу дважды, а вместо этого создает задачи, которые позже могут быть запущены (либо по всей задаче, либо выбирая одну из них в командной строке).