at release-16.03-start 152 lines 3.5 kB view raw
1require 'rbconfig' 2require 'bundler/vendored_thor' 3require 'bundler' 4require 'rubygems/command' 5require 'fileutils' 6require 'pathname' 7require 'tmpdir' 8 9# Options: 10# 11# name - the gem name 12# uri - git repo uri 13# repo - path to local checkout 14# ref - the commit hash 15# version - gem version 16# build-flags - build arguments 17 18ruby = File.join(ENV["ruby"], "bin", RbConfig::CONFIG['ruby_install_name']) 19out = ENV["out"] 20bin_dir = File.join(ENV["out"], "bin") 21 22name = ARGV[0] 23uri = ARGV[1] 24REPO = ARGV[2] 25ref = ARGV[3] 26version = ARGV[4] 27build_flags = ARGV[5] 28 29# options to pass to bundler 30options = { 31 "name" => name, 32 "uri" => uri, 33 "ref" => ref, 34 "version" => version, 35} 36 37# Monkey-patch Bundler to use our local checkout. 38# I wish we didn't have to do this, but bundler does not expose an API to do 39# these kinds of things. 40Bundler.module_eval do 41 def self.requires_sudo? 42 false 43 end 44 45 def self.root 46 # we don't have a Gemfile, so it doesn't make sense to try to make paths 47 # relative to the (non existent) parent directory thereof, so we give a 48 # nonsense path here. 49 Pathname.new("/no-root-path") 50 end 51 52 def self.bundle_path 53 Pathname.new(ENV["GEM_HOME"]) 54 end 55 56 def self.locked_gems 57 nil 58 end 59end 60 61Bundler::Source::Git.class_eval do 62 def allow_git_ops? 63 true 64 end 65end 66 67Bundler::Source::Git::GitProxy.class_eval do 68 def checkout 69 unless path.exist? 70 FileUtils.mkdir_p(path.dirname) 71 FileUtils.cp_r(File.join(REPO, ".git"), path) 72 system("chmod -R +w #{path}") 73 end 74 end 75 76 def copy_to(destination, submodules=false) 77 unless File.exist?(destination.join(".git")) 78 FileUtils.mkdir_p(destination.dirname) 79 FileUtils.cp_r(REPO, destination) 80 system("chmod -R +w #{destination}") 81 end 82 end 83end 84 85# UI 86verbose = false 87no_color = false 88Bundler.ui = Bundler::UI::Shell.new({"no-color" => no_color}) 89Bundler.ui.level = "debug" if verbose 90 91# Install 92source = Bundler::Source::Git.new(options) 93spec = source.specs.search_all(name).first 94Bundler.rubygems.with_build_args [build_flags] do 95 source.install(spec) 96end 97 98msg = spec.post_install_message 99if msg 100 Bundler.ui.confirm "Post-install message from #{name}:" 101 Bundler.ui.info msg 102end 103 104# Write out the binstubs 105if spec.executables.any? 106 FileUtils.mkdir_p(bin_dir) 107 spec.executables.each do |exe| 108 wrapper = File.join(bin_dir, exe) 109 File.open(wrapper, "w") do |f| 110 f.write(<<-EOF) 111#!#{ruby} 112# 113# This file was generated by Nix. 114# 115# The application '#{exe}' is installed as part of a gem, and 116# this file is here to facilitate running it. 117# 118 119require 'rubygems' 120require 'bundler/setup' 121 122load Gem.bin_path(#{spec.name.inspect}, #{exe.inspect}) 123EOF 124 end 125 126 FileUtils.chmod("+x", wrapper) 127 end 128end 129 130# Write out metadata 131meta = "#{out}/nix-support/gem-meta" 132FileUtils.mkdir_p(meta) 133FileUtils.ln_s(spec.loaded_from.to_s, "#{meta}/spec") 134File.open("#{meta}/name", "w") do |f| 135 f.write spec.name 136end 137File.open("#{meta}/install-path", "w") do |f| 138 f.write source.install_path.to_s 139end 140File.open("#{meta}/require-paths", "w") do |f| 141 f.write spec.require_paths.join(" ") 142end 143File.open("#{meta}/executables", "w") do |f| 144 f.write spec.executables.join(" ") 145end 146 147# make the lib available during bundler/git installs 148File.open("#{out}/nix-support/setup-hook", "a") do |f| 149 spec.require_paths.each do |dir| 150 f.puts("addToSearchPath RUBYLIB #{source.install_path}/#{dir}") 151 end 152end