···11+require 'bundler'
22+33+Bundler.module_eval do
44+ class << self
55+ # mappings from original uris to store paths.
66+ def nix_gem_sources
77+ @nix_gem_sources ||=
88+ begin
99+ src = ENV['NIX_GEM_SOURCES']
1010+ eval(Bundler.read_file(src))
1111+ end
1212+ end
1313+1414+ # extract the gemspecs from the gems pulled from Rubygems.
1515+ def nix_gemspecs
1616+ @nix_gemspecs ||= Dir.glob("gems/*.gem").map do |path|
1717+ Bundler.rubygems.spec_from_gem(path)
1818+ end
1919+ end
2020+2121+ # map a git uri to a fetchgit store path.
2222+ def nix_git(uri)
2323+ Pathname.new(nix_gem_sources["git"][uri])
2424+ end
2525+ end
2626+end
2727+2828+Bundler::Source::Git::GitProxy.class_eval do
2929+ def checkout
3030+ unless path.exist?
3131+ FileUtils.mkdir_p(path.dirname)
3232+ FileUtils.cp_r(Bundler.nix_git(@uri).join(".git"), path)
3333+ system("chmod -R +w #{path}")
3434+ end
3535+ end
3636+3737+ def copy_to(destination, submodules=false)
3838+ unless File.exist?(destination.join(".git"))
3939+ FileUtils.mkdir_p(destination.dirname)
4040+ FileUtils.cp_r(Bundler.nix_git(@uri), destination)
4141+ system("chmod -R +w #{destination}")
4242+ end
4343+ end
4444+end
4545+4646+Bundler::Fetcher.class_eval do
4747+ def use_api
4848+ true
4949+ end
5050+5151+ def fetch_dependency_remote_specs(gem_names)
5252+ Bundler.ui.debug "Query Gemcutter Dependency Endpoint API: #{gem_names.join(',')}"
5353+ deps_list = []
5454+5555+ spec_list = gem_names.map do |name|
5656+ spec = Bundler.nix_gemspecs.detect {|spec| spec.name == name }
5757+ dependencies = spec.dependencies.
5858+ select {|dep| dep.type != :development}.
5959+ map do |dep|
6060+ deps_list << dep.name
6161+ dep
6262+ end
6363+6464+ [spec.name, spec.version, spec.platform, dependencies]
6565+ end
6666+6767+ [spec_list, deps_list.uniq]
6868+ end
6969+end
7070+7171+Bundler::Source::Rubygems.class_eval do
7272+ # We copy all gems into $PWD/gems, and this allows RubyGems to find those
7373+ # gems during installation.
7474+ def fetchers
7575+ @fetchers ||= [
7676+ Bundler::Fetcher.new(URI.parse("file://#{File.expand_path(Dir.pwd)}"))
7777+ ]
7878+ end
7979+8080+ # Look-up gems that were originally from Rubygems.
8181+ def remote_specs
8282+ @remote_specs ||=
8383+ begin
8484+ lockfile = Bundler::LockfileParser.new(Bundler.read_file(Bundler.default_lockfile))
8585+ gem_names = lockfile.specs.
8686+ select {|spec| spec.source.is_a?(Bundler::Source::Rubygems)}.
8787+ map {|spec| spec.name}
8888+ idx = Bundler::Index.new
8989+ api_fetchers.each do |f|
9090+ Bundler.ui.info "Fetching source index from #{f.uri}"
9191+ idx.use f.specs(gem_names, self)
9292+ end
9393+ idx
9494+ end
9595+ end
9696+end
9797+9898+Gem::Installer.class_eval do
9999+ # Make the wrappers automagically use bundler.
100100+ #
101101+ # Stage 1.
102102+ # Set $BUNDLE_GEMFILE so bundler knows what gems to load.
103103+ # Set $GEM_HOME to the installed gems, because bundler looks there for
104104+ # non-Rubygems installed gems (e.g. git/svn/path sources).
105105+ # Set $GEM_PATH to include both bundler and installed gems.
106106+ #
107107+ # Stage 2.
108108+ # Setup bundler, locking down the gem versions.
109109+ #
110110+ # Stage 3.
111111+ # Reset $BUNDLE_GEMFILE, $GEM_HOME, $GEM_PATH.
112112+ #
113113+ # Stage 4.
114114+ # Run the actual executable.
115115+ def app_script_text(bin_file_name)
116116+ return <<-TEXT
117117+#{shebang bin_file_name}
118118+#
119119+# This file was generated by Nix's RubyGems.
120120+#
121121+# The application '#{spec.name}' is installed as part of a gem, and
122122+# this file is here to facilitate running it.
123123+#
124124+125125+old_gemfile = ENV["BUNDLE_GEMFILE"]
126126+old_gem_home = ENV["GEM_HOME"]
127127+old_gem_path = ENV["GEM_PATH"]
128128+129129+ENV["BUNDLE_GEMFILE"] =
130130+ "#{ENV["BUNDLE_GEMFILE"]}"
131131+ENV["GEM_HOME"] =
132132+ "#{ENV["GEM_HOME"]}"
133133+ENV["GEM_PATH"] =
134134+ "#{ENV["NIX_BUNDLER_GEMPATH"]}:#{ENV["GEM_HOME"]}\#{old_gem_path ? ":\#{old_gem_path}" : ""}}"
135135+136136+require 'rubygems'
137137+require 'bundler/setup'
138138+139139+ENV["BUNDLE_GEMFILE"] = old_gemfile
140140+ENV["GEM_HOME"] = old_gem_home
141141+ENV["GEM_PATH"] = old_gem_path
142142+143143+load Gem.bin_path('#{spec.name}', '#{bin_file_name}')
144144+TEXT
145145+ end
146146+end