Utilitky pro Ruby: distribuujeme skripty v Ruby

29. 8. 2007
Doba čtení: 4 minuty

Sdílet

Dnes se podíváme na distribuci skriptů v Ruby tak, aby pro jejich použití stačilo jediné kliknutí - nacpeme všechny naše kódy včetně knihoven a interpretu do jediného spustitelného souboru. Stačí jej poslat kamarádovi a může jej okamžitě používat, aniž by musel instalovat něco dalšího nebo splnit řadu komplikovaných závislostí.

Úvod

V jistých situacích se může hodit celý náš program distribuovat jako jeden spustitelný soubor. V Ruby to není problém, existuje sada tří navzájem podobných utilitek, které pokryjí převážnou většinu našich potřeb ohledně distribuce naší aplikace v jediném souboru.

Co se týče podporovaných platforem, na Linuxu problém mít nebudete, podporována jsou i okénka a Mac OS X.

Instalace

Na instalaci není nic složitého, všechny tři utilitky je možné nainstalovat přes balíčkovací systém RubyGems:

sudo gem install allinoneruby rubyscript2exe tar2rubyscript

Tar2RubyScript

Tato utilitka je určena těm, kteří Ruby již nainstalováno mají – jeho výstupem je totiž jediný skript v Ruby. Vzdáleně tak připomíná javovské JAR archivy. Použití je jednoduché, stačí zabalit soubory či složku s aplikací do archivu tar a ten posléze nechat zpracovat příkazem tar2rubyscript.

# vytvoříme tar archiv ze složky script,
# která obsahuje naši aplikaci:
tar cf script.tar script/
# archiv zpracujeme zpět na (jediný) skript v Ruby:
tar2rubyscript script.tar

init.rb

Soubor init.rb je oním spouštícím skriptem, který bude v cílovém skriptu volán. Musí být buď jedním ze souborů umístěných v archivu nebo musí být umístěn v kořenovém adresáři programu.

Protože skript obsahuje zakódovaný archiv, který jsme zadali utilitce tar2rubyscript jako parametr a protože tento archiv bude po spuštění souboru rozbalen do složky s dočasnými soubory, mohou vzniknout problémy s cestou. Stane se tak za předpokladu, že používáte relativní cesty vedoucí mimo kořenový adresář programu, jinými slovy knihovnu z podsložky lib/ můžete volat bez problémů, ale soubor umístěný v nadřazené složce už ne, resp. ne klasickým způsobem. Řešení skýtá escapování pomocí metody oldlocation:

input = oldlocation(ARGV[0])

Metodě oldlocation lze předat i blok kódu:

oldlocation do
  Dir.new(".").each {|file| kód ... }
end

A konečně je také možno se do staré složky přesunout:

Dir.chdir(oldlocation)

V tom případě je ale zas nutno escapovat soubory v nové lokaci a to pomocí newlocation, které funguje obdobným způsobem jako oldlocation.

Osobně mám dojem, že některé drobnosti by to chtělo ještě vyladit a protože systémem Rake se bude zabývat následující díl, aspoň vás trochu navnadím:

require "fileutils"

directory = Dir.pwd

task :default do
  Dir.chdir("..")
  sh("tar cf output.tar '#{File.basename(directory)}'")
  sh("tar2rubyscript output.tar")
  File.open("output.rb", "r") do |output|
    File.open("script.rb", "w") do |script|
      script.puts("#!/usr/bin/env ruby")
      script.puts(output.read)
    end
  end
  FileUtils.chmod(0755, "script.rb")
  FileUtils.remove(%w(output.tar output.rb), :force => true)
  FileUtils.move("script.rb", "hello/")
end

Tento kód uložte do souboru s názvem Rakefile v hlavní složce projektu a pak už pouze jednoduše zavolejte příkaz rake, výsledný soubor s názvem script.rb naleznete v aktuální složce a o víc se již starat nemusíte.

Parametry archivu

Našemu právě vzniklému archivu je možno pochopitelně předávat parametry, které budou klasicky dostupné v proměnné ARGV. Tři specifické parametry jsou však vyhrazeny k manipulaci se archivem:

Parametr Význam
--tar2rubyscript-list Vypíše obsažené soubory a složky.
--tar2rubyscript-justextract Extrahuje obsah skriptu, nespustí jej.
--tar2rubyscript-totar Převede skript zpět na tar archiv.

Výpis souborů:

hello $ ./script.rb --tar2rubyscript-list
d hello/
f hello/._.DS_Store (82)
f hello/.DS_Store (6148)
d hello/conf/
f hello/._init.rb (177)
f hello/init.rb (56)
f hello/._Rakefile (177)
f hello/Rakefile (487)

RubyScript2Exe

Tato utilitka vezme váš kód, interpret Ruby a veškeré knihovny, které potřebuje váš program k běhu a z toho všeho vytvoří jediný komprimovaný spustitelný soubor. Použití je prosté:

rubyscript2exe [aplikace] [parametry]
Parametr Význam
--rubyscript2exe-rubyw Použije binárku rubyw místo ruby, takže nebude vyskakovat okno s  cmd. Pochopitelně pouze na Windows, jinde se nijak neprojeví.
--rubyscript2exe-ruby Defaultní volba, okénko s  cmd se objeví při spuštění programu.
--rubyscript2exe-nostrip Nebude použito stripování.
--rubyscript2exe-verbose „Výřečný” mód.
--rubyscript2exe-quiet Tichý mód.

Tím bychom měli naši aplikaci zabalenou. To ale není všechno, speciální parametry lze předávat i jí samé:

bitcoin_skoleni

Parametr Význam
--eee-list Vylistuje obsah spustitelného souboru.
--eee-info Vypíše informace o programu.
--eee-justextract Extrahuje vnitřek spustitelného souboru.

AllInOneRuby

Prográmek AllInOneRuby není sice určen pro distribuci skriptů, ale s výše zmíněnými velmi úzce souvisí – jedná se pro změnu o utilitku, která je schopna vytvořit binárku Ruby, která již bude obsahovat všechny potřebné knihovny. Dovedu si docela dobře představit, že lidé, pro které život bez Ruby je jen ošklivou sérií nepříjemných a ještě nepříjemnějších dnů, mají svého miláčka vždy u sebe na USB pro všechny běžnější platformy a když je jim smutno, Ruby je vždy nablízku.

Funguje to jednoduše, stačí zavolat příkaz allinoneruby na cílové platformě a počkat, až se vytvoří spustitelný soubor.

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.