Rake 작업 내에서 Rake 작업을 실행하는 방법은 무엇입니까?


411

전역 변수에 따라 두 가지 방법으로 프로젝트를 컴파일하는 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

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


7
어느 것이 답입니까?
nurettin

나는 커뮤니티 투표와 함께 221 번 (서면 시점에) 찬성 된 답변을 선택했습니다. 오리지널 포스터는 이렇게 떠났습니다
MPritchard


참고로, 새로운 스레드를 만들고 Rails 환경을로드 할 필요가 없기 때문에 같은 것을 사용하는 것이 사용하는 것 Rake::Task["build"].invoke보다 훨씬 더 성능이 좋을 수 있습니다 . system rake buildsystem rake build
Joshua Pinter

답변:


639

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

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)

96
작업이 네임 스페이스에있는 경우 작업을 호출 할 때 네임 스페이스를 포함해야합니다. 예 : Rake::Task['db:reset'].invoke
David Tuite

126
문제가되는 작업이 인수를 취하면 인수를 #invoke에 인수로 전달할 수 있습니다. 예 : Rake::Task['with:args'].invoke("pizza")
Trotter

26
환경 변수를 설정해야하는 경우 invoke를 호출하기 전에 설정하십시오. 예를 들어 : ENV['VERSION'] = '20110408170816'; Rake::Task['db:migrate'].invoke자세한 내용은 여기 를 참조 하십시오 .
마이클 스토커

13
최근에 #reenable()사전 요구 사항을 다시 활성화하지 못하고 필요하다는 것을 알았 습니다. 레이크 (> = 10.3.2)에 추가 하면 #all_prerequisite_tasks()사전 요구 사항의 사전 요구 사항을 포함한 모든 작업이 반복됩니다. 그래서Rake::Task[task].all_prerequisite_tasks.each &:reenable
Richard Michael

4
@kch, rake db:reset db:migrate예를 들어 명령 줄과 같이 이들을 함께 묶을 수 있습니까 ? 다음과 같은 작업을 수행 할 수 있습니까 : Rake::Task["db:reset", "db:migrate"].invoke
Jeff

125

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

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

6
이 작업은 아직 호출되지 않은 경우에만 작업을 호출합니다. 그러나 두 번 의존하는 다른 모든 작업으로 작업을 호출해야합니다.

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

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


이것은 기능적이지만 너무 장황합니다. 더 좋은게 없나요?
kch

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

이와 같은 솔루션이 필요한 이유 중 하나는 레이크 작업로드에 많은 시간이 걸리기 때문입니다. 위와 같은 솔루션을 구현하면 로딩 시간이 절약됩니까?
Dipan Mehta

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

그것은 : build 작업의 본문을 실행하고 그것에 의존하는 작업을 호출하지 않기 때문에 작동하지 않습니다.

4

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

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

-1

프로젝트가 실제로 컴파일되어 파일로 생성되는 경우 일반 디버그 및 릴리스 작업을 작성하지 않는 것이 좋습니다. 예를 들어 출력이 다른 디렉토리로 이동한다는 것을 알 수있는 파일 작업을 수행해야합니다. 프로젝트가 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. 이제는 빌드마다 다른 태스크가 있으므로 전역 변수로 매개 변수화 된 빌드 태스크를 다시 활성화 할 필요가 없습니다. 빌드 작업의 코드 재사용은 코드를 재사용하여 빌드 작업을 정의함으로써 수행됩니다. 루프가 어떻게 동일한 작업을 두 번 실행하지 않고 대신 생성 된 작업을 통해 나중에 트리거 할 수 있는지 확인합니다 (모든 작업 또는 레이크 명령 줄에서 작업 중 하나를 선택).
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.