[ruby] 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

메서드처럼 작업을 호출하는 방법이 있습니까? 아니면 어떻게 비슷한 것을 얻을 수 있습니까?



답변

작업이 방법으로 작동해야하는 경우 실제 방법을 사용하는 것은 어떻습니까?

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
  • 먼저 작업의 already_invoked 상태를 재설정하여 작업, 종속성 및 모든 작업을 다시 실행할 수 있습니다.

    Rake::Task["build"].reenable
    Rake::Task["build"].invoke
    
  • 이미 호출 된 종속성은 다시 활성화하지 않으면 자동으로 다시 실행되지 않습니다. Rake> = 10.3.2에서 다음을 사용하여 이들을 다시 활성화 할 수 있습니다.

    Rake::Task["build"].all_prerequisite_tasks.each(&:reenable)

답변

예를 들면 다음과 같습니다.

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


답변

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

그것은 당신을 정리해야하며, 똑같은 것이 필요했습니다.


답변

task :invoke_another_task do
  # some code
  Rake::Task["another:task"].invoke
end


답변

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


답변

실패에 관계없이 각 작업을 실행하려면 다음과 같이 할 수 있습니다.

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


답변

프로젝트가 실제로 컴파일되어 파일로 생성되는 경우 일반 디버그 및 릴리스 작업을 작성하지 않는 것이 좋습니다. 예를 들어 출력이 다른 디렉토리로 이동한다는 것을 알 수있는 파일 작업을 수행해야합니다. 프로젝트가 test.c 파일을 gcc로 out / debug / test.out 및 out / release / test.out으로 컴파일한다고 가정하면 다음과 같이 프로젝트를 설정할 수 있습니다.

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)

이것은 요청 한대로 조금 더 수행하지만 내 요점을 보여줍니다.

  1. 필요에 따라 출력 디렉토리가 작성됩니다.
  2. 파일은 필요한 경우에만 다시 컴파일됩니다 (이 예제는 가장 간단한 test.c 파일에 대해서만 정확함).
  3. 릴리스 빌드 또는 디버그 빌드를 트리거하려는 경우 모든 작업을 즉시 수행 할 수 있습니다.
  4. 이 예제에는 디버그 빌드와 릴리스 빌드 간의 작은 차이도 정의하는 방법이 포함되어 있습니다.
  5. 이제는 빌드마다 다른 태스크가 있으므로 전역 변수로 매개 변수화 된 빌드 태스크를 다시 활성화 할 필요가 없습니다. 빌드 작업의 코드 재사용은 코드를 재사용하여 빌드 작업을 정의함으로써 수행됩니다. 루프가 어떻게 동일한 작업을 두 번 실행하지 않고 대신 생성 된 작업을 통해 나중에 트리거 할 수 있는지 확인합니다 (모든 작업 또는 레이크 명령 줄에서 작업 중 하나를 선택).