autoproj 2.15.0 → 2.15.1

Sign up to get free protection for your applications and to get access to all the features.
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