Komisyon görevleri, Komisyon görevleri içinden nasıl çalıştırılır?


411

Küresel değişkene göre, iki şekilde projeyi derler bir Rakefile var $build_typeolabilir, :debugya da :release(sonuçlar ayrı dizinlerde gidin):

task :build => [:some_other_tasks] do
end

Projeyi her iki yapılandırmayla da derleyen bir görev oluşturmak istiyorum, böyle bir şey:

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

Görevi bir yöntemmiş gibi çağırmanın bir yolu var mı? Ya da benzer bir şeyi nasıl başarabilirim?


7
hangisi cevap?
nurettin

Topluluk oyuyla giderdim ve 221 kez (yazı yazılırken) verilen cevabı seçerdim. Orijinal poster SO
MPritchard


FYI, yeni bir iş parçacığı oluşturmak ve yapmak zorunda olan Rails ortamını yüklemek zorunda olmadığı için Rake::Task["build"].invokekullanmaktan çok daha performanslı olabilir . system rake buildsystem rake build
Joshua Pinter

Yanıtlar:


639

Görevin bir yöntem olarak davranması gerekiyorsa, gerçek bir yöntem kullanmaya ne dersiniz?

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'İn deyimlerine bağlı kalmayı tercih ediyorsanız , geçmiş cevaplardan derlenmiş olasılıklarınız:

  • Bu her zaman görevi yürütür, ancak bağımlılıklarını yürütmez:

    Rake::Task["build"].execute
  • Bu bağımlılıkları yürütür, ancak görevi yalnızca çağrılmadıysa yürütür:

    Rake::Task["build"].invoke
  • Bu, önce görevin önceden çağrıldığı durumu sıfırlar ve görevin yeniden yürütülmesine, bağımlılıklara ve hepsine izin verir:

    Rake::Task["build"].reenable
    Rake::Task["build"].invoke
  • Önceden çağrılan bağımlılıkların, yeniden etkinleştirilmedikçe otomatik olarak yeniden yürütülmeyeceğini unutmayın. Komisyon> = 10.3.2'de, bunları yeniden etkinleştirmek için aşağıdakileri kullanabilirsiniz:

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

96
Görevleriniz ad alanlarındaysa, görevi çağırırken ad alanını eklemeniz gerektiğini unutmayın. Örneğin. Rake::Task['db:reset'].invoke
David Tuite

126
Sorulardaki görev bağımsız değişkenler alıyorsa, bunları #invoke öğesine bağımsız değişkenler olarak iletebilirsiniz. Örneğin. Rake::Task['with:args'].invoke("pizza")
Trotter

26
Bir ortam değişkeni ayarlamanız gerekiyorsa, invoke çağırmadan önce bunu yapın. Örneğin: ENV['VERSION'] = '20110408170816'; Rake::Task['db:migrate'].invokeDaha fazla açıklama için buraya bakın .
Michael Stalker

13
Son zamanlarda #reenable()ön-req'leri yeniden etkinleştirmediğini keşfettim ve ihtiyacım vardı. Komisyon'a (> = 10.3.2) yapılan bu ilave#all_prerequisite_tasks() , ön koşulların ön koşulları dahil olmak üzere tüm görevleri yineleyecektir. Yani,Rake::Task[task].all_prerequisite_tasks.each &:reenable
Richard Michael

4
@kch, bunları bir araya getirebilir misiniz ( rake db:reset db:migrateörneğin komut satırında olduğu gibi ). Gibi bir şey yapabilir misin: Rake::Task["db:reset", "db:migrate"].invoke
Jeff

125

Örneğin:

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

6
Bu, görevi yalnızca önceden çağrılmadıysa çağırır. Ama görevleri iki kez bağlı olan diğer tüm görevlerle çağırmam gerekiyor.

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

Bu seni halletmeli, sadece kendime aynı şeye ihtiyacım vardı.


Bu işlevsel, ama çok ayrıntılı. Daha iyi bir şey olmadığından emin misin?
kch

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

Bunun gibi bir çözüme ihtiyacımın nedenlerinden biri, tırmık görevi yüklemesinin çok zaman almasıdır. Yukarıdaki gibi bir çözüm uygulayarak yükleme süresinden tasarruf edecek mi?
Dipan Mehta

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

Çalışmaz, çünkü sadece şu yapının gövdesini yürütür: yapı görevi ve ona bağlı görevleri çağırmaz.

4

Her görevin herhangi bir başarısızlığa bakılmaksızın çalışmasını istiyorsanız, aşağıdakine benzer bir şey yapabilirsiniz:

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

Proje gerçekten derlenen ve böylece sonuç dosyaları bir şey ise genel hata ayıklama ve sürüm görevleri oluşturmamanızı öneririz. Belirttiğiniz gibi, çıktınızın farklı dizinlere gittiğini belirterek, örneğinizde oldukça yapılabilen dosya görevleri ile gitmelisiniz. Projenizin sadece bir test.c dosyasını out / debug / test.out ve out / release / test.out için derlediğini ve projenizi aşağıdaki gibi kurabileceğinizi varsayalım:

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]

Bu kurulum aşağıdaki gibi kullanılabilir:

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

Bu, istendiği gibi biraz daha fazlasını yapar, ancak puanlarımı gösterir:

  1. çıktı dizinleri gerektiği gibi oluşturulur.
  2. dosyalar yalnızca gerektiğinde yeniden derlenir (bu örnek yalnızca en basit test.c dosyaları için geçerlidir).
  3. yayın derlemesini veya hata ayıklama derlemesini tetiklemek istiyorsanız tüm görevleriniz hazırdır.
  4. bu örnek ayrıca hata ayıklama ve sürüm oluşturma arasındaki küçük farkları tanımlamanın bir yolunu içerir.
  5. Genel değişkenle parametreleştirilmiş bir yapı görevini yeniden etkinleştirmeye gerek yoktur, çünkü şimdi farklı yapıların farklı görevleri vardır. derleme görevinin codereuse'i derleme görevlerini tanımlamak için kodun yeniden kullanılmasıyla yapılır. döngünün aynı görevi iki kez nasıl yürütmediğini, bunun yerine daha sonra tetiklenebilecek olan görevleri (tüm görev tarafından ya da komisyon komut satırından birini seçerek) görün.
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.