lib/autoproj/package_managers/bundler_manager.rb in autoproj-2.0.0.rc4 vs lib/autoproj/package_managers/bundler_manager.rb in autoproj-2.0.0.rc5
- old
+ new
@@ -26,54 +26,57 @@
# Filters all paths that come from other autoproj installations out
# of GEM_PATH
def initialize_environment
env = ws.env
- env.original_env['GEM_PATH'] =
- (env['GEM_PATH'] || "").split(File::PATH_SEPARATOR).find_all do |p|
- !Workspace.in_autoproj_project?(p)
- end.join(File::PATH_SEPARATOR)
env.inherit 'GEM_PATH'
env.init_from_env 'GEM_PATH'
- orig_gem_path = env.original_env['GEM_PATH'].split(File::PATH_SEPARATOR)
+ orig_gem_path = (env['GEM_PATH'] || "").split(File::PATH_SEPARATOR).find_all do |p|
+ !Workspace.in_autoproj_project?(p)
+ end
env.system_env['GEM_PATH'] = Gem.default_path
env.original_env['GEM_PATH'] = orig_gem_path.join(File::PATH_SEPARATOR)
+ if Workspace.in_autoproj_project?(env['GEM_HOME'])
+ env.unset('GEM_HOME')
+ end
+
env.init_from_env 'RUBYLIB'
env.inherit 'RUBYLIB'
original_rubylib =
(env['RUBYLIB'] || "").split(File::PATH_SEPARATOR).find_all do |p|
!Workspace.in_autoproj_project?(p)
!p.start_with?(Bundler.rubygems.gem_dir) &&
!Bundler.rubygems.gem_path.any? { |gem_p| p.start_with?(p) }
end
- system_rubylib = discover_rubylib
- env.system_env['RUBYLIB'] = []
- env.original_env['RUBYLIB'] = (original_rubylib - system_rubylib).join(File::PATH_SEPARATOR)
+ if system_rubylib = discover_rubylib
+ env.system_env['RUBYLIB'] = []
+ env.original_env['RUBYLIB'] = (original_rubylib - system_rubylib).join(File::PATH_SEPARATOR)
+ end
dot_autoproj = ws.dot_autoproj_dir
if ws.config.private_bundler?
- env.push_path 'GEM_PATH', File.join(dot_autoproj, 'bundler')
+ env.add_path 'GEM_PATH', File.join(dot_autoproj, 'bundler')
end
if ws.config.private_autoproj?
- env.push_path 'GEM_PATH', File.join(dot_autoproj, 'autoproj')
+ env.add_path 'GEM_PATH', File.join(dot_autoproj, 'autoproj')
end
ws.manifest.each_reused_autoproj_installation do |p|
reused_w = ws.new(p)
reused_c = reused_w.load_config
if reused_c.private_gems?
- env.push_path 'GEM_PATH', File.join(reused_w.prefix_dir, 'gems')
+ env.add_path 'GEM_PATH', File.join(reused_w.prefix_dir, 'gems')
end
- env.push_path 'PATH', File.join(reused_w.prefix_dir, 'gems', 'bin')
+ 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.push_path 'GEM_PATH', gem_home
+ env.add_path 'GEM_PATH', gem_home
end
FileUtils.mkdir_p gem_home
gemfile = File.join(gem_home, 'Gemfile')
if !File.exists?(gemfile)
@@ -81,22 +84,23 @@
io.puts "eval_gemfile \"#{File.join(ws.dot_autoproj_dir, 'autoproj', 'Gemfile')}\""
end
end
env.set 'BUNDLE_GEMFILE', File.join(gem_home, 'Gemfile')
- env.push_path 'PATH', File.join(ws.dot_autoproj_dir, 'autoproj', 'bin')
- env.push_path 'PATH', File.join(gem_home, 'bin')
+ env.add_path 'PATH', File.join(gem_home, 'bin')
+ env.add_path 'PATH', File.join(ws.dot_autoproj_dir, 'autoproj', 'bin')
Autobuild.programs['bundler'] = File.join(ws.dot_autoproj_dir, 'autoproj', 'bin', 'bundler')
- update_env_rubylib(system_rubylib)
+ if bundle_rubylib = discover_bundle_rubylib
+ update_env_rubylib(bundle_rubylib, system_rubylib)
+ end
end
- def update_env_rubylib(system_rubylib = discover_rubylib)
- rubylib = discover_bundle_rubylib
+ def update_env_rubylib(bundle_rubylib, system_rubylib = discover_rubylib)
current = ws.env.resolved_env['RUBYLIB'].split(File::PATH_SEPARATOR) + system_rubylib
- (rubylib - current).each do |p|
- ws.env.push_path('RUBYLIB', p)
+ (bundle_rubylib - current).each do |p|
+ ws.env.add_path('RUBYLIB', p)
end
end
def parse_package_entry(entry)
if entry =~ /^([^><=~]*)([><=~]+.*)$/
@@ -104,40 +108,72 @@
else
[entry]
end
end
+ class NotCleanState < RuntimeError; end
+
+ def backup_files(mapping)
+ mapping.each do |file, backup_file|
+ if File.file?(file)
+ FileUtils.cp file, backup_file
+ end
+ end
+ end
+
+ def backup_restore(mapping)
+ mapping.each do |file, backup_file|
+ if File.file?(backup_file)
+ FileUtils.cp backup_file, file
+ end
+ end
+ end
+
+ def backup_clean(mapping)
+ mapping.each do |file, backup_file|
+ if File.file?(backup_file)
+ FileUtils.rm backup_file
+ end
+ end
+ end
+
def install(gems)
- # Generate the gemfile
+ root_dir = File.join(ws.prefix_dir, 'gems')
+ gemfile_path = File.join(root_dir, 'Gemfile')
+ gemfile_lock_path = "#{gemfile_path}.lock"
+ backups = Hash[
+ gemfile_path => "#{gemfile_path}.orig",
+ gemfile_lock_path => "#{gemfile_lock_path}.orig"
+ ]
+
+ # Back up the existing gemfile, we'll restore it if something is
+ # wrong to avoid leaving bundler in an inconsistent state
+ backup_files(backups)
+
+ # 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")
-
- root_dir = File.join(ws.prefix_dir, 'gems')
FileUtils.mkdir_p root_dir
- gemfile = File.join(root_dir, 'Gemfile')
- File.open(gemfile, 'w') do |io|
+ File.open(gemfile_path, 'w') do |io|
io.puts "eval_gemfile \"#{File.join(ws.dot_autoproj_dir, 'autoproj', 'Gemfile')}\""
io.puts gems
end
+ FileUtils.rm File.join(root_dir, 'Gemfile.lock')
- File.open(File.join(root_dir, 'Gemfile.lock'), 'w') do |io|
- io.write File.read(File.join(ws.dot_autoproj_dir, 'autoproj', 'Gemfile.lock'))
- end
-
if ws.config.private_gems?
options = ['--path', root_dir]
end
Bundler.with_clean_env do
connections = Set.new
Autobuild::Subprocess.run 'autoproj', 'osdeps',
Autobuild.tool('bundler'), 'install',
- "--gemfile=#{gemfile}", *options,
+ "--gemfile=#{gemfile_path}", *options,
"--binstubs", File.join(root_dir, 'bin'),
- env: Hash['BUNDLE_GEMFILE' => gemfile] do |line|
+ env: Hash['BUNDLE_GEMFILE' => gemfile_path] do |line|
case line
when /Installing (.*)/
Autobuild.message " bundler: installing #{$1}"
when /Fetching.*from (.*)/
@@ -148,31 +184,47 @@
end
end
end
end
- update_env_rubylib
+ 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"
+ end
+
+ rescue Exception => e
+ backup_restore(backups)
+ raise
+ ensure
+ backup_clean(backups)
end
def discover_rubylib
- r, w = IO.pipe
- Bundler.clean_system(
- Hash['RUBYLIB' => nil],
- Autobuild.tool('ruby'), '-e', 'puts $LOAD_PATH',
- out: w)
- w.close
- r.readlines.map { |l| l.chomp }.find_all { |l| !l.empty? }
+ Tempfile.open 'autoproj-rubylib' do |io|
+ result = Bundler.clean_system(
+ Hash['RUBYLIB' => nil],
+ Autobuild.tool('ruby'), '-e', 'puts $LOAD_PATH',
+ out: io)
+ #err: '/dev/null')
+ if result
+ io.readlines.map { |l| l.chomp }.find_all { |l| !l.empty? }
+ end
+ end
end
def discover_bundle_rubylib
gemfile = File.join(ws.prefix_dir, 'gems', 'Gemfile')
- r, w = IO.pipe
- Bundler.clean_system(
- Hash['BUNDLE_GEMFILE' => gemfile],
- Autobuild.tool('bundler'), 'exec', 'ruby', '-e', 'puts $LOAD_PATH',
- out: w)
- w.close
- r.readlines.map { |l| l.chomp }.find_all { |l| !l.empty? }
+ 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')
+ if result
+ io.readlines.map { |l| l.chomp }.find_all { |l| !l.empty? }
+ end
+ end
end
end
end
end