2010-06-12 10 views
6

Chcę, aby moje projekty Rakefile na najwyższym poziomie budowały rzeczy za pomocą plików rake głębiej w drzewie; tzn. plik rakefile najwyższego poziomu mówi, jak zbudować projekt (duży obraz), a te niższego poziomu budują konkretny moduł (obraz lokalny).Jak rekurencyjny grabie? - lub odpowiednie alternatywy

Jest oczywiście wspólny zestaw konfiguracji dla najdrobniejszych szczegółów tego, kiedy można go dzielić między zadania: dlatego chodzi głównie o zachowanie opisów tego, co jest potrzebne do budowy, tak blisko do budowanych źródeł. Na przykład. /Source/Module/code.foo i cie powinny być budowane zgodnie z instrukcjami w/Source/Module/Rakefile; i/Rakefile rozumie zależności między modułami.

Nie obchodzi mnie, czy używa wielu procesów rake (ala rekurencyjnych), czy po prostu tworzy osobne środowiska kompilacji. Tak czy inaczej, powinna być ona wystarczająco samodzielna, aby mogła być przetwarzana przez kolejkę: tak, aby niezależne moduły mogły być budowane jednocześnie.

Problem polega na tym, jak do cholery robisz coś takiego z Rake !? Nie mogłem znaleźć nic sensownego w Internecie ani w dokumentacji. Próbowałem utworzyć nowy obiekt Rake :: Application i skonfigurować go, ale niezależnie od tego, czy próbuję się wywoływać, próbuję wywoływać tylko wyjątki lub błędy "Nie wiem, jak zbudować zadanie": domyślne. (Tak, wszystkie pliki rake mają: wartość domyślną). Oczywiście można było po prostu wykonać "rake" w podkatalogu podrzędnym dla: modulename task, ale to zrzuciłoby opcje podane do najwyższego poziomu; na przykład myśl o $ (MAKE) i $ (MAKEFLAGS).

Ktoś ma wskazówkę, jak prawidłowo zrobić coś w rodzaju prowizji recursive?

Odpowiedz

2

możesz zgrabiać pliki z innych plików rake i uruchamiać zadania z wymaganego pliku.

umieścić to w rakefile.rb:

require 'foo/rakefile.rb' 

task :default => [:bar] 

umieścić to w foo/rakefile.rb:

task :bar do 
    puts "baz" 
end 

uruchomić Rakefile poziomu korzeń i będzie drukować "baz" na ekranie. powinieneś być w stanie porządkować swoje pliki rake i wspólny kod, ale chcesz użyć tego pomysłu.

0

Jeśli dobrze zrozumiałem, twój problem polega na tym, że musisz wywołać zadanie Rake w innym zadaniu Rake z innego RakeFile.

Możesz zbudować swoje potrzebne zadania w/Source/Module/Rakefile w sposób, w jaki jest to potrzebne i zrobić kolejny Rakefile in/Rakefile i wykonywać zadania w ten sposób.

desc 'Description' 
task :foo do 
    %x[rake -f /Source/Module/RakeFile foo:bar] 
end 

-f pozwala określić, gdzie znajduje się Rakefile

Można również określić, gdzie folder rakelib znajduje -R.

rake -f /path/to/Rakefile -R /path/to/rakelib foo:bar 

Mam nadzieję, że to ci pomoże.

+0

Wadą natarcia -f jest to, że nie określa katalog roboczy do lokalizacji powołuje Rakefile. –

0

Mam również podobny wymóg i stworzył następującą funkcję

rakeutils.RB:

def subdirs dirs 
    dirs.each do |d| 
     task d do |t| 
     sh("cd #{t.name} && pwd && rake") 
     end 
    end 
    task :default => dirs 
end 

aw Rakefiles, gdzie chcę mieć tej funkcji, po prostu umieścić go ... dla np

Rakefile:

require 'rakeutils' 

task :test1 do 
    puts "Hi" 
end 

task :default => :test1 
subdirs ["ab", "cd"] 

dotyczące opcji, nie znalazłem żadnego automatyczny sposób ich przekazywania ... inny niż edycja "rake" i przechwytywanie opcji zanim zostanie zużyty przez przetwarzanie opcji rake'a

+0

BTW, powyższy kod ma inne ograniczenie, że nie może rekursywnie wysuszyć pracy po podaniu "-n lub --dry-run". Jeśli naprawdę chcesz, aby rekursywnie suchy biegał z opcją przekazywania do rekurencyjnego rake, to zapoznaj się z moją drugą odpowiedzią: – siva008

2

Jak wspomniano we wcześniejszym poście, tutaj jest kod sn ippet, który obsługuje prawie jak rekurencyjne zachowanie rake, włączając w to przekazywanie opcji, dry-run, trace, zadanie najwyższego poziomu.

zgrabiarka:

#!/usr/bin/env ruby 

begin 
    require 'rubygems' 
    gem 'rake' 
rescue LoadError 
end 

$sub_directories = [] 
$top_level_task_provided__skip_subdir = 0 
module Rake 
    REDUCE_COMPAT = true if ARGV.include?("--reduce-compat") 
    RAKE_OPTS = ARGV.clone.join(" ") 
    module DSL 
    def subdirs dirs 
     puts "DIRS: #{dirs}" 
     $sub_directories = dirs 
    end 
    end 
end 

require 'rake' 

Rake.application.standard_exception_handling do 
    Rake.application.init 
    $top_level_task_provided__skip_subdir = 1 if Rake.application.top_level_tasks.size >= 1 and Rake.application.top_level_tasks[0] != "default" 
    Rake.application.load_rakefile 
    if Rake.application.tasks.size == 0 and $sub_directories.size != 0 then 
     desc "Default task when only subdirs is present in a rakefile" 
     task :default do 
     puts "Default subdir task" 
     end 
    end 
    Rake.application.top_level 
end 

if $top_level_task_provided__skip_subdir == 0 then 
    $sub_directories.each do |d| 
     unless rake_system("cd #{d} && pwd && ruby #{File.expand_path $0} #{Rake::RAKE_OPTS}") then 
      exit(1) 
     end 
    end 
end 
+0

Uwaga: ten skrypt jest testowany tylko z ruby2.0 i rake 0.9.6. Każda zmiana w wewnętrznych "rake" może złamać powyższy kod – siva008