about summary refs log tree commit diff
path: root/doc/languages-frameworks/ruby.xml
blob: df4e5acb22cb94892a5f0dd06c5e7be8b27d170e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
<section xmlns="http://docbook.org/ns/docbook"
         xmlns:xlink="http://www.w3.org/1999/xlink"
         xml:id="sec-language-ruby">
 <title>Ruby</title>

 <para>
  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.
 </para>

 <para>
  For example, to package sensu, we did:
 </para>

<screen>
<![CDATA[$ cd pkgs/servers/monitoring
$ mkdir sensu
$ cd sensu
$ cat > Gemfile
source 'https://rubygems.org'
gem 'sensu'
$ $(nix-build '<nixpkgs>' -A bundix --no-out-link)/bin/bundix --magic
$ cat > default.nix
{ lib, bundlerEnv, ruby }:

bundlerEnv rec {
  name = "sensu-${version}";

  version = (import gemset).sensu.version;
  inherit ruby;
  # expects Gemfile, Gemfile.lock and gemset.nix in the same directory
  gemdir = ./.;

  meta = with lib; {
    description = "A monitoring framework that aims to be simple, malleable, and scalable";
    homepage    = http://sensuapp.org/;
    license     = with licenses; mit;
    maintainers = with maintainers; [ theuni ];
    platforms   = platforms.unix;
  };
}]]>
</screen>

 <para>
  Please check in the <filename>Gemfile</filename>,
  <filename>Gemfile.lock</filename> and the <filename>gemset.nix</filename> so
  future updates can be run easily.
 </para>

 <para>
  Updating Ruby packages can then be done like this:
 </para>

<screen>
<![CDATA[$ cd pkgs/servers/monitoring/sensu
$ nix-shell -p bundler --run 'bundle lock --update'
$ nix-shell -p bundix --run 'bundix'
]]>
</screen>

 <para>
  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:
 </para>

<screen>
<![CDATA[{ lib, bundlerApp }:

bundlerApp {
  pname = "corundum";
  gemdir = ./.;
  exes = [ "corundum-skel" ];

  meta = with lib; {
    description = "Tool and libraries for maintaining Ruby gems.";
    homepage    = https://github.com/nyarly/corundum;
    license     = licenses.mit;
    maintainers = [ maintainers.nyarly ];
    platforms   = platforms.unix;
  };
}]]>
</screen>

 <para>
  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.
 </para>

 <para>
  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:
 </para>

<programlisting>
<![CDATA[let env = bundlerEnv {
  name = "my-script-env";

  inherit ruby;
  gemfile = ./Gemfile;
  lockfile = ./Gemfile.lock;
  gemset = ./gemset.nix;
};

in stdenv.mkDerivation {
  name = "my-script";
  buildInputs = [ env.wrappedRuby ];
  script = ./my-script.rb;
  buildCommand = ''
    install -D -m755 $script $out/bin/my-script
    patchShebangs $out/bin/my-script
  '';
}]]>
</programlisting>
</section>