Utilitky pro Ruby: buildovací systém Rake III

17. 9. 2007
Doba čtení: 3 minuty

Sdílet

Ilustrační obrázek
Autor: Depositphotos – stori
Ilustrační obrázek
Metoda task není zdaleka jedinou možností tvorby úkolů. Řeč bude jak o tascích umožňující spouštět úlohy paralelně, tak o tascích souborových, které se používají například pro rozdílové kompilace. Povíme si něco i o pravidlech, která definují akce pro více souborů zároveň.

Paralelní tasky

Jistě si vybavíte bezpočet případů, kdy by se hodilo spouštět některé úkoly paralelně. V Rake to je snadné – stačí použít metodu multitask:

multitask :backup_all => [:backup_src, :backup_doc, :backup_bin]

Tím bude :backup_src, :backup_doc a :backup_bin spuštěno současně, tedy každé ve svém threadu. Stejně jako metodě task, i metodě multitask lze předat blok kódu, požadováno to však není.

Souborové tasky

Souborové tasky jsou tasky směřující k vygenerování určitého souboru. K jejich konstrukci slouží metoda file, které jako první parametr předáme jméno souboru, který chceme získat na výstupu. Pokud tento soubor již existuje, Rake to zjistí a task nebude vykonán:

file "index.html" do
  touch "index.html"
  STDERR.puts("Your index.html is ready!")
end
rubybook> rake index.html
(in /Users/botanicus/Documents/Publications/RubyBook)
Your index.html is ready!
rubybook> rake index.html
(in /Users/botanicus/Documents/Publications/RubyBook)
rubybook>

Souborové tasky mohou záviset na dalších souborech. Podmínka pro vykonání tasku je pak rozšířena o klauzuli „task bude proveden, pokud výstupní soubor ještě neexistuje, a nebo jsou soubory uvedené v závislostech mladšího data než soubor výstupní”:

content = FileList["#{document}.tex", "chapters.tex", "chapters/**/*.tex"]

desc "Typeset the #{document}.pdf."
file "#{document}.pdf" => content do
  sh("texexec #{document}")
end

Zde je možná na místě udělat drobnou odbočku k metodě uptodate? z FileUtils, která nám může povědět, zda je soubor novější než ostatní dotazované soubory, která lze metodě předat například jako pole. Výše uvedený úkol bychom „klasickou” cestou přes metodu task implementovali takto:

content = FileList["#{document}.tex", "chapters.tex", "chapters/**/*.tex"]

desc "Typeset the #{document}.pdf."
task :build do
  sh("texexec #{document}") unless uptodate?("#{document}.pdf", content)
end

Osobně považuji alternativu s file  za rozumnější, čitelnější a čistší, ale metodu uptodate? je rozhodně vhodné znát, poměrně často se (nejen) v Rake hodí.

Asi vás zarazilo, že volám přímo uptodate? a nikoliv FileUtils.uptodate? s předcházejícím požadavkem na nahrání FileUtils. Je tomu tak proto, že FileUtils již nahrané jsou ( require) a navíc jsou inkludovány do namespace Objectu ( include). Rake na FileUtils hodně staví a samo si je i rozšiřuje. O úpravách FileUtils v Rake bude řeč v příštím díle.

V některých případech by bylo zbytečné tvořit souborový task pro každý ze souborů. Od toho slouží pravidla, která jsou konstruována metodou rule:

rule '.o' => ['.c'] do |task|
  sh %{cc #{task.source} -c -o #{task.name}}
end

Jak jste jistě pochopili, task.source vrací jméno zdrojového souboru, kdežto task.name zase jméno tasku, které je v našem případě shodné s jménem výstupního souboru.

Metodě rule lze krom přípony předat i například celý regulární výraz. Možnosti pravidel jsou velmi komplexní, zájemce tedy odkazuji na dokumentaci.

TOP100

Vzhledem k tomu, že v Rake máte k dispozici komplexní možnosti jazyka Ruby, je také možné tvořit tasky v průchodu cyklem each. To může být často velmi užitečné. Například metodu rule bychom mohli pro náš výše uvedený příklad stejně dobře zastoupit procházením všech souborů s příponou .o, tvorbou souborového tasku z jeho jména a jeho kompilaci z jemu příslušejícímu zdrojovému souboru. Ačkoliv tento konkrétní případ řeší přímočařejší cestou metoda rule, jsou případy, kdy řešení s each  oceníme.

Příště

Protože jsme se dnes proti očekávání již nedostali na velmi užitečnou třídu FileList, věnovat se jí budeme příště. Povíme si také pár slov o knihovně FileUtils, která je jednak pro použití v Rake  velmi užitečná, ale hlavně si ji Rake rozšiřuje, takže FileUtils v Rakefile  umí více než běžné FileUtils.

Odkazy

Autor článku

Jakub Šťastný byl v letech 2007 až 2008 redaktorem serveru Root.cz. Mezi jeho zájmy patří Linux, programování a typografický systém TeX.


Nejnovější články