autoproj 2.10.1 → 2.13.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +5 -8
  3. data/.travis.yml +5 -3
  4. data/autoproj.gemspec +7 -6
  5. data/bin/alog +1 -0
  6. data/bin/autoproj +1 -1
  7. data/bin/autoproj_bootstrap +149 -86
  8. data/bin/autoproj_bootstrap.in +9 -7
  9. data/bin/autoproj_install +148 -82
  10. data/bin/autoproj_install.in +8 -3
  11. data/lib/autoproj.rb +3 -0
  12. data/lib/autoproj/aruba_minitest.rb +15 -0
  13. data/lib/autoproj/autobuild_extensions/dsl.rb +61 -27
  14. data/lib/autoproj/base.rb +35 -6
  15. data/lib/autoproj/cli/base.rb +1 -1
  16. data/lib/autoproj/cli/build.rb +9 -3
  17. data/lib/autoproj/cli/cache.rb +79 -7
  18. data/lib/autoproj/cli/doc.rb +4 -18
  19. data/lib/autoproj/cli/inspection_tool.rb +5 -6
  20. data/lib/autoproj/cli/main.rb +41 -18
  21. data/lib/autoproj/cli/main_doc.rb +86 -0
  22. data/lib/autoproj/cli/main_plugin.rb +3 -0
  23. data/lib/autoproj/cli/main_test.rb +15 -0
  24. data/lib/autoproj/cli/show.rb +12 -18
  25. data/lib/autoproj/cli/status.rb +15 -9
  26. data/lib/autoproj/cli/test.rb +13 -84
  27. data/lib/autoproj/cli/update.rb +77 -19
  28. data/lib/autoproj/cli/utility.rb +136 -0
  29. data/lib/autoproj/configuration.rb +28 -4
  30. data/lib/autoproj/default.osdeps +18 -0
  31. data/lib/autoproj/installation_manifest.rb +7 -5
  32. data/lib/autoproj/manifest.rb +15 -21
  33. data/lib/autoproj/ops/build.rb +23 -27
  34. data/lib/autoproj/ops/cache.rb +151 -33
  35. data/lib/autoproj/ops/cached_env.rb +2 -2
  36. data/lib/autoproj/ops/import.rb +146 -80
  37. data/lib/autoproj/ops/install.rb +140 -79
  38. data/lib/autoproj/ops/phase_reporting.rb +49 -0
  39. data/lib/autoproj/ops/snapshot.rb +2 -1
  40. data/lib/autoproj/ops/tools.rb +2 -2
  41. data/lib/autoproj/os_package_installer.rb +19 -11
  42. data/lib/autoproj/package_definition.rb +29 -10
  43. data/lib/autoproj/package_managers/apt_dpkg_manager.rb +49 -28
  44. data/lib/autoproj/package_managers/bundler_manager.rb +257 -87
  45. data/lib/autoproj/package_managers/homebrew_manager.rb +2 -2
  46. data/lib/autoproj/package_managers/shell_script_manager.rb +44 -24
  47. data/lib/autoproj/package_manifest.rb +49 -34
  48. data/lib/autoproj/package_set.rb +48 -29
  49. data/lib/autoproj/repository_managers/apt.rb +0 -1
  50. data/lib/autoproj/test.rb +29 -10
  51. data/lib/autoproj/variable_expansion.rb +3 -1
  52. data/lib/autoproj/vcs_definition.rb +30 -15
  53. data/lib/autoproj/version.rb +1 -1
  54. data/lib/autoproj/workspace.rb +55 -13
  55. metadata +32 -28
@@ -13,12 +13,14 @@ require 'autoproj/ops/install'
13
13
  ENV.delete('BUNDLE_GEMFILE')
14
14
  ENV.delete('RUBYLIB')
15
15
  ops = Autoproj::Ops::Install.new(Dir.pwd)
16
+
17
+ existing_config = File.join(Dir.pwd, '.autoproj', 'config.yml')
18
+ if File.file?(existing_config)
19
+ puts "Found existing configuration, using it as seed"
20
+ puts "use --no-seed-config to avoid this behavior"
21
+ ops.add_seed_config(existing_config)
22
+ end
16
23
  bootstrap_options = ops.parse_options(ARGV)
17
24
  ops.stage1
18
- if !ops.skip_stage2?
19
- ops.call_stage2
20
- end
21
- if !ops.run_autoproj 'bootstrap', *bootstrap_options
22
- exit 1
23
- end
24
-
25
+ ops.call_stage2 unless ops.skip_stage2?
26
+ exit 1 unless ops.run_autoproj('bootstrap', *bootstrap_options)
@@ -8,10 +8,13 @@ elsif ENV['AUTOPROJ_CURRENT_ROOT'] && (ENV['AUTOPROJ_CURRENT_ROOT'] != Dir.pwd)
8
8
  exit 1
9
9
  end
10
10
 
11
+ # frozen_string_literal: true
12
+
11
13
  require 'pathname'
12
14
  require 'optparse'
13
15
  require 'fileutils'
14
16
  require 'yaml'
17
+ require 'English'
15
18
 
16
19
  module Autoproj
17
20
  module Ops
@@ -23,6 +26,36 @@ module Autoproj
23
26
  class Install
24
27
  class UnexpectedBinstub < RuntimeError; end
25
28
 
29
+ RUBYLIB_REINIT = <<~RUBY
30
+ if defined?(Bundler)
31
+ if Bundler.respond_to?(:with_unbundled_env)
32
+ Bundler.with_unbundled_env do
33
+ exec(Hash['RUBYLIB' => nil], $0, *ARGV)
34
+ end
35
+ else
36
+ Bundler.with_clean_env do
37
+ exec(Hash['RUBYLIB' => nil], $0, *ARGV)
38
+ end
39
+ end
40
+ elsif ENV['RUBYLIB']
41
+ exec(Hash['RUBYLIB' => nil], $0, *ARGV)
42
+ end
43
+ RUBY
44
+
45
+ WITHOUT_BUNDLER = <<~RUBY
46
+ if defined?(Bundler)
47
+ if Bundler.respond_to?(:with_unbundled_env)
48
+ Bundler.with_unbundled_env do
49
+ exec($0, *ARGV)
50
+ end
51
+ else
52
+ Bundler.with_clean_env do
53
+ exec($0, *ARGV)
54
+ end
55
+ end
56
+ end
57
+ RUBY
58
+
26
59
  # The created workspace's root directory
27
60
  attr_reader :root_dir
28
61
  # Content of the Gemfile generated to install autoproj itself
@@ -230,6 +263,10 @@ module Autoproj
230
263
  "gem \"utilrb\", \">= 3.0.1\""].join("\n")
231
264
  end
232
265
 
266
+ def add_seed_config(path)
267
+ @config.merge!(YAML.safe_load(File.read(path), [Symbol]))
268
+ end
269
+
233
270
  # Parse the provided command line options and returns the non-options
234
271
  def parse_options(args = ARGV)
235
272
  options = OptionParser.new do |opt|
@@ -242,54 +279,63 @@ module Autoproj
242
279
  opt.on '--debug', 'Run in debug mode' do
243
280
  @autoproj_options << '--debug'
244
281
  end
245
- opt.on '--gem-source=URL', String, "use this source for RubyGems "\
246
- "instead of rubygems.org" do |url|
282
+ opt.on '--gem-source=URL', String, 'use this source for RubyGems '\
283
+ 'instead of rubygems.org' do |url|
247
284
  @gem_source = url
248
285
  end
249
- opt.on '--gems-path=PATH', "install gems under this path instead "\
250
- "of ~/.autoproj/gems" do |path|
286
+ opt.on '--gems-path=PATH', 'install gems under this path instead '\
287
+ 'of ~/.autoproj/gems' do |path|
251
288
  self.gems_install_path = path
252
289
  end
253
290
  opt.on '--public-gems', "install gems in the default gem location" do
254
291
  self.install_gems_in_gem_user_dir
255
292
  end
256
- opt.on '--version=VERSION_CONSTRAINT', String, 'use the provided "\
257
- "string as a version constraint for autoproj' do |version|
293
+ opt.on '--bundler-version=VERSION_CONSTRAINT', String, 'use the provided '\
294
+ 'string as a version constraint for bundler' do |version|
295
+ @config['bundler_version'] = version
296
+ end
297
+ opt.on '--version=VERSION_CONSTRAINT', String, 'use the provided '\
298
+ 'string as a version constraint for autoproj' do |version|
258
299
  if @gemfile
259
300
  raise "cannot give both --version and --gemfile"
260
301
  end
261
302
  @gemfile = default_gemfile_contents(version)
262
303
  end
263
- opt.on '--gemfile=PATH', String, 'use the given Gemfile to install "\
264
- "autoproj instead of the default' do |path|
304
+ opt.on '--gemfile=PATH', String, 'use the given Gemfile to install '\
305
+ 'autoproj instead of the default' do |path|
265
306
  if @gemfile
266
307
  raise "cannot give both --version and --gemfile"
267
308
  end
268
309
  @gemfile = File.read(path)
269
310
  end
270
- opt.on '--seed-config=PATH', String, 'path to a seed file that "\
271
- "should be used to initialize the configuration' do |path|
272
- @config.merge!(YAML.load(File.read(path)))
311
+ opt.on '--no-seed-config',
312
+ 'when reinstalling an existing autoproj workspace, do not '\
313
+ 'use the config in .autoproj/ as seed' do
314
+ @config.clear
273
315
  end
274
- opt.on '--prefer-os-independent-packages', 'prefer OS-independent "\
275
- "packages (such as a RubyGem) over their OS-packaged equivalent "\
276
- "(e.g. the thor gem vs. the ruby-thor debian package)' do
316
+ opt.on '--seed-config=PATH', String, 'path to a seed file that '\
317
+ 'should be used to initialize the configuration' do |path|
318
+ add_seed_config(path)
319
+ end
320
+ opt.on '--prefer-os-independent-packages', 'prefer OS-independent '\
321
+ 'packages (such as a RubyGem) over their OS-packaged equivalent '\
322
+ '(e.g. the thor gem vs. the ruby-thor debian package)' do
277
323
  @prefer_indep_over_os_packages = true
278
324
  end
279
- opt.on '--[no-]color', 'do not use colored output (enabled by "\
280
- "default if the terminal supports it)' do |color|
325
+ opt.on '--[no-]color', 'do not use colored output (enabled by '\
326
+ 'default if the terminal supports it)' do |color|
281
327
  if color then @autoproj_options << "--color"
282
328
  else @autoproj_options << '--no-color'
283
329
  end
284
330
  end
285
- opt.on '--[no-]progress', 'do not use progress output (enabled by "\
286
- "default if the terminal supports it)' do |progress|
331
+ opt.on '--[no-]progress', 'do not use progress output (enabled by '\
332
+ 'default if the terminal supports it)' do |progress|
287
333
  if progress then @autoproj_options << "--progress"
288
334
  else @autoproj_options << '--no-progress'
289
335
  end
290
336
  end
291
- opt.on '--[no-]interactive', 'if non-interactive, use default "\
292
- "answer for questions' do |flag|
337
+ opt.on '--[no-]interactive', 'if non-interactive, use default '\
338
+ 'answer for questions' do |flag|
293
339
  if flag then @autoproj_options << "--interactive"
294
340
  else @autoproj_options << "--no-interactive"
295
341
  end
@@ -299,22 +345,50 @@ module Autoproj
299
345
  @autoproj_options + args
300
346
  end
301
347
 
302
- def find_bundler(gem_program)
303
- setup_paths =
304
- IO.popen([env_for_child, Gem.ruby, gem_program, 'which','-a', 'bundler/setup']) do |io|
305
- io.read
306
- end
307
- return unless $?.success?
348
+ def bundler_version
349
+ @config['bundler_version']
350
+ end
351
+
352
+ def find_bundler(gem_program, version: nil)
308
353
  bundler_path = File.join(gems_gem_home, 'bin', 'bundle')
309
- setup_paths.each_line do |setup_path|
310
- if File.exist?(bundler_path) && setup_path.start_with?(gems_gem_home)
311
- return bundler_path
354
+ return unless File.exist?(bundler_path)
355
+
356
+ setup_paths =
357
+ if version
358
+ find_versioned_bundler_setup(gem_program, version)
359
+ else
360
+ find_unversioned_bundler_setup(gem_program)
312
361
  end
362
+
363
+ setup_paths.each do |setup_path|
364
+ return bundler_path if setup_path.start_with?(gems_gem_home)
313
365
  end
314
- return
366
+ nil
367
+ end
368
+
369
+ def find_versioned_bundler_setup(gem_program, version)
370
+ contents = IO.popen(
371
+ [env_for_child, Gem.ruby, gem_program,
372
+ 'contents', '-v', version, 'bundler'],
373
+ &:readlines
374
+ )
375
+ return [] unless $CHILD_STATUS.success?
376
+
377
+ contents.grep(%r{bundler/setup.rb$})
378
+ end
379
+
380
+ def find_unversioned_bundler_setup(gem_program)
381
+ setup_paths = IO.popen(
382
+ [env_for_child, Gem.ruby, gem_program,
383
+ 'which', '-a', 'bundler/setup'],
384
+ &:readlines
385
+ )
386
+ return [] unless $CHILD_STATUS.success?
387
+
388
+ setup_paths
315
389
  end
316
390
 
317
- def install_bundler(gem_program, silent: false)
391
+ def install_bundler(gem_program, version: nil, silent: false)
318
392
  local = ['--local'] if local?
319
393
 
320
394
  redirection = Hash.new
@@ -322,6 +396,9 @@ module Autoproj
322
396
  redirection = Hash[out: :close]
323
397
  end
324
398
 
399
+ version_args = []
400
+ version_args << '-v' << version if version
401
+
325
402
  # Shut up the bundler warning about 'bin' not being in PATH
326
403
  env = self.env
327
404
  env['PATH'] += [File.join(gems_gem_home, 'bin')]
@@ -332,14 +409,14 @@ module Autoproj
332
409
  '--clear-sources', '--source', gem_source,
333
410
  '--no-user-install', '--install-dir', gems_gem_home,
334
411
  *local, "--bindir=#{File.join(gems_gem_home, 'bin')}",
335
- 'bundler', **redirection)
412
+ 'bundler', *version_args, **redirection)
336
413
 
337
414
  if !result
338
415
  STDERR.puts "FATAL: failed to install bundler in #{gems_gem_home}"
339
416
  nil
340
417
  end
341
418
 
342
- if (bundler_path = find_bundler(gem_program))
419
+ if (bundler_path = find_bundler(gem_program, version: version))
343
420
  bundler_path
344
421
  else
345
422
  STDERR.puts "gem install bundler returned successfully, but still "\
@@ -348,7 +425,7 @@ module Autoproj
348
425
  end
349
426
  end
350
427
 
351
- def install_autoproj(bundler)
428
+ def install_autoproj(bundler, bundler_version: self.bundler_version)
352
429
  # Force bundler to update. If the user does not want this, let
353
430
  # him specify a Gemfile with tighter version constraints
354
431
  lockfile = File.join(dot_autoproj, 'Gemfile.lock')
@@ -363,14 +440,19 @@ module Autoproj
363
440
  opts << "--path=#{gems_install_path}"
364
441
  shims_path = File.join(dot_autoproj, 'bin')
365
442
 
366
- result = system(clean_env,
367
- Gem.ruby, bundler, 'install',
368
- "--gemfile=#{autoproj_gemfile_path}",
369
- "--shebang=#{Gem.ruby}",
370
- "--binstubs=#{shims_path}",
371
- *opts, chdir: dot_autoproj)
443
+ version_arg = []
444
+ version_arg << "_#{bundler_version}_" if bundler_version
372
445
 
373
- if !result
446
+ result = system(
447
+ clean_env,
448
+ Gem.ruby, bundler, *version_arg, 'install',
449
+ "--gemfile=#{autoproj_gemfile_path}",
450
+ "--shebang=#{Gem.ruby}",
451
+ "--binstubs=#{shims_path}",
452
+ *opts, chdir: dot_autoproj
453
+ )
454
+
455
+ unless result
374
456
  STDERR.puts "FATAL: failed to install autoproj in #{dot_autoproj}"
375
457
  exit 1
376
458
  end
@@ -379,7 +461,7 @@ module Autoproj
379
461
  root_dir, autoproj_gemfile_path, gems_gem_home)
380
462
  end
381
463
 
382
- EXCLUDED_FROM_SHIMS = %w{rake thor}
464
+ EXCLUDED_FROM_SHIMS = %w[rake thor].freeze
383
465
 
384
466
  def self.rewrite_shims(shim_path, ruby_executable,
385
467
  root_dir, autoproj_gemfile_path, gems_gem_home)
@@ -435,11 +517,7 @@ module Autoproj
435
517
  #
436
518
 
437
519
  # Autoproj generated preamble
438
- if defined?(Bundler)
439
- Bundler.with_clean_env do
440
- exec($0, *ARGV)
441
- end
442
- end
520
+ #{WITHOUT_BUNDLER}
443
521
  ENV['BUNDLE_GEMFILE'] ||= '#{autoproj_gemfile_path}'
444
522
  ENV['GEM_HOME'] = '#{gems_gem_home}'
445
523
  ENV.delete('GEM_PATH')
@@ -451,12 +529,7 @@ Gem.paths = Hash['GEM_HOME' => '#{gems_gem_home}', 'GEM_PATH' => '']
451
529
  def self.shim_bundler_old(ruby_executable, autoproj_gemfile_path, gems_gem_home)
452
530
  "#! #{ruby_executable}
453
531
 
454
- if defined?(Bundler)
455
- Bundler.with_clean_env do
456
- exec($0, *ARGV)
457
- end
458
- end
459
-
532
+ #{WITHOUT_BUNDLER}
460
533
  ENV['BUNDLE_GEMFILE'] ||= '#{autoproj_gemfile_path}'
461
534
  ENV['GEM_HOME'] = '#{gems_gem_home}'
462
535
  ENV.delete('GEM_PATH')
@@ -481,14 +554,7 @@ load Gem.bin_path('bundler', 'bundler')"
481
554
  #
482
555
 
483
556
  # Autoproj generated preamble, v1
484
- if defined?(Bundler)
485
- Bundler.with_clean_env do
486
- exec(Hash['RUBYLIB' => nil], $0, *ARGV)
487
- end
488
- elsif ENV['RUBYLIB']
489
- exec(Hash['RUBYLIB' => nil], $0, *ARGV)
490
- end
491
-
557
+ #{RUBYLIB_REINIT}
492
558
  ENV['BUNDLE_GEMFILE'] = '#{autoproj_gemfile_path}'
493
559
  ENV['AUTOPROJ_CURRENT_ROOT'] = '#{root_dir}'
494
560
  Gem.paths = Hash['GEM_HOME' => '#{gems_gem_home}', 'GEM_PATH' => '']
@@ -500,14 +566,7 @@ Gem.paths = Hash['GEM_HOME' => '#{gems_gem_home}', 'GEM_PATH' => '']
500
566
  gems_gem_home, load_line)
501
567
  "#! #{ruby_executable}
502
568
 
503
- if defined?(Bundler)
504
- Bundler.with_clean_env do
505
- exec(Hash['RUBYLIB' => nil], $0, *ARGV)
506
- end
507
- elsif ENV['RUBYLIB']
508
- exec(Hash['RUBYLIB' => nil], $0, *ARGV)
509
- end
510
-
569
+ #{RUBYLIB_REINIT}
511
570
  ENV['BUNDLE_GEMFILE'] = '#{autoproj_gemfile_path}'
512
571
  ENV['AUTOPROJ_CURRENT_ROOT'] = '#{root_dir}'
513
572
  require 'rubygems'
@@ -601,8 +660,11 @@ require 'bundler/setup'
601
660
  #
602
661
  # So, we're calling 'gem' as a subcommand to discovery the
603
662
  # actual bindir
604
- bindir = IO.popen(env_for_child,
605
- [Gem.ruby, '-e', 'puts "#{Gem.user_dir}/bin"']).read
663
+ bindir = IO.popen(
664
+ env_for_child,
665
+ [Gem.ruby, '-e', 'puts "#{Gem.user_dir}/bin"'], # rubocop:disable Lint/InterpolationCheck
666
+ &:read
667
+ )
606
668
  if bindir
607
669
  @gem_bindir = bindir.chomp
608
670
  else
@@ -610,11 +672,11 @@ require 'bundler/setup'
610
672
  end
611
673
  end
612
674
 
613
- def install
675
+ def install(bundler_version: self.bundler_version)
614
676
  if ENV['BUNDLER_GEMFILE']
615
677
  raise "cannot run autoproj_install or autoproj_bootstrap while "\
616
- "under a 'bundler exec' subcommand or having loaded an env.sh. "\
617
- "Open a new console and try again"
678
+ "under a 'bundler exec' subcommand or having loaded an "\
679
+ "env.sh. Open a new console and try again"
618
680
  end
619
681
 
620
682
  gem_program = self.class.guess_gem_program
@@ -622,13 +684,12 @@ require 'bundler/setup'
622
684
  env['GEM_HOME'] = [gems_gem_home]
623
685
  env['GEM_PATH'] = [gems_gem_home]
624
686
 
625
- if bundler = find_bundler(gem_program)
687
+ if (bundler = find_bundler(gem_program, version: bundler_version))
626
688
  puts "Detected bundler at #{bundler}"
627
689
  else
628
690
  puts "Installing bundler in #{gems_gem_home}"
629
- if !(bundler = install_bundler(gem_program))
630
- exit 1
631
- end
691
+ bundler = install_bundler(gem_program, version: bundler_version)
692
+ exit(1) unless bundler
632
693
  end
633
694
  self.class.rewrite_shims(
634
695
  File.join(dot_autoproj, 'bin'),
@@ -640,7 +701,7 @@ require 'bundler/setup'
640
701
  save_gemfile
641
702
 
642
703
  puts "Installing autoproj in #{gems_gem_home}"
643
- install_autoproj(bundler)
704
+ install_autoproj(bundler, bundler_version: bundler_version)
644
705
  end
645
706
 
646
707
  def load_config
@@ -742,8 +803,13 @@ end
742
803
  ENV.delete('BUNDLE_GEMFILE')
743
804
  ENV.delete('RUBYLIB')
744
805
  ops = Autoproj::Ops::Install.new(Dir.pwd)
806
+
807
+ existing_config = File.join(Dir.pwd, '.autoproj', 'config.yml')
808
+ if File.file?(existing_config)
809
+ puts "Found existing configuration, using it as seed"
810
+ puts "use --no-seed-config to avoid this behavior"
811
+ ops.add_seed_config(existing_config)
812
+ end
745
813
  ops.parse_options(ARGV)
746
814
  ops.stage1
747
- if !ops.skip_stage2?
748
- ops.call_stage2
749
- end
815
+ ops.call_stage2 unless ops.skip_stage2?
@@ -13,8 +13,13 @@ require 'autoproj/ops/install'
13
13
  ENV.delete('BUNDLE_GEMFILE')
14
14
  ENV.delete('RUBYLIB')
15
15
  ops = Autoproj::Ops::Install.new(Dir.pwd)
16
+
17
+ existing_config = File.join(Dir.pwd, '.autoproj', 'config.yml')
18
+ if File.file?(existing_config)
19
+ puts "Found existing configuration, using it as seed"
20
+ puts "use --no-seed-config to avoid this behavior"
21
+ ops.add_seed_config(existing_config)
22
+ end
16
23
  ops.parse_options(ARGV)
17
24
  ops.stage1
18
- if !ops.skip_stage2?
19
- ops.call_stage2
20
- end
25
+ ops.call_stage2 unless ops.skip_stage2?
@@ -9,6 +9,8 @@
9
9
  require 'backports/2.4.0/nil_class/dup'
10
10
  require 'backports/2.4.0/false_class/dup'
11
11
  require 'backports/2.4.0/true_class/dup'
12
+ require 'backports/2.4.0/hash/transform_values'
13
+ require 'backports/2.5.0/hash/transform_keys'
12
14
 
13
15
  require 'autobuild'
14
16
  require 'autoproj/autobuild'
@@ -44,6 +46,7 @@
44
46
  require 'autoproj/source_package_query'
45
47
  require 'autoproj/os_package_query'
46
48
 
49
+ require 'autoproj/ops/phase_reporting'
47
50
  require 'autoproj/ops/install'
48
51
  require 'autoproj/ops/tools'
49
52
  require 'autoproj/ops/loader'