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