autoproj 2.0.0.rc9 → 2.0.0.rc10

Sign up to get free protection for your applications and to get access to all the features.
@@ -12,3 +12,4 @@ ENV.delete('RUBYLIB')
12
12
  ops = Autoproj::Ops::Install.new(Dir.pwd)
13
13
  ops.parse_options(ARGV)
14
14
  ops.stage1
15
+ ops.call_stage2
@@ -549,15 +549,11 @@ class Autobuild::Git
549
549
  # only override the branch
550
550
  # @return [Hash] the snapshot information, in a format that can be used by
551
551
  # {#relocate}
552
- def snapshot(package, target_dir = nil, options = Hash.new)
553
- options = Kernel.validate_options options,
554
- local: true,
555
- exact_state: true
556
-
557
- if options[:local]
558
- snapshot_local(package, exact_state: options[:exact_state])
552
+ def snapshot(package, target_dir = nil, only_local: true, exact_state: true)
553
+ if only_local
554
+ snapshot_local(package, exact_state: exact_state)
559
555
  else
560
- snapshot_against_remote(package, exact_state: options[:exact_state])
556
+ snapshot_against_remote(package, exact_state: exact_state)
561
557
  end
562
558
  end
563
559
 
@@ -64,7 +64,7 @@ def run(buildconf_info, options)
64
64
  amake
65
65
 
66
66
  The resulting software is installed in
67
- #{root_dir}/install
67
+ #{ws.prefix_dir}
68
68
 
69
69
  EOTEXT
70
70
 
@@ -59,7 +59,7 @@ def run(selection, options = Hash.new)
59
59
  if name == selection || pkg.srcdir == selection
60
60
  puts result_value(pkg, options)
61
61
  return
62
- elsif name =~ selection_rx || selection.start_with?(pkg.srcdir)
62
+ elsif name =~ selection_rx || selection.start_with?(pkg.srcdir) || (selection.start_with?(pkg.builddir) if pkg.builddir)
63
63
  candidates << pkg
64
64
  end
65
65
  end
@@ -26,8 +26,14 @@ class Main < Thor
26
26
  def run_autoproj_cli(filename, classname, report_options, *args)
27
27
  require "autoproj/cli/#{filename}"
28
28
  Autoproj.report(Hash[silent: !options[:debug], debug: options[:debug]].merge(report_options)) do
29
+ options = self.options.dup
30
+ # We use --local on the CLI but the APIs are expecting
31
+ # only_local
32
+ if options.has_key?('local')
33
+ options[:only_local] = options.delete('local')
34
+ end
29
35
  cli = CLI.const_get(classname).new
30
- run_args = cli.validate_options(args, self.options)
36
+ run_args = cli.validate_options(args, options)
31
37
  cli.run(*run_args)
32
38
  end
33
39
  end
@@ -57,7 +63,7 @@ def envsh
57
63
  end
58
64
 
59
65
  desc 'status [PACKAGES]', 'displays synchronization status between this workspace and the package(s) source'
60
- option :only_local,
66
+ option :local, type: :boolean, default: false,
61
67
  desc: 'only use locally available information (mainly for distributed version control systems such as git)'
62
68
  option :mainline, type: :string,
63
69
  desc: "compare to the given baseline. if 'true', the comparison will ignore any override, otherwise it will take into account overrides only up to the given package set"
@@ -27,6 +27,10 @@ def run(user_selection, options = Hash.new)
27
27
  return
28
28
  end
29
29
 
30
+ if !options.has_key?(:parallel) && options[:only_local]
31
+ options[:parallel] = 1
32
+ end
33
+
30
34
  if options[:config]
31
35
  pkg_sets = ws.manifest.each_package_set.to_a
32
36
  if !pkg_sets.empty?
@@ -40,7 +44,7 @@ def run(user_selection, options = Hash.new)
40
44
  packages = packages.sort.map do |pkg_name|
41
45
  ws.manifest.find_package(pkg_name)
42
46
  end
43
- display_status(packages, snapshot: options[:snapshot], only_local: options[:only_local])
47
+ display_status(packages, parallel: options[:parallel], snapshot: options[:snapshot], only_local: options[:only_local])
44
48
  end
45
49
 
46
50
  def snapshot_overrides_vcs?(importer, vcs, snapshot)
@@ -53,7 +57,7 @@ def snapshot_overrides_vcs?(importer, vcs, snapshot)
53
57
  end
54
58
 
55
59
  PackageStatus = Struct.new :msg, :sync, :uncommitted, :local, :remote
56
- def status_of_package(package_description, options = Hash.new)
60
+ def status_of_package(package_description, only_local: false, snapshot: false)
57
61
  pkg = package_description.autobuild
58
62
  importer = pkg.importer
59
63
  package_status = PackageStatus.new(Array.new, false, false, false, false)
@@ -66,7 +70,7 @@ def status_of_package(package_description, options = Hash.new)
66
70
  else
67
71
  if importer.respond_to?(:snapshot)
68
72
  snapshot =
69
- begin importer.snapshot(pkg, nil, exact_state: false, local: options[:only_local])
73
+ begin importer.snapshot(pkg, nil, exact_state: false, only_local: only_local)
70
74
  rescue Autobuild::PackageException
71
75
  Hash.new
72
76
  end
@@ -74,13 +78,13 @@ def status_of_package(package_description, options = Hash.new)
74
78
  non_nil_values = snapshot.delete_if { |k, v| !v }
75
79
  package_status.msg << Autoproj.color(" found configuration that contains all local changes: #{non_nil_values.sort_by(&:first).map { |k, v| "#{k}: #{v}" }.join(", ")}", :bright_green)
76
80
  package_status.msg << Autoproj.color(" consider adding this to your overrides, or use autoproj versions to do it for you", :bright_green)
77
- if options[:snapshot]
81
+ if snapshot
78
82
  importer.relocate(importer.repository, snapshot)
79
83
  end
80
84
  end
81
85
  end
82
86
 
83
- begin status = importer.status(pkg, options[:only_local])
87
+ begin status = importer.status(pkg, only_local)
84
88
  rescue Interrupt
85
89
  raise
86
90
  rescue Exception => e
@@ -139,7 +143,10 @@ def display_status(packages, options = Hash.new)
139
143
  pkg.autobuild.importer && pkg.autobuild.importer.interactive?
140
144
  end
141
145
  noninteractive = noninteractive.map do |pkg|
142
- [pkg, Concurrent::Future.execute(executor: executor) { status_of_package(pkg, snapshot: options[:snapshot], only_local: options[:only_local]) }]
146
+ future = Concurrent::Future.execute(executor: executor) do
147
+ status_of_package(pkg, snapshot: options[:snapshot], only_local: options[:only_local])
148
+ end
149
+ [pkg, future]
143
150
  end
144
151
 
145
152
  sync_packages = ""
@@ -57,7 +57,7 @@ def run(selected_packages, options)
57
57
 
58
58
  ws.load_package_sets(
59
59
  mainline: options[:mainline],
60
- only_local: options[:local],
60
+ only_local: options[:only_local],
61
61
  checkout_only: !options[:config] || options[:checkout_only],
62
62
  reset: options[:reset],
63
63
  ignore_errors: options[:keep_going],
@@ -112,7 +112,7 @@ def run(selected_packages, options)
112
112
  source_packages, osdep_packages =
113
113
  ops.import_packages(selected_packages,
114
114
  checkout_only: options[:checkout_only],
115
- only_local: options[:local],
115
+ only_local: options[:only_local],
116
116
  reset: options[:reset],
117
117
  recursive: options[:deps],
118
118
  ignore_errors: options[:keep_going],
@@ -33,16 +33,15 @@ def run(user_selection, options)
33
33
  finalize_setup(user_selection,
34
34
  recursive: options[:deps],
35
35
  ignore_non_imported_packages: true)
36
-
37
36
 
38
37
  ops = Ops::Snapshot.new(ws.manifest, ignore_errors: options[:keep_going])
39
38
 
40
39
  versions = Array.new
41
40
  if (config_selected && options[:config] != false) || user_selection.empty?
42
- versions += ops.snapshot_package_sets(nil, local: options[:local])
41
+ versions += ops.snapshot_package_sets(nil, only_local: options[:only_local])
43
42
  end
44
43
  if (!config_selected && !options[:config]) || !user_selection.empty?
45
- versions += ops.snapshot_packages(packages, nil, local: options[:local])
44
+ versions += ops.snapshot_packages(packages, nil, only_local: options[:only_local])
46
45
  end
47
46
 
48
47
  if output_file = options[:save]
@@ -207,15 +207,36 @@ def parallel_import_level=(level)
207
207
  end
208
208
 
209
209
  def private_bundler?
210
- get('private_bundler', false)
210
+ !!get('private_bundler', false)
211
+ end
212
+
213
+ def bundler_gem_home
214
+ get('private_bundler', Gem.user_dir)
211
215
  end
212
216
 
213
217
  def private_autoproj?
214
- get('private_autoproj', false)
218
+ !!get('private_autoproj', false)
219
+ end
220
+
221
+ def autoproj_gem_home
222
+ get('private_autoproj', Gem.user_dir)
215
223
  end
216
224
 
217
225
  def private_gems?
218
- get('private_gems', false)
226
+ !!get('private_gems', false)
227
+ end
228
+
229
+ def gems_gem_home
230
+ value = get('private_gems', false)
231
+ if value.respond_to?(:to_str)
232
+ return value
233
+ elsif value
234
+ default = File.join(ws.prefix_dir, 'gems')
235
+ set('private_gems', default)
236
+ default
237
+ else
238
+ Gem.user_dir
239
+ end
219
240
  end
220
241
 
221
242
  def ruby_executable
@@ -229,13 +250,15 @@ def ruby_executable
229
250
  end
230
251
 
231
252
  def validate_ruby_executable
253
+ actual = OSPackageResolver.autodetect_ruby_program
232
254
  if has_value_for?('ruby_executable')
233
255
  expected = get('ruby_executable')
234
- if expected != ruby_executable
235
- raise ConfigError.new, "this autoproj installation was bootstrapped using #{expected}, but you are currently running under #{ruby_executable}. This is usually caused by calling a wrong gem program (for instance, gem1.8 instead of gem1.9.1)"
256
+ if expected != actual
257
+ raise ConfigError.new, "this autoproj installation was bootstrapped using #{expected}, but you are currently running under #{actual}. This is usually caused by manually calling a wrong gem program (for instance, gem2.1 instead of gem2.0)"
236
258
  end
259
+ else
260
+ set('ruby_executable', actual, true)
237
261
  end
238
- set('ruby_executable', ruby_executable, true)
239
262
  end
240
263
 
241
264
  def use_prerelease?
@@ -441,4 +464,3 @@ def prefer_indep_over_os_packages?
441
464
  end
442
465
  end
443
466
  end
444
-
@@ -207,6 +207,7 @@ pip:
207
207
  freebsd: pip
208
208
 
209
209
  sudo:
210
+ macos-brew: ignore
210
211
  default: sudo
211
212
 
212
213
  # vim: expandtab
@@ -225,6 +225,9 @@ def load_and_update_package_sets(root_pkg_set, options = Hash.new)
225
225
  by_repository_id = Hash.new
226
226
  by_name = Hash.new
227
227
 
228
+ required_remotes_dirs = Array.new
229
+ required_user_dirs = Array.new
230
+
228
231
  queue = queue_auto_imports_if_needed(Array.new, root_pkg_set, root_pkg_set)
229
232
  while !queue.empty?
230
233
  vcs, import_options, imported_from = queue.shift
@@ -243,17 +246,30 @@ def load_and_update_package_sets(root_pkg_set, options = Hash.new)
243
246
  end
244
247
  by_repository_id[repository_id] = [vcs, imported_from]
245
248
 
249
+ # Make sure the package set has been already checked out to
250
+ # retrieve the actual name of the package set
246
251
  if !vcs.local?
247
252
  update_remote_package_set(vcs, options)
248
253
  create_remote_set_user_dir(vcs)
254
+ raw_local_dir = PackageSet.raw_local_dir_of(vcs)
255
+ required_remotes_dirs << raw_local_dir
249
256
  end
250
257
 
251
258
  name = PackageSet.name_of(ws.manifest, vcs)
259
+
260
+ required_user_dirs = by_name.collect { |k,v| k }
261
+ Autoproj.debug "Trying to load package_set: #{name} from definition #{repository_id}"
262
+ Autoproj.debug "Already loaded package_sets are: #{required_user_dirs}"
263
+
252
264
  if already_loaded = by_name[name]
253
265
  already_loaded_pkg_set, already_loaded_vcs = *already_loaded
254
266
  if already_loaded_vcs != vcs
255
267
  if imported_from
256
- Autoproj.warn "#{imported_from.name} auto-imports a package set from #{vcs}, but a package set with the same name (#{name}) has already been imported from #{already_loaded_vcs}, I am skipping this one"
268
+ Autoproj.warn "redundant auto-import by #{imported_from.name} for package set '#{name}'."
269
+ Autoproj.warn " A package set with the same name (#{name}) has already been imported from"
270
+ Autoproj.warn " #{already_loaded_vcs}"
271
+ Autoproj.warn " Skipping the following one: "
272
+ Autoproj.warn " #{vcs}"
257
273
  else
258
274
  Autoproj.warn "the manifest refers to a package set from #{vcs}, but a package set with the same name (#{name}) has already been imported from #{already_loaded_vcs}, I am skipping this one"
259
275
  end
@@ -264,6 +280,8 @@ def load_and_update_package_sets(root_pkg_set, options = Hash.new)
264
280
  imported_from.imports << already_loaded_pkg_set
265
281
  end
266
282
  next
283
+ else
284
+ create_remote_set_user_dir(vcs)
267
285
  end
268
286
 
269
287
  pkg_set = load_package_set(vcs, import_options, imported_from)
@@ -276,18 +294,20 @@ def load_and_update_package_sets(root_pkg_set, options = Hash.new)
276
294
  queue_auto_imports_if_needed(queue, pkg_set, root_pkg_set)
277
295
  end
278
296
 
279
- cleanup_remotes_dir(package_sets)
280
- cleanup_remotes_user_dir(package_sets)
297
+ cleanup_remotes_dir(package_sets, required_remotes_dirs)
298
+ cleanup_remotes_user_dir(package_sets, required_user_dirs)
281
299
  package_sets
282
300
  end
283
301
 
284
302
  # Removes from {remotes_dir} the directories that do not match a package
285
303
  # set
286
- def cleanup_remotes_dir(package_sets = ws.manifest.package_sets)
304
+ def cleanup_remotes_dir(package_sets = ws.manifest.package_sets, required_remotes_dirs = Array.new)
287
305
  # Cleanup the .remotes and remotes_symlinks_dir directories
288
306
  Dir.glob(File.join(remotes_dir, '*')).each do |dir|
289
307
  dir = File.expand_path(dir)
290
- if File.directory?(dir) && !package_sets.find { |pkg| pkg.raw_local_dir == dir }
308
+ # Once a package set has been checked out during the process,
309
+ # keep it -- so that it won't be checked out again
310
+ if File.directory?(dir) && !required_remotes_dirs.include?(dir)
291
311
  FileUtils.rm_rf dir
292
312
  end
293
313
  end
@@ -295,10 +315,11 @@ def cleanup_remotes_dir(package_sets = ws.manifest.package_sets)
295
315
 
296
316
  # Removes from {remotes_user_dir} the directories that do not match a
297
317
  # package set
298
- def cleanup_remotes_user_dir(package_sets = ws.manifest.package_sets)
318
+ def cleanup_remotes_user_dir(package_sets = ws.manifest.package_sets, required_user_dirs = Array.new)
299
319
  Dir.glob(File.join(remotes_user_dir, '*')).each do |file|
300
320
  file = File.expand_path(file)
301
- if File.symlink?(file) && !package_sets.find { |pkg_set| pkg_set.user_local_dir == file }
321
+ user_dir = File.basename(file)
322
+ if File.symlink?(file) && !required_user_dirs.include?(user_dir)
302
323
  FileUtils.rm_f file
303
324
  end
304
325
  end
@@ -30,20 +30,15 @@ def initialize(root_dir)
30
30
  @gemfile = default_gemfile_contents
31
31
  end
32
32
 
33
- load_config
34
- @local = false
35
- @env = self.class.clean_env
36
- end
37
-
38
- def self.clean_env
39
- env = Hash.new
33
+ @env = Hash.new
40
34
  env['RUBYLIB'] = []
41
35
  env['GEM_PATH'] = []
42
- %w{PATH GEM_HOME}.each do |name|
43
- env[name] = sanitize_env(ENV[name] || "")
44
- end
36
+ env['GEM_HOME'] = []
37
+ env['PATH'] = self.class.sanitize_env(ENV['PATH'] || "")
45
38
  env['BUNDLE_GEMFILE'] = []
46
- env
39
+
40
+ load_config
41
+ @local = false
47
42
  end
48
43
 
49
44
  def env_for_child
@@ -81,7 +76,7 @@ def self.in_workspace?(base_dir)
81
76
 
82
77
 
83
78
  def dot_autoproj; File.join(root_dir, '.autoproj') end
84
- def bundler_install_dir; File.join(dot_autoproj, 'bundler') end
79
+
85
80
  def autoproj_install_dir; File.join(dot_autoproj, 'autoproj') end
86
81
  # The path to the gemfile used to install autoproj
87
82
  def autoproj_gemfile_path; File.join(autoproj_install_dir, 'Gemfile') end
@@ -93,18 +88,47 @@ def local?; !!@local end
93
88
  def local=(flag); @local = flag end
94
89
 
95
90
  # Whether bundler should be installed locally in {#dot_autoproj}
96
- def private_bundler?; @private_bundler end
91
+ def private_bundler?; !!@private_bundler end
92
+ # The path to the directory into which the bundler gem should be
93
+ # installed
94
+ def bundler_gem_home; @private_bundler || gem_bindir end
97
95
  # (see #private_bundler?)
98
- def private_bundler=(flag); @private_bundler = !!flag end
96
+ def private_bundler=(flag)
97
+ @private_bundler =
98
+ if flag.respond_to?(:to_str) then File.expand_path(flag)
99
+ elsif flag
100
+ File.join(dot_autoproj, 'bundler')
101
+ end
102
+ end
103
+
99
104
  # Whether autoproj should be installed locally in {#dot_autoproj}
100
- def private_autoproj?; @private_autoproj end
105
+ def private_autoproj?; !!@private_autoproj end
106
+ # The path to the directory into which the autoproj gem should be
107
+ # installed
108
+ def autoproj_gem_home; @private_autoproj || gem_bindir end
101
109
  # (see #private_autoproj?)
102
- def private_autoproj=(flag); @private_autoproj = !!flag end
103
- # Whether bundler should be installed locally in the workspace
104
- # prefix directory
105
- def private_gems?; @private_gems end
110
+ def private_autoproj=(flag)
111
+ @private_autoproj =
112
+ if flag.respond_to?(:to_str) then File.expand_path(flag)
113
+ elsif flag
114
+ File.join(dot_autoproj, 'autoproj')
115
+ end
116
+ end
117
+
118
+ # Whether autoproj should be installed locally in {#dot_autoproj}
119
+ #
120
+ # Unlike for {#private_autoproj?} and {#private_bundler?}, there is
121
+ # no default path to save the gems as we don't yet know the path to
122
+ # the prefix directory
123
+ def private_gems?; !!@private_gems end
106
124
  # (see #private_gems?)
107
- def private_gems=(flag); @private_gems = !!flag end
125
+ def private_gems=(value)
126
+ @private_gems =
127
+ if value.respond_to?(:to_str) then File.expand_path(value)
128
+ else value
129
+ end
130
+ end
131
+
108
132
  # Whether autoproj should prefer OS-independent packages over their
109
133
  # OS-packaged equivalents (e.g. the thor gem vs. the ruby-thor
110
134
  # Debian package)
@@ -146,19 +170,19 @@ def parse_options(args = ARGV)
146
170
  opt.on '--local', 'do not access the network (may fail)' do
147
171
  @local = true
148
172
  end
149
- opt.on '--private-bundler', 'install bundler locally in the workspace' do
150
- @private_bundler = true
173
+ opt.on '--private-bundler[=PATH]', 'install bundler locally in the workspace' do |path|
174
+ self.private_bundler = path || true
151
175
  end
152
- opt.on '--private-autoproj', 'install autoproj locally in the workspace' do
153
- @private_autoproj = true
176
+ opt.on '--private-autoproj[=PATH]', 'install autoproj locally in the workspace' do |path|
177
+ self.private_autoproj = path || true
154
178
  end
155
- opt.on '--private-gems', 'install gems locally in the prefix directory' do
156
- @private_gems = true
179
+ opt.on '--private-gems[=PATH]', 'install gems locally in the prefix directory' do |path|
180
+ self.private_gems = path || true
157
181
  end
158
- opt.on '--private', 'whether bundler, autoproj and the workspace gems should be installed locally in the workspace' do
159
- @private_bundler = true
160
- @private_autoproj = true
161
- @private_gems = true
182
+ opt.on '--private[=PATH]', 'whether bundler, autoproj and the workspace gems should be installed locally in the workspace' do |path|
183
+ self.private_bundler = path || true
184
+ self.private_autoproj = path || true
185
+ self.private_gems = path || true
162
186
  end
163
187
  opt.on '--version=VERSION_CONSTRAINT', String, 'use the provided string as a version constraint for autoproj' do |version|
164
188
  @gemfile = default_gemfile_contents(version)
@@ -180,54 +204,51 @@ def install_bundler
180
204
  local = ['--local'] if local?
181
205
 
182
206
  result = system(
183
- env_for_child.merge('GEM_PATH' => nil, 'GEM_HOME' => bundler_install_dir),
184
- gem_program, 'install', '--no-document', '--no-user-install', '--no-format-executable',
207
+ env_for_child.merge('GEM_PATH' => "", 'GEM_HOME' => bundler_gem_home),
208
+ gem_program, 'install', '--no-document', '--no-format-executable',
185
209
  *local,
186
- "--bindir=#{File.join(bundler_install_dir, 'bin')}", 'bundler')
210
+ "--bindir=#{File.join(bundler_gem_home, 'bin')}", 'bundler')
187
211
 
188
212
  if !result
189
213
  STDERR.puts "FATAL: failed to install bundler in #{dot_autoproj}"
190
214
  exit 1
191
215
  end
192
- env['PATH'].unshift File.join(bundler_install_dir, 'bin')
193
- File.join(bundler_install_dir, 'bin', 'bundler')
216
+ File.join(bundler_gem_home, 'bin', 'bundler')
194
217
  end
195
218
 
196
219
  def find_bundler
197
- self.env['PATH'].unshift gem_bindir
198
220
  clean_env = env_for_child
199
- Gem.paths = Hash[
200
- 'GEM_HOME' => clean_env['GEM_HOME'] || Gem.default_dir,
201
- 'GEM_PATH' => clean_env['GEM_PATH'] || nil
202
- ]
203
-
204
- bundler = find_in_clean_path('bundler')
205
- if !bundler
206
- clean_path = env_for_child['PATH']
207
- STDERR.puts "cannot find 'bundler' in PATH=#{clean_path}"
208
- STDERR.puts "installing it now ..."
209
- result = system(clean_env, Gem.ruby, '-S', 'gem', 'install', 'bundler')
210
- if !result
211
- if ENV['PATH'] != clean_path
212
- STDERR.puts " it appears that you already have some autoproj-generated env.sh loaded"
213
- STDERR.puts " - if you are running 'autoproj upgrade', please contact the autoproj author at https://github.com/rock-core/autoproj/issues/new"
214
- STDERR.puts " - if you are running an install, try again in a console where the env.sh is not loaded"
215
- exit 1
216
- else
217
- STDERR.puts " the recommended action is to install it manually first by running 'gem install bundler'"
218
- STDERR.puts " or call this command again with --private-bundler to have it installed in the workspace"
219
- exit 1
220
- end
221
- end
221
+ if bundler = find_in_clean_path('bundler', gem_bindir)
222
+ return bundler
223
+ end
224
+
225
+ clean_path = env_for_child['PATH']
226
+ STDERR.puts "cannot find 'bundler' in PATH=#{clean_path}#{File::PATH_SEPARATOR}#{gem_bindir}"
227
+ STDERR.puts "installing it now ..."
228
+ result = system(
229
+ clean_env.merge('GEM_PATH' => "", 'GEM_HOME' => bundler_gem_path),
230
+ Gem.ruby, '-S', 'gem', 'install', 'bundler')
222
231
 
223
- bundler = find_in_clean_path('bundler')
224
- if !bundler
225
- STDERR.puts "FATAL: gem install bundler returned successfully, but still cannot find bundler"
226
- STDERR.puts "FATAL: in #{clean_path}"
232
+ if !result
233
+ if ENV['PATH'] != clean_path
234
+ STDERR.puts " it appears that you already have some autoproj-generated env.sh loaded"
235
+ STDERR.puts " - if you are running 'autoproj upgrade', please contact the autoproj author at https://github.com/rock-core/autoproj/issues/new"
236
+ STDERR.puts " - if you are running an install, try again in a console where the env.sh is not loaded"
237
+ exit 1
238
+ else
239
+ STDERR.puts " the recommended action is to install it manually first by running 'gem install bundler'"
240
+ STDERR.puts " or call this command again with --private-bundler to have it installed in the workspace"
241
+ exit 1
227
242
  end
228
243
  end
229
244
 
230
- bundler
245
+ bundler = File.join(bundler_gem_path, 'bin', 'bundler')
246
+ if File.exist?(bundler)
247
+ bundler
248
+ else
249
+ STDERR.puts "gem install bundler returned successfully, but still cannot find bundler in #{bundler}"
250
+ nil
251
+ end
231
252
  end
232
253
 
233
254
  def install_autoproj(bundler)
@@ -238,17 +259,17 @@ def install_autoproj(bundler)
238
259
  FileUtils.rm lockfile
239
260
  end
240
261
 
241
- opts = Array.new
242
- clean_env = env_for_child.merge('BUNDLE_GEMFILE' => nil)
262
+ clean_env = env_for_child.dup
243
263
 
264
+ opts = Array.new
244
265
  opts << '--local' if local?
245
266
  if private_autoproj?
246
- clean_env['GEM_PATH'] = (bundler_install_dir if private_bundler?)
267
+ clean_env['GEM_PATH'] = bundler_gem_home
247
268
  clean_env['GEM_HOME'] = nil
248
- opts << "--clean" << "--path=#{autoproj_install_dir}"
269
+ opts << "--clean" << "--path=#{autoproj_gem_home}"
249
270
  end
250
271
  binstubs_path = File.join(autoproj_install_dir, 'bin')
251
- result = system(clean_env,
272
+ result = system(clean_env.merge('GEM_HOME' => autoproj_gem_home),
252
273
  Gem.ruby, bundler, 'install',
253
274
  "--gemfile=#{autoproj_gemfile_path}",
254
275
  "--shebang=#{Gem.ruby}",
@@ -259,6 +280,17 @@ def install_autoproj(bundler)
259
280
  STDERR.puts "FATAL: failed to install autoproj in #{dot_autoproj}"
260
281
  exit 1
261
282
  end
283
+ ensure
284
+ self.class.clean_binstubs(binstubs_path)
285
+ end
286
+
287
+ def self.clean_binstubs(binstubs_path)
288
+ %w{bundler bundle}.each do |bundler_bin|
289
+ path = File.join(binstubs_path, bundler_bin)
290
+ if File.file?(path)
291
+ FileUtils.rm path
292
+ end
293
+ end
262
294
 
263
295
  # Now tune the binstubs to force the usage of the autoproj
264
296
  # gemfile. Otherwise, they get BUNDLE_GEMFILE from the
@@ -279,15 +311,6 @@ def install_autoproj(bundler)
279
311
  io.write filtered.join("")
280
312
  end
281
313
  end
282
-
283
- env['PATH'].unshift File.join(autoproj_install_dir, 'bin')
284
- if private_autoproj?
285
- env['GEM_PATH'].unshift autoproj_install_dir
286
- end
287
- ensure
288
- if binstubs_path
289
- FileUtils.rm_f File.join(binstubs_path, 'bundler')
290
- end
291
314
  end
292
315
 
293
316
  def save_env_sh(*vars)
@@ -327,8 +350,8 @@ def save_gemfile
327
350
  ENV_BUNDLE_GEMFILE_RX = /^(\s*ENV\[['"]BUNDLE_GEMFILE['"]\]\s*)(?:\|\|)?=/
328
351
 
329
352
 
330
- def find_in_clean_path(command)
331
- clean_path = env_for_child['PATH'].split(File::PATH_SEPARATOR)
353
+ def find_in_clean_path(command, *additional_paths)
354
+ clean_path = env_for_child['PATH'].split(File::PATH_SEPARATOR) + additional_paths
332
355
  clean_path.each do |p|
333
356
  full_path = File.join(p, command)
334
357
  if File.file?(full_path)
@@ -352,7 +375,7 @@ def gem_bindir
352
375
  #
353
376
  # So, we're calling 'gem' as a subcommand to discovery the
354
377
  # actual bindir
355
- bindir = IO.popen(env_for_child, [Gem.ruby, '-e', 'puts Gem.bindir']).read
378
+ bindir = IO.popen(env_for_child, [Gem.ruby, '-e', 'puts "#{Gem.user_dir}/bin"']).read
356
379
  if bindir
357
380
  @gem_bindir = bindir.chomp
358
381
  else
@@ -362,11 +385,12 @@ def gem_bindir
362
385
 
363
386
  def install
364
387
  if private_bundler?
365
- puts "Installing bundler in #{bundler_install_dir}"
388
+ puts "Installing bundler in #{bundler_gem_home}"
366
389
  bundler = install_bundler
367
- else
368
- bundler = find_bundler
390
+ elsif bundler = find_bundler
369
391
  puts "Detected bundler at #{bundler}"
392
+ else
393
+ exit 1
370
394
  end
371
395
  save_gemfile
372
396
  puts "Installing autoproj in #{dot_autoproj}"
@@ -384,6 +408,17 @@ def load_config
384
408
  config.merge!(YAML.load(File.read(autoproj_config_path)))
385
409
  end
386
410
 
411
+ ruby = RbConfig::CONFIG['RUBY_INSTALL_NAME']
412
+ ruby_bindir = RbConfig::CONFIG['bindir']
413
+ ruby_executable = File.join(ruby_bindir, ruby)
414
+ if current = config['ruby_executable'] # When upgrading or reinstalling
415
+ if current != ruby_executable
416
+ raise "this workspace has already been initialized using #{current}, you cannot run autoproj install with #{ruby_executable}. If you know what you're doing, delete the ruby_executable line in config.yml and try again"
417
+ end
418
+ else
419
+ config['ruby_executable'] = ruby_executable
420
+ end
421
+
387
422
  @config = config
388
423
  %w{private_bundler private_gems private_autoproj prefer_indep_over_os_packages}.each do |flag|
389
424
  instance_variable_set "@#{flag}", config.fetch(flag, false)
@@ -391,25 +426,33 @@ def load_config
391
426
  end
392
427
 
393
428
  def save_config
394
- config['private_bundler'] = private_bundler?
395
- config['private_autoproj'] = private_autoproj?
396
- config['private_gems'] = private_gems?
429
+ config['private_bundler'] = (bundler_gem_home if private_bundler?)
430
+ config['private_autoproj'] = (autoproj_gem_home if private_autoproj?)
431
+ config['private_gems'] = @private_gems
397
432
  config['prefer_indep_over_os_packages'] = prefer_indep_over_os_packages?
398
433
  File.open(autoproj_config_path, 'w') { |io| YAML.dump(config, io) }
399
434
  end
400
435
 
436
+ def autoproj_path
437
+ File.join(autoproj_install_dir, 'bin', 'autoproj')
438
+ end
439
+
440
+ def run_autoproj(*args)
441
+ system env_for_child.merge('BUNDLE_GEMFILE' => autoproj_gemfile_path),
442
+ Gem.ruby, autoproj_path, *args
443
+ end
444
+
401
445
  def stage1
402
446
  FileUtils.mkdir_p dot_autoproj
403
447
  save_config
404
448
  install
449
+ end
405
450
 
451
+ def call_stage2
406
452
  clean_env = env_for_child
407
453
  stage2_vars = clean_env.map { |k, v| "#{k}=#{v}" }
408
454
  puts "starting the newly installed autoproj for stage2 install"
409
- result = system clean_env.merge('BUNDLE_GEMFILE' => autoproj_gemfile_path),
410
- Gem.ruby, File.join(autoproj_install_dir, 'bin', 'autoproj'),
411
- 'install-stage2', root_dir, *stage2_vars
412
- if !result
455
+ if !run_autoproj('install-stage2', root_dir, *stage2_vars)
413
456
  raise "failed to execute autoproj install-stage2"
414
457
  end
415
458
  end
@@ -419,7 +462,7 @@ def stage2(*vars)
419
462
  puts "saving env.sh and .autoproj/env.sh"
420
463
  save_env_sh(*vars)
421
464
  puts "calling autoproj envsh"
422
- system(Gem.ruby, $0, 'envsh')
465
+ system(Gem.ruby, autoproj_path, 'envsh')
423
466
  end
424
467
  end
425
468
  end