bin/autoproj_bootstrap in autoproj-2.0.0.rc32 vs bin/autoproj_bootstrap in autoproj-2.0.0.rc33

- old
+ new

@@ -39,16 +39,12 @@ # The URL of the source to be used to get gems attr_accessor :gem_source def initialize(root_dir) @root_dir = root_dir - if File.file?(autoproj_gemfile_path) - @gemfile = File.read(autoproj_gemfile_path) - else - @gemfile = default_gemfile_contents - end @gem_source = "https://rubygems.org" + @gemfile = nil @autoproj_options = Array.new @env = Hash.new env['RUBYLIB'] = [] @@ -64,11 +60,10 @@ @ruby_executable = config['ruby_executable'] @local = false default_gem_path = File.join(Dir.home, '.autoproj', 'gems') @gems_install_path = default_gem_path - @autoproj_install_path = default_gem_path end def env_for_child env.inject(Hash.new) do |h, (k, v)| h[k] = if v && !v.empty? then v.join(File::PATH_SEPARATOR) @@ -134,37 +129,14 @@ def gem_path_suffix @gem_path_suffix ||= Pathname.new(Gem.user_dir). relative_path_from(Pathname.new(dot_gem_dir)).to_s end - # The path into which autoproj and its dependencies should be installed - # - # They are installed in a versioned subdirectory of this path, e.g. - # {#gem_path_suffix}. It is always absolute. - # - # @return [String] - attr_reader :autoproj_install_path - # The GEM_HOME into which the autoproj gems should be installed - def autoproj_gem_home; File.join(autoproj_install_path, gem_path_suffix) end - # Sets the place where autoproj should be installed - # - # @param [String] path Sets the path given to bundler, i.e. the - # gems will be installed under the {#gem_path_suffix} - def autoproj_install_path=(path) - @autoproj_install_path = File.expand_path(path) - end - # Install autoproj in Gem's default user dir - def install_autoproj_in_gem_user_dir - @autoproj_install_path = File.join(Gem.user_home, '.gem') - end - # The path into which the workspace's gems should be installed # # They are installed in a versioned subdirectory of this path, e.g. - # {#gem_path_suffix}. Unlike {#autoproj_install_path}, it can be - # relative, in which case it is relative to the workspace's prefix - # directory. + # {#gem_path_suffix}. # # @return [String] attr_reader :gems_install_path # The GEM_HOME under which the workspace's gems should be installed # @@ -188,11 +160,11 @@ # Debian package) def prefer_indep_over_os_packages?; @prefer_indep_over_os_packages end # (see #prefer_index_over_os_packages?) def prefer_indep_over_os_packages=(flag); @prefer_indep_over_os_packages = !!flag end - def guess_gem_program + def self.guess_gem_program ruby_bin = RbConfig::CONFIG['RUBY_INSTALL_NAME'] ruby_bindir = RbConfig::CONFIG['bindir'] candidates = ['gem'] if ruby_bin =~ /^ruby(.+)$/ @@ -223,29 +195,28 @@ options = OptionParser.new do |opt| opt.on '--local', 'do not access the network (may fail)' do @local = true end opt.on '--gem-source=URL', String, "use this source for RubyGems instead of rubygems.org" do |url| - self.gem_source = url + @gem_source = url end - opt.on '--shared-gems[=PATH]', "install gems in a shared location. By default, uses the default RubyGems locations" do |path| - if path - self.autoproj_install_path = path - self.gems_install_path = path - else - self.install_autoproj_in_gem_user_dir - self.install_gems_in_gem_user_dir - end + opt.on '--gems-path=PATH', "install gems under this path instead of ~/.autoproj/gems" do |path| + self.gems_install_path = path end - opt.on '--private-gems', "install bundler, autoproj and the workspace gems in dedicated locations within the workspace" do |path| - self.autoproj_install_path = File.join(dot_autoproj, 'gems') - self.gems_install_path = 'gems' + opt.on '--public-gems', "install gems in the default gem location" do + self.install_gems_in_gem_user_dir end opt.on '--version=VERSION_CONSTRAINT', String, 'use the provided string as a version constraint for autoproj' do |version| + if @gemfile + raise "cannot give both --version and --gemfile" + end @gemfile = default_gemfile_contents(version) end opt.on '--gemfile=PATH', String, 'use the given Gemfile to install autoproj instead of the default' do |path| + if @gemfile + raise "cannot give both --version and --gemfile" + end @gemfile = File.read(path) end opt.on '--seed-config=PATH', String, 'path to a seed file that should be used to initialize the configuration' do |path| @config.merge!(YAML.load(File.read(path))) end @@ -272,11 +243,11 @@ env_for_child, Gem.ruby, gem_program, 'which', 'bundler/setup', out: '/dev/null') return if !result - bundler_path = File.join(autoproj_gem_home, 'bin', 'bundler') + bundler_path = File.join(gems_gem_home, 'bin', 'bundler') if File.exist?(bundler_path) bundler_path end end @@ -285,18 +256,18 @@ result = system( env_for_child, Gem.ruby, gem_program, 'install', '--env-shebang', '--no-document', '--no-format-executable', '--clear-sources', '--source', gem_source, *local, - "--bindir=#{File.join(autoproj_gem_home, 'bin')}", 'bundler') + "--bindir=#{File.join(gems_gem_home, 'bin')}", 'bundler') if !result - STDERR.puts "FATAL: failed to install bundler in #{autoproj_gem_home}" + STDERR.puts "FATAL: failed to install bundler in #{gems_gem_home}" nil end - bundler_path = File.join(autoproj_gem_home, 'bin', 'bundler') + bundler_path = File.join(gems_gem_home, 'bin', 'bundler') if File.exist?(bundler_path) bundler_path else STDERR.puts "gem install bundler returned successfully, but still cannot find bundler in #{bundler_path}" nil @@ -313,11 +284,11 @@ clean_env = env_for_child.dup opts = Array.new opts << '--local' if local? - opts << "--path=#{autoproj_install_path}" + opts << "--path=#{gems_install_path}" shims_path = File.join(dot_autoproj, 'bin') result = system(clean_env, Gem.ruby, bundler, 'install', "--gemfile=#{autoproj_gemfile_path}", "--shebang=#{Gem.ruby}", @@ -327,45 +298,75 @@ if !result STDERR.puts "FATAL: failed to install autoproj in #{dot_autoproj}" exit 1 end ensure - self.class.clean_binstubs(shims_path, ruby_executable, bundler) + self.class.rewrite_shims(shims_path, ruby_executable, autoproj_gemfile_path, gems_gem_home) end - def self.clean_binstubs(shim_path, ruby_executable, bundler_path) - %w{bundler bundle rake thor ruby}.each do |bundler_bin| - path = File.join(shim_path, bundler_bin) - if File.file?(path) - FileUtils.rm path - end + def self.rewrite_shims(shim_path, ruby_executable, autoproj_gemfile_path, gems_gem_home) + FileUtils.mkdir_p shim_path + File.open(File.join(shim_path, 'ruby'), 'w') do |io| + io.puts "#! /bin/sh" + io.puts "exec #{ruby_executable} \"$@\"" end + FileUtils.chmod 0755, File.join(shim_path, 'ruby') - # Now tune the binstubs to force the usage of the autoproj - # gemfile. Otherwise, they get BUNDLE_GEMFILE from the - # environment by default - Dir.glob(File.join(shim_path, '*')) do |path| - next if !File.file?(path) + FileUtils.touch File.join(shim_path, 'bundler') + FileUtils.touch File.join(shim_path, 'bundle') + Dir.glob(File.join(shim_path, '*')) do |bin_script| + next if !File.file?(bin_script) + bin_name = File.basename(bin_script) + next if bin_name == 'ruby' - lines = File.readlines(path) - matched = false - filtered = lines.map do |l| - matched ||= (ENV_BUNDLE_GEMFILE_RX === l) - l.gsub(ENV_BUNDLE_GEMFILE_RX, '\\1=') + bin_shim = File.join(shim_path, bin_name) + bin_script_lines = File.readlines(bin_script) + File.open(bin_shim, 'w') do |io| + if bin_name == 'bundler' || bin_name == 'bundle' + io.puts shim_bundler(ruby_executable, autoproj_gemfile_path, gems_gem_home) + else + load_line = bin_script_lines.grep(/load Gem.bin_path/).first + io.puts shim_script(ruby_executable, autoproj_gemfile_path, gems_gem_home, load_line) + end end - if !matched - raise UnexpectedBinstub, "expected #{path} to contain a line looking like ENV['BUNDLE_GEMFILE'] ||= but could not find one" - end - File.open(path, 'w') do |io| - io.write filtered.join("") - end + FileUtils.chmod 0755, bin_shim end + end - ensure - save_ruby_and_bundler_shims(shim_path, ruby_executable, bundler_path) + def self.shim_bundler(ruby_executable, autoproj_gemfile_path, gems_gem_home) +"#! #{ruby_executable} + +if defined?(Bundler) + Bundler.with_clean_env do + exec($0, *ARGV) + end +end + +ENV.delete('BUNDLE_GEMFILE') +ENV['GEM_HOME'] = '#{gems_gem_home}' +ENV.delete('GEM_PATH') +Gem.paths = Hash['GEM_HOME' => '#{gems_gem_home}', 'GEM_PATH' => ''] + +load Gem.bin_path('bundler', 'bundler')" end + + def self.shim_script(ruby_executable, autoproj_gemfile_path, gems_gem_home, load_line) +"#! #{ruby_executable} +if defined?(Bundler) + Bundler.with_clean_env do + exec($0, *ARGV) + end +end + +ENV['BUNDLE_GEMFILE'] = '#{autoproj_gemfile_path}' +require 'rubygems' +Gem.paths = Hash['GEM_HOME' => '#{gems_gem_home}', 'GEM_PATH' => ''] +require 'bundler/setup' +#{load_line}" + end + def save_env_sh(*vars) env = Autobuild::Environment.new env.prepare vars.each do |kv| k, *v = kv.split("=") @@ -390,10 +391,19 @@ env.export_env_sh(io) end end def save_gemfile + gemfile = + if @gemfile + @gemfile + elsif File.file?(autoproj_gemfile_path) + File.read(autoproj_gemfile_path) + else + default_gemfile_contents + end + FileUtils.mkdir_p File.dirname(autoproj_gemfile_path) File.open(autoproj_gemfile_path, 'w') do |io| io.write gemfile end end @@ -432,50 +442,36 @@ else raise "FATAL: cannot run #{Gem.ruby} -e 'puts Gem.bindir'" end end - def self.save_ruby_and_bundler_shims(shim_path, ruby_executable, bundler_path) - FileUtils.mkdir_p shim_path - bundler_rubylib = File.expand_path(File.join('..', '..', 'lib'), bundler_path) - File.open(File.join(shim_path, 'bundler'), 'w') do |io| - io.puts "#! /bin/sh" - io.puts "exec #{ruby_executable} #{bundler_path} \"$@\"" - end - FileUtils.chmod 0755, File.join(shim_path, 'bundler') - File.open(File.join(shim_path, 'ruby'), 'w') do |io| - io.puts "#! /bin/sh" - io.puts "exec #{ruby_executable} \"$@\"" - end - FileUtils.chmod 0755, File.join(shim_path, 'ruby') - end - def install if ENV['BUNDLER_GEMFILE'] raise "cannot run autoproj_install or autoproj_bootstrap while under a 'bundler exec' subcommand or having loaded an env.sh. Open a new console and try again" end - gem_program = guess_gem_program + gem_program = self.class.guess_gem_program puts "Detected 'gem' to be #{gem_program}" - env['GEM_HOME'] = [autoproj_gem_home] + env['GEM_HOME'] = [gems_gem_home] if bundler = find_bundler(gem_program) puts "Detected bundler at #{bundler}" else - puts "Installing bundler in #{autoproj_gem_home}" + puts "Installing bundler in #{gems_gem_home}" if !(bundler = install_bundler(gem_program)) exit 1 end end - self.class.save_ruby_and_bundler_shims( + self.class.rewrite_shims( File.join(dot_autoproj, 'bin'), ruby_executable, - bundler) + autoproj_gemfile_path, + gems_gem_home) env['PATH'].unshift File.join(dot_autoproj, 'bin') save_gemfile - puts "Installing autoproj in #{autoproj_gem_home}" + puts "Installing autoproj in #{gems_gem_home}" install_autoproj(bundler) end def load_config v1_config_path = File.join(root_dir, 'autoproj', 'config.yml') @@ -498,17 +494,16 @@ else config['ruby_executable'] = ruby_executable end @config = config - %w{autoproj_install_path gems_install_path prefer_indep_over_os_packages}.each do |flag| + %w{gems_install_path prefer_indep_over_os_packages}.each do |flag| instance_variable_set "@#{flag}", config.fetch(flag, false) end end def save_config - config['autoproj_install_path'] = autoproj_install_path config['gems_install_path'] = gems_install_path config['prefer_indep_over_os_packages'] = prefer_indep_over_os_packages? File.open(autoproj_config_path, 'w') { |io| YAML.dump(config, io) } end @@ -549,16 +544,16 @@ def stage2(*vars) require 'autobuild' puts "saving env.sh and .autoproj/env.sh" save_env_sh(*vars) - if !system(Gem.ruby, autoproj_path, 'envsh', *autoproj_options) + if !system(Gem.ruby, autoproj_path, 'envsh', *autoproj_options, '--debug') STDERR.puts "failed to run autoproj envsh on the newly installed autoproj (#{autoproj_path})" exit 1 end # This is really needed on an existing install to install the # gems that were present in the v1 layout - if !system(Gem.ruby, autoproj_path, 'osdeps') + if !system(Gem.ruby, autoproj_path, 'osdeps', '--debug') STDERR.puts "failed to run autoproj osdeps on the newly installed autoproj (#{autoproj_path})" exit 1 end end end