Clone of https://github.com/NixOS/nixpkgs.git (to stress-test knotserver)
at 19.09 158 lines 4.2 kB view raw
1{ stdenv, runCommand, ruby, lib 2, defaultGemConfig, buildRubyGem, buildEnv 3, makeWrapper 4, bundler 5}@defs: 6 7{ 8 name ? null 9, pname ? null 10, mainGemName ? null 11, gemdir ? null 12, gemfile ? null 13, lockfile ? null 14, gemset ? null 15, ruby ? defs.ruby 16, gemConfig ? defaultGemConfig 17, postBuild ? null 18, document ? [] 19, meta ? {} 20, groups ? null 21, ignoreCollisions ? false 22, buildInputs ? [] 23, ... 24}@args: 25 26assert name == null -> pname != null; 27 28with import ./functions.nix { inherit lib gemConfig; }; 29 30let 31 gemFiles = bundlerFiles args; 32 33 importedGemset = if builtins.typeOf gemFiles.gemset != "set" 34 then import gemFiles.gemset 35 else gemFiles.gemset; 36 37 filteredGemset = filterGemset { inherit ruby groups; } importedGemset; 38 39 configuredGemset = lib.flip lib.mapAttrs filteredGemset (name: attrs: 40 applyGemConfigs (attrs // { inherit ruby; gemName = name; }) 41 ); 42 43 hasBundler = builtins.hasAttr "bundler" filteredGemset; 44 45 bundler = 46 if hasBundler then gems.bundler 47 else defs.bundler.override (attrs: { inherit ruby; }); 48 49 gems = lib.flip lib.mapAttrs configuredGemset (name: attrs: buildGem name attrs); 50 51 name' = if name != null then 52 name 53 else 54 let 55 gem = gems.${pname}; 56 version = gem.version; 57 in 58 "${pname}-${version}"; 59 60 pname' = if pname != null then 61 pname 62 else 63 name; 64 65 copyIfBundledByPath = { bundledByPath ? false, ...}: 66 (if bundledByPath then 67 assert gemFiles.gemdir != null; "cp -a ${gemFiles.gemdir}/* $out/" #*/ 68 else "" 69 ); 70 71 maybeCopyAll = pkgname: if pkgname == null then "" else 72 let 73 mainGem = gems.${pkgname} or (throw "bundlerEnv: gem ${pkgname} not found"); 74 in 75 copyIfBundledByPath mainGem; 76 77 # We have to normalize the Gemfile.lock, otherwise bundler tries to be 78 # helpful by doing so at run time, causing executables to immediately bail 79 # out. Yes, I'm serious. 80 confFiles = runCommand "gemfile-and-lockfile" {} '' 81 mkdir -p $out 82 ${maybeCopyAll mainGemName} 83 cp ${gemFiles.gemfile} $out/Gemfile || ls -l $out/Gemfile 84 cp ${gemFiles.lockfile} $out/Gemfile.lock || ls -l $out/Gemfile.lock 85 ''; 86 87 buildGem = name: attrs: ( 88 let 89 gemAttrs = composeGemAttrs ruby gems name attrs; 90 in 91 if gemAttrs.type == "path" then 92 pathDerivation (gemAttrs.source // gemAttrs) 93 else 94 buildRubyGem gemAttrs 95 ); 96 97 envPaths = lib.attrValues gems ++ lib.optional (!hasBundler) bundler; 98 99 basicEnv = buildEnv { 100 inherit buildInputs ignoreCollisions; 101 102 name = name'; 103 104 paths = envPaths; 105 pathsToLink = [ "/lib" ]; 106 107 postBuild = genStubsScript (defs // args // { 108 inherit confFiles bundler groups; 109 binPaths = envPaths; 110 }) + lib.optionalString (postBuild != null) postBuild; 111 112 meta = { platforms = ruby.meta.platforms; } // meta; 113 114 passthru = rec { 115 inherit ruby bundler gems confFiles envPaths; 116 117 wrappedRuby = stdenv.mkDerivation { 118 name = "wrapped-ruby-${pname'}"; 119 nativeBuildInputs = [ makeWrapper ]; 120 buildCommand = '' 121 mkdir -p $out/bin 122 for i in ${ruby}/bin/*; do 123 makeWrapper "$i" $out/bin/$(basename "$i") \ 124 --set BUNDLE_GEMFILE ${confFiles}/Gemfile \ 125 --set BUNDLE_PATH ${basicEnv}/${ruby.gemPath} \ 126 --set BUNDLE_FROZEN 1 \ 127 --set GEM_HOME ${basicEnv}/${ruby.gemPath} \ 128 --set GEM_PATH ${basicEnv}/${ruby.gemPath} 129 done 130 ''; 131 }; 132 133 env = let 134 irbrc = builtins.toFile "irbrc" '' 135 if !(ENV["OLD_IRBRC"].nil? || ENV["OLD_IRBRC"].empty?) 136 require ENV["OLD_IRBRC"] 137 end 138 require 'rubygems' 139 require 'bundler/setup' 140 ''; 141 in stdenv.mkDerivation { 142 name = "${pname'}-interactive-environment"; 143 nativeBuildInputs = [ wrappedRuby basicEnv ]; 144 shellHook = '' 145 export OLD_IRBRC=$IRBRC 146 export IRBRC=${irbrc} 147 ''; 148 buildCommand = '' 149 echo >&2 "" 150 echo >&2 "*** Ruby 'env' attributes are intended for interactive nix-shell sessions, not for building! ***" 151 echo >&2 "" 152 exit 1 153 ''; 154 }; 155 }; 156 }; 157in 158 basicEnv