···1+require 'bundler'
2+3+Bundler.module_eval do
4+ class << self
5+ # mappings from original uris to store paths.
6+ def nix_gem_sources
7+ @nix_gem_sources ||=
8+ begin
9+ src = ENV['NIX_GEM_SOURCES']
10+ eval(Bundler.read_file(src))
11+ end
12+ end
13+14+ # extract the gemspecs from the gems pulled from Rubygems.
15+ def nix_gemspecs
16+ @nix_gemspecs ||= Dir.glob("gems/*.gem").map do |path|
17+ Bundler.rubygems.spec_from_gem(path)
18+ end
19+ end
20+21+ # map a git uri to a fetchgit store path.
22+ def nix_git(uri)
23+ Pathname.new(nix_gem_sources["git"][uri])
24+ end
25+ end
26+end
27+28+Bundler::Source::Git::GitProxy.class_eval do
29+ def checkout
30+ unless path.exist?
31+ FileUtils.mkdir_p(path.dirname)
32+ FileUtils.cp_r(Bundler.nix_git(@uri).join(".git"), path)
33+ system("chmod -R +w #{path}")
34+ end
35+ end
36+37+ def copy_to(destination, submodules=false)
38+ unless File.exist?(destination.join(".git"))
39+ FileUtils.mkdir_p(destination.dirname)
40+ FileUtils.cp_r(Bundler.nix_git(@uri), destination)
41+ system("chmod -R +w #{destination}")
42+ end
43+ end
44+end
45+46+Bundler::Fetcher.class_eval do
47+ def use_api
48+ true
49+ end
50+51+ def fetch_dependency_remote_specs(gem_names)
52+ Bundler.ui.debug "Query Gemcutter Dependency Endpoint API: #{gem_names.join(',')}"
53+ deps_list = []
54+55+ spec_list = gem_names.map do |name|
56+ spec = Bundler.nix_gemspecs.detect {|spec| spec.name == name }
57+ dependencies = spec.dependencies.
58+ select {|dep| dep.type != :development}.
59+ map do |dep|
60+ deps_list << dep.name
61+ dep
62+ end
63+64+ [spec.name, spec.version, spec.platform, dependencies]
65+ end
66+67+ [spec_list, deps_list.uniq]
68+ end
69+end
70+71+Bundler::Source::Rubygems.class_eval do
72+ # We copy all gems into $PWD/gems, and this allows RubyGems to find those
73+ # gems during installation.
74+ def fetchers
75+ @fetchers ||= [
76+ Bundler::Fetcher.new(URI.parse("file://#{File.expand_path(Dir.pwd)}"))
77+ ]
78+ end
79+80+ # Look-up gems that were originally from Rubygems.
81+ def remote_specs
82+ @remote_specs ||=
83+ begin
84+ lockfile = Bundler::LockfileParser.new(Bundler.read_file(Bundler.default_lockfile))
85+ gem_names = lockfile.specs.
86+ select {|spec| spec.source.is_a?(Bundler::Source::Rubygems)}.
87+ map {|spec| spec.name}
88+ idx = Bundler::Index.new
89+ api_fetchers.each do |f|
90+ Bundler.ui.info "Fetching source index from #{f.uri}"
91+ idx.use f.specs(gem_names, self)
92+ end
93+ idx
94+ end
95+ end
96+end
97+98+Gem::Installer.class_eval do
99+ # Make the wrappers automagically use bundler.
100+ #
101+ # Stage 1.
102+ # Set $BUNDLE_GEMFILE so bundler knows what gems to load.
103+ # Set $GEM_HOME to the installed gems, because bundler looks there for
104+ # non-Rubygems installed gems (e.g. git/svn/path sources).
105+ # Set $GEM_PATH to include both bundler and installed gems.
106+ #
107+ # Stage 2.
108+ # Setup bundler, locking down the gem versions.
109+ #
110+ # Stage 3.
111+ # Reset $BUNDLE_GEMFILE, $GEM_HOME, $GEM_PATH.
112+ #
113+ # Stage 4.
114+ # Run the actual executable.
115+ def app_script_text(bin_file_name)
116+ return <<-TEXT
117+#{shebang bin_file_name}
118+#
119+# This file was generated by Nix's RubyGems.
120+#
121+# The application '#{spec.name}' is installed as part of a gem, and
122+# this file is here to facilitate running it.
123+#
124+125+old_gemfile = ENV["BUNDLE_GEMFILE"]
126+old_gem_home = ENV["GEM_HOME"]
127+old_gem_path = ENV["GEM_PATH"]
128+129+ENV["BUNDLE_GEMFILE"] =
130+ "#{ENV["BUNDLE_GEMFILE"]}"
131+ENV["GEM_HOME"] =
132+ "#{ENV["GEM_HOME"]}"
133+ENV["GEM_PATH"] =
134+ "#{ENV["NIX_BUNDLER_GEMPATH"]}:#{ENV["GEM_HOME"]}\#{old_gem_path ? ":\#{old_gem_path}" : ""}}"
135+136+require 'rubygems'
137+require 'bundler/setup'
138+139+ENV["BUNDLE_GEMFILE"] = old_gemfile
140+ENV["GEM_HOME"] = old_gem_home
141+ENV["GEM_PATH"] = old_gem_path
142+143+load Gem.bin_path('#{spec.name}', '#{bin_file_name}')
144+TEXT
145+ end
146+end