1{
2 lib,
3 callPackage,
4 runCommand,
5 makeWrapper,
6 ruby,
7}@defs:
8
9# Use for simple installation of Ruby tools shipped in a Gem.
10# Start with a Gemfile that includes `gem <toolgem>`
11# > nix-shell -p bundler bundix
12# (shell)> bundle lock
13# (shell)> bundix
14# Then use rubyTool in the default.nix:
15
16# rubyTool { pname = "gemifiedTool"; gemdir = ./.; exes = ["gemified-tool"]; }
17# The 'exes' parameter ensures that a copy of e.g. rake doesn't pollute the system.
18{
19 # use the name of the name in question; its version will be picked up from the gemset
20 pname,
21 # Gemdir is the location of the Gemfile{,.lock} and gemset.nix; usually ./.
22 # This is required unless gemfile, lockfile, and gemset are all provided
23 gemdir ? null,
24 # Exes is the list of executables provided by the gems in the Gemfile
25 exes ? [ ],
26 # Scripts are ruby programs depend on gems in the Gemfile (e.g. scripts/rails)
27 scripts ? [ ],
28 ruby ? defs.ruby,
29 gemfile ? null,
30 lockfile ? null,
31 gemset ? null,
32 preferLocalBuild ? false,
33 allowSubstitutes ? false,
34 installManpages ? true,
35 meta ? { },
36 nativeBuildInputs ? [ ],
37 buildInputs ? [ ],
38 postBuild ? "",
39 gemConfig ? null,
40 passthru ? { },
41}@args:
42
43let
44 basicEnv =
45 (callPackage ../bundled-common {
46 inherit ruby;
47 })
48 args;
49
50 cmdArgs =
51 removeAttrs args [
52 "postBuild"
53 "gemConfig"
54 "passthru"
55 "gemset"
56 "gemdir"
57 ]
58 // {
59 inherit preferLocalBuild allowSubstitutes; # pass the defaults
60 inherit (basicEnv) version;
61
62 nativeBuildInputs = nativeBuildInputs ++ lib.optionals (scripts != [ ]) [ makeWrapper ];
63
64 meta = {
65 mainProgram = pname;
66 inherit (ruby.meta) platforms;
67 }
68 // meta;
69 passthru =
70 basicEnv.passthru
71 // {
72 inherit basicEnv;
73 inherit (basicEnv) env;
74 }
75 // passthru;
76 };
77in
78runCommand basicEnv.name cmdArgs ''
79 mkdir -p $out/bin
80 ${(lib.concatMapStrings (x: "ln -s '${basicEnv}/bin/${x}' $out/bin/${x};\n") exes)}
81 ${
82 (lib.concatMapStrings (
83 s:
84 "makeWrapper $out/bin/$(basename ${s}) $srcdir/${s} "
85 + "--set BUNDLE_GEMFILE ${basicEnv.confFiles}/Gemfile "
86 + "--unset BUNDLE_PATH "
87 + "--set BUNDLE_FROZEN 1 "
88 + "--set GEM_HOME ${basicEnv}/${ruby.gemPath} "
89 + "--set GEM_PATH ${basicEnv}/${ruby.gemPath} "
90 + "--chdir \"$srcdir\";\n"
91 ) scripts)
92 }
93
94 ${lib.optionalString installManpages ''
95 for section in {1..9}; do
96 mandir="$out/share/man/man$section"
97
98 # See: https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/ruby-modules/gem/default.nix#L184-L200
99 # See: https://github.com/rubygems/rubygems/blob/7a7b234721c375874b7e22b1c5b14925b943f04e/bundler/lib/bundler.rb#L285-L291
100 find -L ${basicEnv}/${ruby.gemPath}/${
101 lib.optionalString (basicEnv.gemType == "git" || basicEnv.gemType == "url") "bundler/"
102 }gems/${basicEnv.name} \( -wholename "*/man/*.$section" -o -wholename "*/man/man$section/*.$section" \) -print -execdir mkdir -p $mandir \; -execdir cp '{}' $mandir \;
103 done
104 ''}
105''