Clone of https://github.com/NixOS/nixpkgs.git (to stress-test knotserver)
at 20.09 107 lines 4.4 kB view raw
1<section xmlns="http://docbook.org/ns/docbook" 2 xmlns:xlink="http://www.w3.org/1999/xlink" 3 xml:id="sec-language-ruby"> 4 <title>Ruby</title> 5 6 <para> 7 There currently is support to bundle applications that are packaged as Ruby gems. The utility "bundix" allows you to write a <filename>Gemfile</filename>, let bundler create a <filename>Gemfile.lock</filename>, and then convert this into a nix expression that contains all Gem dependencies automatically. 8 </para> 9 10 <para> 11 For example, to package sensu, we did: 12 </para> 13 14<screen> 15<prompt>$ </prompt>cd pkgs/servers/monitoring 16<prompt>$ </prompt>mkdir sensu 17<prompt>$ </prompt>cd sensu 18<prompt>$ </prompt>cat > Gemfile 19source 'https://rubygems.org' 20gem 'sensu' 21<prompt>$ </prompt>$(nix-build '&lt;nixpkgs>' -A bundix --no-out-link)/bin/bundix --magic 22<prompt>$ </prompt>cat > default.nix 23{ lib, bundlerEnv, ruby }: 24 25bundlerEnv rec { 26 name = "sensu-${version}"; 27 28 version = (import gemset).sensu.version; 29 inherit ruby; 30 # expects Gemfile, Gemfile.lock and gemset.nix in the same directory 31 gemdir = ./.; 32 33 meta = with lib; { 34 description = "A monitoring framework that aims to be simple, malleable, and scalable"; 35 homepage = "http://sensuapp.org/"; 36 license = with licenses; mit; 37 maintainers = with maintainers; [ theuni ]; 38 platforms = platforms.unix; 39 }; 40} 41</screen> 42 43 <para> 44 Please check in the <filename>Gemfile</filename>, <filename>Gemfile.lock</filename> and the <filename>gemset.nix</filename> so future updates can be run easily. 45 </para> 46 47 <para> 48 Updating Ruby packages can then be done like this: 49 </para> 50 51<screen> 52<prompt>$ </prompt>cd pkgs/servers/monitoring/sensu 53<prompt>$ </prompt>nix-shell -p bundler --run 'bundle lock --update' 54<prompt>$ </prompt>nix-shell -p bundix --run 'bundix' 55</screen> 56 57 <para> 58 For tools written in Ruby - i.e. where the desire is to install a package and then execute e.g. <command>rake</command> at the command line, there is an alternative builder called <literal>bundlerApp</literal>. Set up the <filename>gemset.nix</filename> the same way, and then, for example: 59 </para> 60 61<programlisting> 62<![CDATA[{ lib, bundlerApp }: 63 64bundlerApp { 65 pname = "corundum"; 66 gemdir = ./.; 67 exes = [ "corundum-skel" ]; 68 69 meta = with lib; { 70 description = "Tool and libraries for maintaining Ruby gems."; 71 homepage = "https://github.com/nyarly/corundum"; 72 license = licenses.mit; 73 maintainers = [ maintainers.nyarly ]; 74 platforms = platforms.unix; 75 }; 76}]]> 77</programlisting> 78 79 <para> 80 The chief advantage of <literal>bundlerApp</literal> over <literal>bundlerEnv</literal> is the executables introduced in the environment are precisely those selected in the <literal>exes</literal> list, as opposed to <literal>bundlerEnv</literal> which adds all the executables made available by gems in the gemset, which can mean e.g. <command>rspec</command> or <command>rake</command> in unpredictable versions available from various packages. 81 </para> 82 83 <para> 84 Resulting derivations for both builders also have two helpful attributes, <literal>env</literal> and <literal>wrappedRuby</literal>. The first one allows one to quickly drop into <command>nix-shell</command> with the specified environment present. E.g. <command>nix-shell -A sensu.env</command> would give you an environment with Ruby preset so it has all the libraries necessary for <literal>sensu</literal> in its paths. The second one can be used to make derivations from custom Ruby scripts which have <filename>Gemfile</filename>s with their dependencies specified. It is a derivation with <command>ruby</command> wrapped so it can find all the needed dependencies. For example, to make a derivation <literal>my-script</literal> for a <filename>my-script.rb</filename> (which should be placed in <filename>bin</filename>) you should run <command>bundix</command> as specified above and then use <literal>bundlerEnv</literal> like this: 85 </para> 86 87<programlisting> 88<![CDATA[let env = bundlerEnv { 89 name = "my-script-env"; 90 91 inherit ruby; 92 gemfile = ./Gemfile; 93 lockfile = ./Gemfile.lock; 94 gemset = ./gemset.nix; 95}; 96 97in stdenv.mkDerivation { 98 name = "my-script"; 99 buildInputs = [ env.wrappedRuby ]; 100 script = ./my-script.rb; 101 buildCommand = '' 102 install -D -m755 $script $out/bin/my-script 103 patchShebangs $out/bin/my-script 104 ''; 105}]]> 106</programlisting> 107</section>