autoproj 2.15.0 → 2.15.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e37a5cc9f8c9ada28c0adbf2fed26100734010c4076251e49efdcacc55692a8f
4
- data.tar.gz: e0d14e06bd7531fa0e572f1af4a85d805480a50457cce7e433c3d6f54331c546
3
+ metadata.gz: 79dfca26614ef3c2b0491b7c91979986dd94e3c74ae0a15bc4a3b6729c0d0bd4
4
+ data.tar.gz: 425261fdab1ec54880133f874a357a1b4adb0a247d08c421da02dde615e4c1b4
5
5
  SHA512:
6
- metadata.gz: 1b8194f91586c641f6ea957791a8511d94eac07b454a45a77ac67e085bd3a96251ba87193dd0410709863d97db4fde959911c1e3911b86d49e5cfb3808cbcd94
7
- data.tar.gz: 2d05c7b38d65095aac4183967c036e86dc596d765e5a236cad7af5b19e8d6d56188d6da42a227b6aa4080ea71356ac70521cbc86ef10a27fe6682c9f0a80b46b
6
+ metadata.gz: 2e46b35e75abf68b4cf1643ffe96b915179b3a2e59862c95248ed64ae8eb1d54ae892ea7dd006db87f7722a065f24512e26435e0f848458d23e67f12a41f7165
7
+ data.tar.gz: 371003014229e5023749734b108bf4484059ad3fd0e73f9b7dfcf6cabe426d709b8d2aca75415b10687354eae17eebf9c6b6835006c505f40a1093983217084d
data/autoproj.gemspec CHANGED
@@ -29,7 +29,9 @@ Gem::Specification.new do |s|
29
29
  s.add_runtime_dependency "backports", "~> 3.0"
30
30
  s.add_runtime_dependency "bundler"
31
31
  s.add_runtime_dependency "concurrent-ruby", "~> 1.1"
32
+ s.add_runtime_dependency "parslet"
32
33
  s.add_runtime_dependency "rb-inotify" if RbConfig::CONFIG["target_os"] =~ /linux/
34
+ s.add_runtime_dependency "rgl", "~> 0.5.7"
33
35
  s.add_runtime_dependency "thor", "~> 1.0"
34
36
  s.add_runtime_dependency "tty-color", "~> 0.5.0"
35
37
  s.add_runtime_dependency "tty-prompt", "~> 0.21.0"
@@ -172,16 +172,23 @@ module Autoproj
172
172
  attr_writer :local
173
173
 
174
174
  # The user-wide place where RubyGems installs gems
175
- def dot_gem_dir
176
- File.join(Gem.user_home, ".gem")
175
+ def self.dot_gem_dir
176
+ if Gem.respond_to?(:data_home) # Debian 11+
177
+ File.join(Gem.data_home, "gem")
178
+ else
179
+ File.join(Gem.user_home, ".gem")
180
+ end
177
181
  end
178
182
 
179
183
  # The version and platform-specific suffix under {#dot_gem_dir}
180
184
  #
181
185
  # This is also the suffix used by bundler to install gems
182
- def gem_path_suffix
183
- @gem_path_suffix ||= Pathname.new(Gem.user_dir)
184
- .relative_path_from(Pathname.new(dot_gem_dir)).to_s
186
+ def self.gems_path_suffix
187
+ @gems_path_suffix ||=
188
+ Pathname
189
+ .new(Gem.user_dir)
190
+ .relative_path_from(Pathname.new(dot_gem_dir))
191
+ .to_s
185
192
  end
186
193
 
187
194
  # The path into which the workspace's gems should be installed
@@ -196,13 +203,13 @@ module Autoproj
196
203
  #
197
204
  # @return [String]
198
205
  def gems_gem_home
199
- File.join(gems_install_path, gem_path_suffix)
206
+ File.join(gems_install_path, self.class.gems_path_suffix)
200
207
  end
201
208
  # Sets where the workspace's gems should be installed
202
209
  #
203
210
  # @param [String] path the absolute path that should be given to
204
211
  # bundler. The gems themselves will be installed in the
205
- # {#gem_path_suffix} subdirectory under this
212
+ # {.gems_path_suffix} subdirectory under this
206
213
 
207
214
  private def xdg_var(varname, default)
208
215
  if (env = ENV[varname]) && !env.empty?
@@ -439,32 +446,42 @@ module Autoproj
439
446
  lockfile = File.join(dot_autoproj, "Gemfile.lock")
440
447
  FileUtils.rm lockfile if File.exist?(lockfile)
441
448
 
442
- clean_env = env_for_child.dup
449
+ run_bundler(bundler, "config", "set", "--local", "path", gems_install_path,
450
+ bundler_version: bundler_version)
451
+ run_bundler(bundler, "config", "set", "--local", "shebang", Gem.ruby,
452
+ bundler_version: bundler_version)
453
+
454
+ install_args = ["--gemfile=#{autoproj_gemfile_path}"]
455
+ install_args << "--local" if local?
456
+ run_bundler(bundler, "install", *install_args,
457
+ bundler_version: bundler_version)
443
458
 
444
- opts = Array.new
445
- opts << "--local" if local?
446
- opts << "--path=#{gems_install_path}"
447
459
  shims_path = File.join(dot_autoproj, "bin")
460
+ run_bundler(bundler, "binstubs", "--all", "--force", "--path", shims_path,
461
+ bundler_version: bundler_version)
462
+ self.class.rewrite_shims(
463
+ shims_path, ruby_executable, root_dir,
464
+ autoproj_gemfile_path, gems_gem_home
465
+ )
466
+ end
467
+
468
+ class BundlerFailed < RuntimeError; end
469
+
470
+ def run_bundler(bundler, *args, bundler_version: self.bundler_version)
471
+ clean_env = env_for_child.dup
448
472
 
449
473
  version_arg = []
450
474
  version_arg << "_#{bundler_version}_" if bundler_version
451
475
 
452
476
  result = system(
453
- clean_env,
454
- Gem.ruby, bundler, *version_arg, "install",
455
- "--gemfile=#{autoproj_gemfile_path}",
456
- "--shebang=#{Gem.ruby}",
457
- "--binstubs=#{shims_path}",
458
- *opts, chdir: dot_autoproj
477
+ clean_env, Gem.ruby, bundler, *version_arg,
478
+ *args, chdir: dot_autoproj
459
479
  )
460
480
 
461
481
  unless result
462
- STDERR.puts "FATAL: failed to install autoproj in #{dot_autoproj}"
463
- exit 1
482
+ raise BundlerFailed,
483
+ "FAILED: bundler #{args.join(', ')} in #{dot_autoproj}"
464
484
  end
465
- ensure
466
- self.class.rewrite_shims(shims_path, ruby_executable,
467
- root_dir, autoproj_gemfile_path, gems_gem_home)
468
485
  end
469
486
 
470
487
  EXCLUDED_FROM_SHIMS = %w[rake thor].freeze
@@ -491,6 +508,7 @@ module Autoproj
491
508
  bin_shim = File.join(shim_path, bin_name)
492
509
  bin_script_lines = File.readlines(bin_script)
493
510
  next if has_autoproj_preamble?(bin_script_lines)
511
+ next unless ruby_script?(bin_script_lines)
494
512
 
495
513
  File.open(bin_shim, "w") do |io|
496
514
  if bin_name == "bundler" || bin_name == "bundle"
@@ -505,6 +523,10 @@ module Autoproj
505
523
  end
506
524
  end
507
525
 
526
+ def self.ruby_script?(script_lines)
527
+ script_lines.first =~ /\#\s*!(.*ruby.*)/
528
+ end
529
+
508
530
  def self.new_style_bundler_binstub?(script_lines)
509
531
  script_lines.any? { |l| l =~ /This file was generated by Bundler/ }
510
532
  end
data/bin/autoproj_install CHANGED
@@ -172,16 +172,23 @@ module Autoproj
172
172
  attr_writer :local
173
173
 
174
174
  # The user-wide place where RubyGems installs gems
175
- def dot_gem_dir
176
- File.join(Gem.user_home, ".gem")
175
+ def self.dot_gem_dir
176
+ if Gem.respond_to?(:data_home) # Debian 11+
177
+ File.join(Gem.data_home, "gem")
178
+ else
179
+ File.join(Gem.user_home, ".gem")
180
+ end
177
181
  end
178
182
 
179
183
  # The version and platform-specific suffix under {#dot_gem_dir}
180
184
  #
181
185
  # This is also the suffix used by bundler to install gems
182
- def gem_path_suffix
183
- @gem_path_suffix ||= Pathname.new(Gem.user_dir)
184
- .relative_path_from(Pathname.new(dot_gem_dir)).to_s
186
+ def self.gems_path_suffix
187
+ @gems_path_suffix ||=
188
+ Pathname
189
+ .new(Gem.user_dir)
190
+ .relative_path_from(Pathname.new(dot_gem_dir))
191
+ .to_s
185
192
  end
186
193
 
187
194
  # The path into which the workspace's gems should be installed
@@ -196,13 +203,13 @@ module Autoproj
196
203
  #
197
204
  # @return [String]
198
205
  def gems_gem_home
199
- File.join(gems_install_path, gem_path_suffix)
206
+ File.join(gems_install_path, self.class.gems_path_suffix)
200
207
  end
201
208
  # Sets where the workspace's gems should be installed
202
209
  #
203
210
  # @param [String] path the absolute path that should be given to
204
211
  # bundler. The gems themselves will be installed in the
205
- # {#gem_path_suffix} subdirectory under this
212
+ # {.gems_path_suffix} subdirectory under this
206
213
 
207
214
  private def xdg_var(varname, default)
208
215
  if (env = ENV[varname]) && !env.empty?
@@ -439,32 +446,42 @@ module Autoproj
439
446
  lockfile = File.join(dot_autoproj, "Gemfile.lock")
440
447
  FileUtils.rm lockfile if File.exist?(lockfile)
441
448
 
442
- clean_env = env_for_child.dup
449
+ run_bundler(bundler, "config", "set", "--local", "path", gems_install_path,
450
+ bundler_version: bundler_version)
451
+ run_bundler(bundler, "config", "set", "--local", "shebang", Gem.ruby,
452
+ bundler_version: bundler_version)
453
+
454
+ install_args = ["--gemfile=#{autoproj_gemfile_path}"]
455
+ install_args << "--local" if local?
456
+ run_bundler(bundler, "install", *install_args,
457
+ bundler_version: bundler_version)
443
458
 
444
- opts = Array.new
445
- opts << "--local" if local?
446
- opts << "--path=#{gems_install_path}"
447
459
  shims_path = File.join(dot_autoproj, "bin")
460
+ run_bundler(bundler, "binstubs", "--all", "--force", "--path", shims_path,
461
+ bundler_version: bundler_version)
462
+ self.class.rewrite_shims(
463
+ shims_path, ruby_executable, root_dir,
464
+ autoproj_gemfile_path, gems_gem_home
465
+ )
466
+ end
467
+
468
+ class BundlerFailed < RuntimeError; end
469
+
470
+ def run_bundler(bundler, *args, bundler_version: self.bundler_version)
471
+ clean_env = env_for_child.dup
448
472
 
449
473
  version_arg = []
450
474
  version_arg << "_#{bundler_version}_" if bundler_version
451
475
 
452
476
  result = system(
453
- clean_env,
454
- Gem.ruby, bundler, *version_arg, "install",
455
- "--gemfile=#{autoproj_gemfile_path}",
456
- "--shebang=#{Gem.ruby}",
457
- "--binstubs=#{shims_path}",
458
- *opts, chdir: dot_autoproj
477
+ clean_env, Gem.ruby, bundler, *version_arg,
478
+ *args, chdir: dot_autoproj
459
479
  )
460
480
 
461
481
  unless result
462
- STDERR.puts "FATAL: failed to install autoproj in #{dot_autoproj}"
463
- exit 1
482
+ raise BundlerFailed,
483
+ "FAILED: bundler #{args.join(', ')} in #{dot_autoproj}"
464
484
  end
465
- ensure
466
- self.class.rewrite_shims(shims_path, ruby_executable,
467
- root_dir, autoproj_gemfile_path, gems_gem_home)
468
485
  end
469
486
 
470
487
  EXCLUDED_FROM_SHIMS = %w[rake thor].freeze
@@ -491,6 +508,7 @@ module Autoproj
491
508
  bin_shim = File.join(shim_path, bin_name)
492
509
  bin_script_lines = File.readlines(bin_script)
493
510
  next if has_autoproj_preamble?(bin_script_lines)
511
+ next unless ruby_script?(bin_script_lines)
494
512
 
495
513
  File.open(bin_shim, "w") do |io|
496
514
  if bin_name == "bundler" || bin_name == "bundle"
@@ -505,6 +523,10 @@ module Autoproj
505
523
  end
506
524
  end
507
525
 
526
+ def self.ruby_script?(script_lines)
527
+ script_lines.first =~ /\#\s*!(.*ruby.*)/
528
+ end
529
+
508
530
  def self.new_style_bundler_binstub?(script_lines)
509
531
  script_lines.any? { |l| l =~ /This file was generated by Bundler/ }
510
532
  end
@@ -1,4 +1,5 @@
1
1
  require "autoproj/autobuild_extensions/package"
2
+ require "autoproj/autobuild_extensions/python"
2
3
  require "autoproj/autobuild_extensions/archive_importer"
3
4
  require "autoproj/autobuild_extensions/git"
4
5
  require "autoproj/autobuild_extensions/svn"
@@ -16,3 +17,6 @@ end
16
17
  Autobuild::SVN.class_eval do
17
18
  prepend Autoproj::AutobuildExtensions::SVN
18
19
  end
20
+ Autobuild::Python.class_eval do
21
+ prepend Autoproj::AutobuildExtensions::Python
22
+ end
@@ -20,6 +20,28 @@ module Autoproj
20
20
  end
21
21
  end
22
22
 
23
+ class << self
24
+ attr_writer :custom_package_handlers
25
+
26
+ def custom_package_handlers
27
+ @custom_package_handlers ||= []
28
+ end
29
+ end
30
+
31
+ def self.each_custom_package_handler(&block)
32
+ return enum_for(__method__) unless block_given?
33
+
34
+ custom_package_handlers.each do |handler|
35
+ block.call(handler)
36
+ end
37
+ end
38
+
39
+ # Registers a block that will be called to determine a package
40
+ # handler for the package in full_path.
41
+ def self.custom_package_handler(&block)
42
+ custom_package_handlers << block
43
+ end
44
+
23
45
  # @api private
24
46
  #
25
47
  # Helper method that extracts the package name from a Rake-style package
@@ -112,6 +134,10 @@ module Autoproj
112
134
 
113
135
  # Tries to find a handler automatically for 'full_path'
114
136
  def self.package_handler_for(full_path)
137
+ each_custom_package_handler do |handler|
138
+ pair = handler.call(full_path)
139
+ return pair if pair
140
+ end
115
141
  pyglob = File.join(File.basename(full_path), "*.py")
116
142
  if !Dir.enum_for(:glob, File.join(full_path, "*.orogen")).to_a.empty?
117
143
  ["orogen_package", full_path]
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Autoproj
4
+ module AutobuildExtensions
5
+ # Extension for Autobuild::Python
6
+ module Python
7
+ def activate_python
8
+ Autoproj::Python.setup_python_configuration_options(ws: ws)
9
+ Autoproj::Python.assert_python_activated(ws: ws)
10
+ end
11
+
12
+ def update_environment
13
+ activate_python
14
+ super
15
+ end
16
+ end
17
+ end
18
+ end
@@ -270,13 +270,12 @@ module Autoproj
270
270
 
271
271
  # The user-wide place where RubyGems installs gems
272
272
  def self.dot_gem_dir
273
- File.join(Gem.user_home, ".gem")
273
+ Ops::Install.dot_gem_dir
274
274
  end
275
275
 
276
276
  # The Ruby platform and version-specific subdirectory used by bundler and rubygem
277
277
  def self.gems_path_suffix
278
- @gems_path_suffix ||= Pathname.new(Gem.user_dir)
279
- .relative_path_from(Pathname.new(dot_gem_dir)).to_s
278
+ Ops::Install.gems_path_suffix
280
279
  end
281
280
 
282
281
  # The gem install root into which the workspace gems are installed
@@ -1,9 +1,54 @@
1
+ require "rgl/adjacency"
2
+ require "rgl/dot"
3
+ require "rgl/topsort"
4
+
1
5
  module Autoproj
2
6
  module Ops
3
7
  #--
4
8
  # NOTE: indentation is wrong to let git track the history properly
5
9
  #+++
6
10
 
11
+ # PackageSetHierachy be used to build the hierarchy of package set
12
+ # imports, as directed acyclic graph (DAG)
13
+ # so that they can be (topologically) sorted according to their
14
+ # dependencies
15
+ class PackageSetHierarchy
16
+ attr_reader :dag
17
+
18
+ def initialize(package_sets, root_pkg_set)
19
+ @dag = RGL::DirectedAdjacencyGraph.new
20
+
21
+ package_sets.each do |p|
22
+ p.imports.each do |dep|
23
+ @dag.add_edge dep, p
24
+ end
25
+ end
26
+
27
+ @dag.add_vertex root_pkg_set
28
+ import_order = root_pkg_set.imports.to_a
29
+ import_order.each_with_index do |p, index|
30
+ if index + 1 < import_order.size
31
+ @dag.add_edge p, import_order[index + 1]
32
+ @dag.add_edge p, root_pkg_set
33
+ end
34
+ end
35
+
36
+ unless @dag.acyclic?
37
+ raise "The package set hierarchy contains cycles: #{@dag.cycles}"
38
+ end
39
+ end
40
+
41
+ # Flatten the hierarchy, a establish a sorting
42
+ def flatten
43
+ @dag.topsort_iterator.to_a
44
+ end
45
+
46
+ # Write the hierarchy to an image (png) file
47
+ def to_png(path)
48
+ @dag.write_to_graphic_file("png", path.gsub(".png", ""))
49
+ end
50
+ end
51
+
7
52
  # Implementation of the operations to manage the configuration
8
53
  class Configuration
9
54
  attr_reader :ws
@@ -160,7 +205,6 @@ module Autoproj
160
205
  def load_package_set(vcs, options, imported_from)
161
206
  pkg_set = PackageSet.new(ws, vcs)
162
207
  pkg_set.auto_imports = options[:auto_imports]
163
- ws.load_if_present(pkg_set, pkg_set.local_dir, "init.rb")
164
208
  pkg_set.load_description_file
165
209
  if imported_from
166
210
  pkg_set.imported_from << imported_from
@@ -314,57 +358,19 @@ module Autoproj
314
358
  to_s
315
359
  end
316
360
 
361
+ # Sort the package sets by dependency order
362
+ # Package sets that have no dependencies come first,
363
+ # the local package set (by main configuration) last
317
364
  def sort_package_sets_by_import_order(package_sets, root_pkg_set)
318
- # The sorting is done in two steps:
319
- # - first, we build a topological order of the package sets
320
- # - then, we insert the auto-imported packages, following this
321
- # topological order, in the user-provided order. Each package is
322
- # considered in turn, and added at the earliest place that fits
323
- # the dependencies
324
- topological = Array.new
325
- queue = (package_sets.to_a + [root_pkg_set]).uniq
326
- until queue.empty?
327
- last_size = queue.size
328
- pending = queue.dup
329
- queue = Array.new
330
- until pending.empty?
331
- pkg_set = pending.shift
332
- if pkg_set.imports.any? { |imported_set| !topological.include?(imported_set) }
333
- queue.push(pkg_set)
334
- else
335
- topological << pkg_set
336
- end
337
- end
338
- if queue.size == last_size
339
- raise ArgumentError, "cannot resolve the dependencies between package sets. There seem to be a cycle amongst #{queue.map(&:name).sort.join(', ')}"
340
- end
341
- end
342
-
343
- result = root_pkg_set.imports.to_a.dup
344
- to_insert = topological.dup
345
- .find_all { |p| !result.include?(p) }
346
- until to_insert.empty?
347
- pkg_set = to_insert.shift
348
- dependencies = pkg_set.imports.dup
349
- if dependencies.empty?
350
- result.unshift(pkg_set)
351
- else
352
- i = result.find_index do |p|
353
- dependencies.delete(p)
354
- dependencies.empty?
355
- end
356
- result.insert(i + 1, pkg_set)
357
- end
358
- end
365
+ c = PackageSetHierarchy.new(package_sets, root_pkg_set)
366
+ sorted_pkg_sets = c.flatten
359
367
 
360
- # Sanity check related to the root package set
361
- # - it should be last
362
- # - it should be present only once
363
- if result.last != root_pkg_set
364
- raise InternalError, "failed to sort the package sets: the root package set should be last, but is not"
368
+ if sorted_pkg_sets.last != root_pkg_set
369
+ raise InternalError, "Failed to sort the package sets: the " \
370
+ "root package set should be last, but is not #{sorted_pkg_sets.map(&:name)}"
365
371
  end
366
372
 
367
- result
373
+ sorted_pkg_sets
368
374
  end
369
375
 
370
376
  def load_package_sets(
@@ -623,6 +629,7 @@ module Autoproj
623
629
  package_sets = sort_package_sets_by_import_order(package_sets, root_pkg_set)
624
630
  ws.manifest.reset_package_sets
625
631
  package_sets.each do |pkg_set|
632
+ ws.load_if_present(pkg_set, pkg_set.local_dir, "init.rb")
626
633
  ws.manifest.register_package_set(pkg_set)
627
634
  end
628
635
  failures
@@ -467,7 +467,9 @@ module Autoproj
467
467
 
468
468
  raise failures.first if !keep_going && !failures.empty?
469
469
 
470
- install_internal_dependencies_for(*all_processed_packages)
470
+ install_internal_dependencies_for(
471
+ *all_processed_packages, install_only: import_options[:checkout_only]
472
+ )
471
473
  finalize_package_load(all_processed_packages, auto_exclude: auto_exclude)
472
474
 
473
475
  all_enabled_osdeps = selection.each_osdep_package_name.to_set
@@ -162,16 +162,23 @@ module Autoproj
162
162
  attr_writer :local
163
163
 
164
164
  # The user-wide place where RubyGems installs gems
165
- def dot_gem_dir
166
- File.join(Gem.user_home, ".gem")
165
+ def self.dot_gem_dir
166
+ if Gem.respond_to?(:data_home) # Debian 11+
167
+ File.join(Gem.data_home, "gem")
168
+ else
169
+ File.join(Gem.user_home, ".gem")
170
+ end
167
171
  end
168
172
 
169
173
  # The version and platform-specific suffix under {#dot_gem_dir}
170
174
  #
171
175
  # This is also the suffix used by bundler to install gems
172
- def gem_path_suffix
173
- @gem_path_suffix ||= Pathname.new(Gem.user_dir)
174
- .relative_path_from(Pathname.new(dot_gem_dir)).to_s
176
+ def self.gems_path_suffix
177
+ @gems_path_suffix ||=
178
+ Pathname
179
+ .new(Gem.user_dir)
180
+ .relative_path_from(Pathname.new(dot_gem_dir))
181
+ .to_s
175
182
  end
176
183
 
177
184
  # The path into which the workspace's gems should be installed
@@ -186,13 +193,13 @@ module Autoproj
186
193
  #
187
194
  # @return [String]
188
195
  def gems_gem_home
189
- File.join(gems_install_path, gem_path_suffix)
196
+ File.join(gems_install_path, self.class.gems_path_suffix)
190
197
  end
191
198
  # Sets where the workspace's gems should be installed
192
199
  #
193
200
  # @param [String] path the absolute path that should be given to
194
201
  # bundler. The gems themselves will be installed in the
195
- # {#gem_path_suffix} subdirectory under this
202
+ # {.gems_path_suffix} subdirectory under this
196
203
 
197
204
  private def xdg_var(varname, default)
198
205
  if (env = ENV[varname]) && !env.empty?
@@ -429,32 +436,42 @@ module Autoproj
429
436
  lockfile = File.join(dot_autoproj, "Gemfile.lock")
430
437
  FileUtils.rm lockfile if File.exist?(lockfile)
431
438
 
432
- clean_env = env_for_child.dup
439
+ run_bundler(bundler, "config", "set", "--local", "path", gems_install_path,
440
+ bundler_version: bundler_version)
441
+ run_bundler(bundler, "config", "set", "--local", "shebang", Gem.ruby,
442
+ bundler_version: bundler_version)
443
+
444
+ install_args = ["--gemfile=#{autoproj_gemfile_path}"]
445
+ install_args << "--local" if local?
446
+ run_bundler(bundler, "install", *install_args,
447
+ bundler_version: bundler_version)
433
448
 
434
- opts = Array.new
435
- opts << "--local" if local?
436
- opts << "--path=#{gems_install_path}"
437
449
  shims_path = File.join(dot_autoproj, "bin")
450
+ run_bundler(bundler, "binstubs", "--all", "--force", "--path", shims_path,
451
+ bundler_version: bundler_version)
452
+ self.class.rewrite_shims(
453
+ shims_path, ruby_executable, root_dir,
454
+ autoproj_gemfile_path, gems_gem_home
455
+ )
456
+ end
457
+
458
+ class BundlerFailed < RuntimeError; end
459
+
460
+ def run_bundler(bundler, *args, bundler_version: self.bundler_version)
461
+ clean_env = env_for_child.dup
438
462
 
439
463
  version_arg = []
440
464
  version_arg << "_#{bundler_version}_" if bundler_version
441
465
 
442
466
  result = system(
443
- clean_env,
444
- Gem.ruby, bundler, *version_arg, "install",
445
- "--gemfile=#{autoproj_gemfile_path}",
446
- "--shebang=#{Gem.ruby}",
447
- "--binstubs=#{shims_path}",
448
- *opts, chdir: dot_autoproj
467
+ clean_env, Gem.ruby, bundler, *version_arg,
468
+ *args, chdir: dot_autoproj
449
469
  )
450
470
 
451
471
  unless result
452
- STDERR.puts "FATAL: failed to install autoproj in #{dot_autoproj}"
453
- exit 1
472
+ raise BundlerFailed,
473
+ "FAILED: bundler #{args.join(', ')} in #{dot_autoproj}"
454
474
  end
455
- ensure
456
- self.class.rewrite_shims(shims_path, ruby_executable,
457
- root_dir, autoproj_gemfile_path, gems_gem_home)
458
475
  end
459
476
 
460
477
  EXCLUDED_FROM_SHIMS = %w[rake thor].freeze
@@ -481,6 +498,7 @@ module Autoproj
481
498
  bin_shim = File.join(shim_path, bin_name)
482
499
  bin_script_lines = File.readlines(bin_script)
483
500
  next if has_autoproj_preamble?(bin_script_lines)
501
+ next unless ruby_script?(bin_script_lines)
484
502
 
485
503
  File.open(bin_shim, "w") do |io|
486
504
  if bin_name == "bundler" || bin_name == "bundle"
@@ -495,6 +513,10 @@ module Autoproj
495
513
  end
496
514
  end
497
515
 
516
+ def self.ruby_script?(script_lines)
517
+ script_lines.first =~ /\#\s*!(.*ruby.*)/
518
+ end
519
+
498
520
  def self.new_style_bundler_binstub?(script_lines)
499
521
  script_lines.any? { |l| l =~ /This file was generated by Bundler/ }
500
522
  end
@@ -9,6 +9,12 @@ module Autoproj
9
9
  class AptDpkgManager < ShellScriptManager
10
10
  attr_accessor :status_file
11
11
 
12
+ class << self
13
+ def inherit
14
+ @inherit ||= Set.new
15
+ end
16
+ end
17
+
12
18
  def initialize(ws, status_file = "/var/lib/dpkg/status")
13
19
  @status_file = status_file
14
20
  @installed_packages = nil
@@ -129,6 +135,7 @@ module Autoproj
129
135
  end
130
136
  end
131
137
 
138
+ # rubocop:disable Metrics/AbcSize
132
139
  def install(packages, filter_uptodate_packages: false, install_only: false)
133
140
  if filter_uptodate_packages || install_only
134
141
  already_installed, missing = packages.partition do |package_name|
@@ -144,12 +151,13 @@ module Autoproj
144
151
  packages = missing + (need_update || [])
145
152
  end
146
153
 
147
- if super(packages)
154
+ if super(packages, inherit: self.class.inherit)
148
155
  # Invalidate caching of installed packages, as we just
149
156
  # installed new packages !
150
157
  @installed_packages = nil
151
158
  end
152
159
  end
160
+ # rubocop:enable Metrics/AbcSize
153
161
  end
154
162
  end
155
163
  end