at v206 3.6 kB view raw
1{ lib, ruby, rubygemsFun, fetchurl, makeWrapper, git } @ defs: 2 3lib.makeOverridable ( 4 5{ name 6, ruby ? defs.ruby 7, rubygems ? (rubygemsFun ruby) 8, stdenv ? ruby.stdenv 9, namePrefix ? "${ruby.name}" + "-" 10, buildInputs ? [] 11, doCheck ? false 12, dontBuild ? true 13, meta ? {} 14, gemPath ? [] 15, ...} @ attrs: 16 17stdenv.mkDerivation (attrs // { 18 inherit ruby rubygems; 19 inherit doCheck; 20 21 buildInputs = [ ruby rubygems makeWrapper git ] ++ buildInputs; 22 23 name = namePrefix + name; 24 25 src = if attrs ? src 26 then attrs.src 27 else fetchurl { 28 url = "http://rubygems.org/downloads/${attrs.name}.gem"; 29 inherit (attrs) sha256; 30 }; 31 32 phases = [ "unpackPhase" "patchPhase" "buildPhase" "checkPhase" "installPhase" "fixupPhase" ]; 33 34 # The source is expected to either be a gem package or a directory. 35 # 36 # - Gem packages are already built, so they don't even need to be unpacked. 37 # They will skip the buildPhase. 38 # - A directory containing the sources will need to go through all of the 39 # usual phases. 40 unpackPhase= '' 41 gemRegex="\.gem" 42 if [[ $src =~ $gemRegex ]] 43 then 44 runHook preUnpack 45 echo "source is a gem package, won't unpack" 46 gempkg=$src 47 dontBuild=1 48 runHook postUnpack 49 else 50 # Fall back to the original thing for everything else. 51 unpackPhase 52 fi 53 ''; 54 55 checkPhase = "true"; 56 57 buildPhase = '' 58 runHook preBuild 59 60 # TODO: Investigate. The complete working tree is touched by fetchgit. 61 if [ -d .git ]; then 62 git reset 63 fi 64 65 gemspec=$(find . -name '*.gemspec') 66 echo "found the following gemspecs:" 67 echo "$gemspec" 68 69 gemspec=$(echo "$gemspec" | head -n1) 70 echo "building $gemspec" 71 72 exec 3>&1 73 output=$(gem build $gemspec | tee >(cat - >&3)) 74 exec 3>&- 75 76 gempkg=$(echo "$output" | grep -oP 'File: \K(.*)') 77 78 echo "gem package built: $gempkg" 79 80 runHook postBuild 81 ''; 82 83 installPhase = '' 84 runHook preInstall 85 86 # NOTE: This does NOT build the unpacked gem, but installs $src directly. 87 # Gems that have not been downloaded from rubygems.org may need a 88 # separate buildPhase. 89 # --ignore-dependencies is necessary as rubygems otherwise always 90 # connects to the repository, thus breaking pure builds. 91 GEM_HOME=$out/${ruby.gemPath} \ 92 gem install \ 93 --local \ 94 --force \ 95 --http-proxy "http://nodtd.invalid" \ 96 --ignore-dependencies \ 97 --build-root "/" \ 98 --backtrace \ 99 $gempkg $gemFlags -- $buildFlags 100 101 # Yes, we really do need the $out/${ruby.gemPath}/cache. 102 # This is very important in order for many parts of RubyGems/Bundler to not blow up. 103 # See https://github.com/bundler/bundler/issues/3327 104 105 mkdir -p $out/bin 106 for prog in $out/${ruby.gemPath}/gems/*/bin/*; do 107 makeWrapper $prog $out/bin/$(basename $prog) \ 108 --prefix GEM_PATH : "$out/${ruby.gemPath}:$GEM_PATH" \ 109 --prefix RUBYLIB : "${rubygems}/lib" \ 110 $extraWrapperFlags ''${extraWrapperFlagsArray[@]} 111 done 112 #--prefix RUBYOPT rubygems \ 113 114 # looks like useless files which break build repeatability and consume space 115 rm -fv $out/${ruby.gemPath}/doc/*/*/created.rid || true 116 rm -fv $out/${ruby.gemPath}/gems/*/ext/*/mkmf.log || true 117 118 mkdir -p $out/nix-support 119 120 cat > $out/nix-support/setup-hook <<EOF 121 if [[ "\$GEM_PATH" != *$out* ]]; then 122 addToSearchPath GEM_PATH $out/${ruby.gemPath} 123 fi 124 EOF 125 126 runHook postInstall 127 ''; 128 129 propagatedBuildInputs = gemPath; 130 propagatedUserEnvPkgs = gemPath; 131 132 passthru.isRubyGem = true; 133 inherit meta; 134}) 135 136)