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