diff --git a/pkgs/development/ruby-modules/gem/default.nix b/pkgs/development/ruby-modules/gem/default.nix index eba0dc2c4a7c..5bde59eab04d 100644 --- a/pkgs/development/ruby-modules/gem/default.nix +++ b/pkgs/development/ruby-modules/gem/default.nix @@ -65,6 +65,8 @@ let inherit (attrs.source) url rev sha256 fetchSubmodules; leaveDotGit = true; } + else if type == "url" then + fetchurl attrs.source else throw "buildRubyGem: don't know how to build a gem of type \"${type}\"" ); @@ -84,7 +86,8 @@ stdenv.mkDerivation ((builtins.removeAttrs attrs ["source"]) // { buildInputs = [ ruby makeWrapper - ] ++ lib.optionals (type == "git") [ git bundler ] + ] ++ lib.optionals (type == "git") [ git ] + ++ lib.optionals (type != "gem") [ bundler ] ++ lib.optional stdenv.isDarwin darwin.libobjc ++ buildInputs; @@ -159,14 +162,22 @@ stdenv.mkDerivation ((builtins.removeAttrs attrs ["source"]) // { echo "buildFlags: $buildFlags" + ${lib.optionalString (type == "url") '' + ruby ${./nix-bundle-install.rb} \ + "path" \ + '${gemName}' \ + '${version}' \ + '${lib.escapeShellArgs buildFlags}' + ''} ${lib.optionalString (type == "git") '' ruby ${./nix-bundle-install.rb} \ - ${gemName} \ - ${attrs.source.url} \ - ${src} \ - ${attrs.source.rev} \ - ${version} \ - ${lib.escapeShellArgs buildFlags} + "git" \ + '${gemName}' \ + '${version}' \ + '${lib.escapeShellArgs buildFlags}' \ + '${attrs.source.url}' \ + '${src}' \ + '${attrs.source.rev}' ''} ${lib.optionalString (type == "gem") '' diff --git a/pkgs/development/ruby-modules/gem/nix-bundle-install.rb b/pkgs/development/ruby-modules/gem/nix-bundle-install.rb index 8eac766554e1..142d2da9bee2 100644 --- a/pkgs/development/ruby-modules/gem/nix-bundle-install.rb +++ b/pkgs/development/ruby-modules/gem/nix-bundle-install.rb @@ -13,31 +13,46 @@ end # Options: # +# type - installation type, either "git" or "path" # name - the gem name +# version - gem version +# build-flags - build arguments +# +# Git-only options: +# # uri - git repo uri # repo - path to local checkout # ref - the commit hash -# version - gem version -# build-flags - build arguments ruby = File.join(ENV["ruby"], "bin", RbConfig::CONFIG['ruby_install_name']) out = ENV["out"] bin_dir = File.join(ENV["out"], "bin") -name = ARGV[0] -uri = ARGV[1] -REPO = ARGV[2] -ref = ARGV[3] -version = ARGV[4] -build_flags = ARGV[5] +type = ARGV[0] +name = ARGV[1] +version = ARGV[2] +build_flags = ARGV[3] +if type == "git" + uri = ARGV[4] + REPO = ARGV[5] + ref = ARGV[6] +end # options to pass to bundler options = { - "name" => name, - "uri" => uri, - "ref" => ref, + "name" => name, "version" => version, } +if type == "path" + options.merge!({ + "path" => Dir.pwd, + }) +elsif type == "git" + options.merge!({ + "uri" => uri, + "ref" => ref, + }) +end # Monkey-patch Bundler to use our local checkout. # I wish we didn't have to do this, but bundler does not expose an API to do @@ -63,26 +78,28 @@ Bundler.module_eval do end end -Bundler::Source::Git.class_eval do - def allow_git_ops? - true - end -end - -Bundler::Source::Git::GitProxy.class_eval do - def checkout - unless path.exist? - FileUtils.mkdir_p(path.dirname) - FileUtils.cp_r(File.join(REPO, ".git"), path) - system("chmod -R +w #{path}") +if type == "git" + Bundler::Source::Git.class_eval do + def allow_git_ops? + true end end - def copy_to(destination, submodules=false) - unless File.exist?(destination.join(".git")) - FileUtils.mkdir_p(destination.dirname) - FileUtils.cp_r(REPO, destination) - system("chmod -R +w #{destination}") + Bundler::Source::Git::GitProxy.class_eval do + def checkout + unless path.exist? + FileUtils.mkdir_p(path.dirname) + FileUtils.cp_r(File.join(REPO, ".git"), path) + system("chmod -R +w #{path}") + end + end + + def copy_to(destination, submodules=false) + unless File.exist?(destination.join(".git")) + FileUtils.mkdir_p(destination.dirname) + FileUtils.cp_r(REPO, destination) + system("chmod -R +w #{destination}") + end end end end @@ -94,7 +111,11 @@ Bundler.ui = Bundler::UI::Shell.new({"no-color" => no_color}) Bundler.ui.level = "debug" if verbose # Install -source = Bundler::Source::Git.new(options) +if type == "git" + source = Bundler::Source::Git.new(options) +else + source = Bundler::Source::Path.new(options) +end spec = source.specs.search_all(name).first Bundler.rubygems.with_build_args [build_flags] do source.install(spec) @@ -139,8 +160,10 @@ FileUtils.ln_s(spec.loaded_from.to_s, "#{meta}/spec") File.open("#{meta}/name", "w") do |f| f.write spec.name end -File.open("#{meta}/install-path", "w") do |f| - f.write source.install_path.to_s +if type == "git" + File.open("#{meta}/install-path", "w") do |f| + f.write source.install_path.to_s + end end File.open("#{meta}/require-paths", "w") do |f| f.write spec.require_paths.join(" ") @@ -150,8 +173,10 @@ File.open("#{meta}/executables", "w") do |f| end # make the lib available during bundler/git installs -File.open("#{out}/nix-support/setup-hook", "a") do |f| - spec.require_paths.each do |dir| - f.puts("addToSearchPath RUBYLIB #{source.install_path}/#{dir}") +if type == "git" + File.open("#{out}/nix-support/setup-hook", "a") do |f| + spec.require_paths.each do |dir| + f.puts("addToSearchPath RUBYLIB #{source.install_path}/#{dir}") + end end end