You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

108 lines
4.3 KiB

  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. <para>
  6. 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.
  7. </para>
  8. <para>
  9. For example, to package sensu, we did:
  10. </para>
  11. <screen>
  12. <prompt>$ </prompt>cd pkgs/servers/monitoring
  13. <prompt>$ </prompt>mkdir sensu
  14. <prompt>$ </prompt>cd sensu
  15. <prompt>$ </prompt>cat > Gemfile
  16. source 'https://rubygems.org'
  17. gem 'sensu'
  18. <prompt>$ </prompt>$(nix-build '&lt;nixpkgs>' -A bundix --no-out-link)/bin/bundix --magic
  19. <prompt>$ </prompt>cat > default.nix
  20. { lib, bundlerEnv, ruby }:
  21. bundlerEnv rec {
  22. name = "sensu-${version}";
  23. version = (import gemset).sensu.version;
  24. inherit ruby;
  25. # expects Gemfile, Gemfile.lock and gemset.nix in the same directory
  26. gemdir = ./.;
  27. meta = with lib; {
  28. description = "A monitoring framework that aims to be simple, malleable, and scalable";
  29. homepage = "http://sensuapp.org/";
  30. license = with licenses; mit;
  31. maintainers = with maintainers; [ theuni ];
  32. platforms = platforms.unix;
  33. };
  34. }
  35. </screen>
  36. <para>
  37. Please check in the <filename>Gemfile</filename>, <filename>Gemfile.lock</filename> and the <filename>gemset.nix</filename> so future updates can be run easily.
  38. </para>
  39. <para>
  40. Updating Ruby packages can then be done like this:
  41. </para>
  42. <screen>
  43. <prompt>$ </prompt>cd pkgs/servers/monitoring/sensu
  44. <prompt>$ </prompt>nix-shell -p bundler --run 'bundle lock --update'
  45. <prompt>$ </prompt>nix-shell -p bundix --run 'bundix'
  46. </screen>
  47. <para>
  48. 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:
  49. </para>
  50. <programlisting>
  51. <![CDATA[{ lib, bundlerApp }:
  52. bundlerApp {
  53. pname = "corundum";
  54. gemdir = ./.;
  55. exes = [ "corundum-skel" ];
  56. meta = with lib; {
  57. description = "Tool and libraries for maintaining Ruby gems.";
  58. homepage = "https://github.com/nyarly/corundum";
  59. license = licenses.mit;
  60. maintainers = [ maintainers.nyarly ];
  61. platforms = platforms.unix;
  62. };
  63. }]]>
  64. </programlisting>
  65. <para>
  66. 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.
  67. </para>
  68. <para>
  69. 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:
  70. </para>
  71. <programlisting>
  72. <![CDATA[let env = bundlerEnv {
  73. name = "my-script-env";
  74. inherit ruby;
  75. gemfile = ./Gemfile;
  76. lockfile = ./Gemfile.lock;
  77. gemset = ./gemset.nix;
  78. };
  79. in stdenv.mkDerivation {
  80. name = "my-script";
  81. buildInputs = [ env.wrappedRuby ];
  82. script = ./my-script.rb;
  83. buildCommand = ''
  84. install -D -m755 $script $out/bin/my-script
  85. patchShebangs $out/bin/my-script
  86. '';
  87. }]]>
  88. </programlisting>
  89. </section>