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