lib/autoproj/package_managers/bundler_manager.rb in autoproj-2.0.0.rc9 vs lib/autoproj/package_managers/bundler_manager.rb in autoproj-2.0.0.rc10
- old
+ new
@@ -27,69 +27,59 @@
# Filters all paths that come from other autoproj installations out
# of GEM_PATH
def initialize_environment
env = ws.env
- env.inherit 'GEM_PATH'
- env.init_from_env 'GEM_PATH'
- env.system_env['GEM_PATH'] = Gem.default_path
+ config = ws.config
- if (env.original_env['GEM_HOME'] || '').empty?
- env.unset('GEM_HOME')
+ env.add_path 'PATH', File.join(Gem.user_dir, 'bin')
+ env.add_path 'PATH', File.join(ws.prefix_dir, 'gems', 'bin')
+ env.add_path 'PATH', File.join(config.bundler_gem_home, 'bin')
+ env.add_path 'PATH', File.join(ws.dot_autoproj_dir, 'autoproj', 'bin')
+ env.set 'GEM_HOME', config.gems_gem_home
+
+ if !config.private_bundler? || !config.private_autoproj? || !config.private_gems?
+ env.set('GEM_PATH', *Gem.default_path)
end
+ if config.private_bundler?
+ Autobuild.programs['bundler'] = File.join(config.bundler_gem_home, 'bin', 'bundler')
+ env.add_path 'GEM_PATH', config.bundler_gem_home
+ else
+ Autobuild.programs['bundler'] = env.find_in_path('bundler')
+ end
env.init_from_env 'RUBYLIB'
env.inherit 'RUBYLIB'
+ # Sanitize the rubylib we get from the environment by removing
+ # anything that comes from Gem or Bundler
original_rubylib =
(env['RUBYLIB'] || "").split(File::PATH_SEPARATOR).find_all do |p|
!p.start_with?(Bundler.rubygems.gem_dir) &&
!Bundler.rubygems.gem_path.any? { |gem_p| p.start_with?(p) }
end
+ # And discover the system's rubylib
if system_rubylib = discover_rubylib
env.system_env['RUBYLIB'] = []
env.original_env['RUBYLIB'] = (original_rubylib - system_rubylib).join(File::PATH_SEPARATOR)
end
ws.config.each_reused_autoproj_installation do |p|
reused_w = ws.new(p)
reused_c = reused_w.load_config
- if reused_c.private_gems?
- env.add_path 'GEM_PATH', File.join(reused_w.prefix_dir, 'gems')
- end
env.add_path 'PATH', File.join(reused_w.prefix_dir, 'gems', 'bin')
end
- gem_home = File.join(ws.prefix_dir, "gems")
- if ws.config.private_gems?
- env.set 'GEM_HOME', gem_home
- env.add_path 'GEM_PATH', gem_home
- end
-
- FileUtils.mkdir_p gem_home
- gemfile = File.join(gem_home, 'Gemfile')
+ prefix_gems = File.join(ws.prefix_dir, "gems")
+ FileUtils.mkdir_p prefix_gems
+ gemfile = File.join(prefix_gems, 'Gemfile')
if !File.exists?(gemfile)
File.open(gemfile, 'w') do |io|
io.puts "eval_gemfile \"#{File.join(ws.dot_autoproj_dir, 'autoproj', 'Gemfile')}\""
end
end
- env.set 'BUNDLE_GEMFILE', File.join(gem_home, 'Gemfile')
- env.add_path 'PATH', Gem.bindir
- env.add_path 'PATH', File.join(gem_home, 'bin')
-
- dot_autoproj = ws.dot_autoproj_dir
- if ws.config.private_bundler?
- env.add_path 'PATH', File.join(dot_autoproj, 'bundler', 'bin')
- env.add_path 'GEM_PATH', File.join(dot_autoproj, 'bundler')
- end
- env.add_path 'PATH', File.join(dot_autoproj, 'autoproj', 'bin')
- if ws.config.private_autoproj?
- env.add_path 'GEM_PATH', File.join(dot_autoproj, 'autoproj')
- end
- Autobuild.programs['bundler'] = 'bundler'
-
- if bundle_rubylib = discover_bundle_rubylib
+ if bundle_rubylib = discover_bundle_rubylib(silent_errors: true)
update_env_rubylib(bundle_rubylib, system_rubylib)
end
end
def update_env_rubylib(bundle_rubylib, system_rubylib = discover_rubylib)
@@ -131,10 +121,41 @@
FileUtils.rm backup_file
end
end
end
+ def self.run_bundler_install(ws, gemfile, *options, update: true, binstubs: nil)
+ if update && File.file?("#{gemfile}.lock")
+ FileUtils.rm "#{gemfile}.lock"
+ end
+
+ options << "--shebang" << Gem.ruby
+ if binstubs
+ options << "--binstubs" << binstubs
+ end
+
+ Bundler.with_clean_env do
+ connections = Set.new
+ ws.run 'autoproj', 'osdeps',
+ Autobuild.tool('bundler'), 'install',
+ *options,
+ working_directory: File.dirname(gemfile), env: Hash['BUNDLE_GEMFILE' => nil, 'RUBYOPT' => nil] do |line|
+
+ case line
+ when /Installing (.*)/
+ Autobuild.message " bundler: installing #{$1}"
+ when /Fetching.*from (.*)/
+ host = $1.gsub(/\.+$/, '')
+ if !connections.include?(host)
+ Autobuild.message " bundler: connected to #{host}"
+ connections << host
+ end
+ end
+ end
+ end
+ end
+
def install(gems)
root_dir = File.join(ws.prefix_dir, 'gems')
gemfile_path = File.join(root_dir, 'Gemfile')
gemfile_lock_path = "#{gemfile_path}.lock"
backups = Hash[
@@ -149,52 +170,53 @@
File.open("#{gemfile_path}.orig", 'w') do |io|
io.puts "eval_gemfile \"#{File.join(ws.dot_autoproj_dir, 'autoproj', 'Gemfile')}\""
end
end
+ gemfiles = []
+ ws.manifest.each_package_set do |source|
+ if source.local_dir && File.file?(pkg_set_gemfile = File.join(source.local_dir, 'Gemfile'))
+ gemfiles << pkg_set_gemfile
+ end
+ end
+ # In addition, look into overrides.d
+ Dir.glob(File.join(ws.config_dir, "*.gemfile")) do |gemfile_path|
+ gemfiles << gemfile_path
+ end
+
# Generate the gemfile and remove the lockfile
gems = gems.sort.map do |name|
name, version = parse_package_entry(name)
"gem \"#{name}\", \"#{version || ">= 0"}\""
end.join("\n")
FileUtils.mkdir_p root_dir
File.open(gemfile_path, 'w') do |io|
io.puts "eval_gemfile \"#{File.join(ws.dot_autoproj_dir, 'autoproj', 'Gemfile')}\""
+ gemfiles.each do |gemfile|
+ io.puts File.read(gemfile)
+ end
io.puts gems
end
- FileUtils.rm File.join(root_dir, 'Gemfile.lock')
- binstubs_path = File.join(root_dir, 'bin')
- Bundler.with_clean_env do
- connections = Set.new
- Autobuild::Subprocess.run 'autoproj', 'osdeps',
- Autobuild.tool('bundler'), 'install',
- "--gemfile=#{gemfile_path}", *options,
- "--binstubs", binstubs_path,
- "--shebang", Gem.ruby,
- env: Hash['BUNDLE_GEMFILE' => gemfile_path] do |line|
-
- case line
- when /Installing (.*)/
- Autobuild.message " bundler: installing #{$1}"
- when /Fetching.*from (.*)/
- host = $1.gsub(/\.+$/, '')
- if !connections.include?(host)
- Autobuild.message " bundler: connected to #{host}"
- connections << host
- end
- end
- end
+ options = Array.new
+ if ws.config.private_gems?
+ options << "--path" << ws.config.gems_gem_home
end
+ binstubs_path = File.join(root_dir, 'bin')
+ self.class.run_bundler_install ws, gemfile_path, *options,
+ binstubs: binstubs_path
+
if bundle_rubylib = discover_bundle_rubylib
update_env_rubylib(bundle_rubylib)
else
- raise NotCleanState, "bundler executed successfully, but the result is not in a clean state"
+ raise NotCleanState, "bundler executed successfully, but the result was not in a clean state"
end
rescue Exception => e
+ Autoproj.warn "saved the new Gemfile in #{gemfile_path}.FAILED and restored the last Gemfile version"
+ FileUtils.cp gemfile_path, "#{gemfile_path}.FAILED"
backup_restore(backups)
raise
ensure
FileUtils.rm_f File.join(binstubs_path, 'bundler')
backup_clean(backups)
@@ -212,18 +234,22 @@
io.readlines.map { |l| l.chomp }.find_all { |l| !l.empty? }
end
end
end
- def discover_bundle_rubylib
+ def discover_bundle_rubylib(silent_errors: false)
require 'bundler'
gemfile = File.join(ws.prefix_dir, 'gems', 'Gemfile')
+ silent_redirect = Hash.new
+ if silent_errors
+ silent_redirect[:err] = '/dev/null'
+ end
Tempfile.open 'autoproj-rubylib' do |io|
result = Bundler.clean_system(
Hash['BUNDLE_GEMFILE' => gemfile],
Autobuild.tool('bundler'), 'exec', 'ruby', '-e', 'puts $LOAD_PATH',
- out: io,
- err: '/dev/null')
+ out: io, **silent_redirect)
+
if result
io.readlines.map { |l| l.chomp }.find_all { |l| !l.empty? }
end
end
end