autoproj 1.12.6 → 1.13.0.b1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,94 @@
1
+ require 'autoproj'
2
+ require 'autoproj/cmdline'
3
+ require 'autoproj/ops/tools'
4
+ require 'autoproj/ops/snapshot'
5
+
6
+ module Autoproj
7
+ module CLI
8
+ class Versions
9
+ include Ops::Tools
10
+
11
+ DEFAULT_VERSIONS_FILE_BASENAME = Ops::Snapshot::DEFAULT_VERSIONS_FILE_BASENAME
12
+
13
+ def default_versions_file
14
+ File.join( Autoproj.overrides_dir, DEFAULT_VERSIONS_FILE_BASENAME )
15
+ end
16
+
17
+ attr_reader :manifest
18
+
19
+ def initialize(manifest)
20
+ @manifest = manifest
21
+ end
22
+
23
+ def resolve_selection( user_selection )
24
+ resolved_selection = CmdLine.
25
+ resolve_user_selection(user_selection, :filter => false)
26
+ resolved_selection.filter_excluded_and_ignored_packages(manifest)
27
+ # This calls #prepare, which is required to run build_packages
28
+ packages = CmdLine.import_packages(resolved_selection)
29
+
30
+ # Remove non-existing packages
31
+ packages.each do |pkg|
32
+ if !File.directory?(manifest.package(pkg).autobuild.srcdir)
33
+ raise ConfigError, "cannot commit #{pkg} as it is not checked out"
34
+ end
35
+ end
36
+ packages
37
+ end
38
+
39
+
40
+ def parse_options(args)
41
+ options = Hash.new
42
+ parser = OptionParser.new do |opt|
43
+ opt.on '--[no-]package-sets', 'commit the package set state as well (default if no packages are selected)' do |flag|
44
+ options[:package_sets] = flag
45
+ end
46
+ opt.on '--replace', String, 'if the file given to --save exists, replace it instead of updating it' do
47
+ options[:replace] = true
48
+ end
49
+ opt.on '-k', '--keep-going', "ignore packages that can't be snapshotted (the default is to terminate with an error)" do
50
+ options[:keep_going] = true
51
+ end
52
+ opt.on '--save[=FILE]', String, "the file into which the versions should be saved (if no file is given, defaults to #{default_versions_file})" do |file|
53
+ options[:output_file] =
54
+ if file == '-'
55
+ nil
56
+ elsif !file
57
+ default_versions_file
58
+ else
59
+ file
60
+ end
61
+ end
62
+ end
63
+ common_options(parser)
64
+ remaining = parser.parse(args)
65
+ return remaining, options
66
+ end
67
+
68
+ def run(user_selection, options)
69
+ do_package_sets = options[:package_sets]
70
+ if do_package_sets.nil? && user_selection.empty?
71
+ do_package_sets = true
72
+ end
73
+
74
+ CmdLine.report(silent: true) do
75
+ packages = resolve_selection user_selection
76
+ ops = Ops::Snapshot.new(manifest, keep_going: options[:keep_going])
77
+
78
+ versions = Array.new
79
+ if do_package_sets
80
+ versions += ops.snapshot_package_sets
81
+ end
82
+ versions += ops.snapshot_packages(packages)
83
+ if output_file = options[:output_file]
84
+ ops.save_versions(versions, output_file, replace: options[:replace])
85
+ else
86
+ versions = ops.sort_versions(versions)
87
+ puts YAML.dump(versions)
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end
93
+ end
94
+
@@ -43,6 +43,14 @@ module Autoproj
43
43
  end
44
44
 
45
45
  module CmdLine
46
+ def self.argv
47
+ if defined? ORIGINAL_ARGV
48
+ ORIGINAL_ARGV
49
+ else
50
+ ARGV
51
+ end
52
+ end
53
+
46
54
  def self.config
47
55
  Autoproj.config
48
56
  end
@@ -193,17 +201,11 @@ module Autoproj
193
201
  Autoproj.save_config
194
202
  ENV['AUTOPROJ_RESTARTING'] = '1'
195
203
  require 'rbconfig'
196
- if defined?(ORIGINAL_ARGV)
197
- exec(ruby_executable, $0, *ORIGINAL_ARGV)
198
- else
199
- exec(ruby_executable, $0, *ARGV)
200
- end
204
+ exec(ruby_executable, $0, *argv)
201
205
  end
202
206
  end
203
207
 
204
208
  def self.load_configuration(silent = false)
205
- manifest = Autoproj.manifest
206
-
207
209
  manifest.each_package_set do |pkg_set|
208
210
  if Gem::Version.new(pkg_set.required_autoproj_version) > Gem::Version.new(Autoproj::VERSION)
209
211
  raise ConfigError.new(pkg_set.source_file), "the #{pkg_set.name} package set requires autoproj v#{pkg_set.required_autoproj_version} but this is v#{Autoproj::VERSION}"
@@ -254,6 +256,13 @@ module Autoproj
254
256
  end
255
257
  end
256
258
 
259
+ manifest.each_autobuild_package do |pkg|
260
+ Autobuild.each_utility do |uname, _|
261
+ pkg.utility(uname).enabled =
262
+ config.utility_enabled_for?(uname, pkg.name)
263
+ end
264
+ end
265
+
257
266
  # We finished loading the configuration files. Not all configuration
258
267
  # is done (since we need to process the package setup blocks), but
259
268
  # save the current state of the configuration anyway.
@@ -261,7 +270,7 @@ module Autoproj
261
270
  end
262
271
 
263
272
  def self.update_configuration
264
- Ops::Configuration.new(Autoproj.manifest, Ops.loader).update_configuration(only_local?)
273
+ Ops::Configuration.new(manifest, Ops.loader).update_configuration(only_local?)
265
274
  end
266
275
 
267
276
  def self.setup_package_directories(pkg)
@@ -289,11 +298,9 @@ module Autoproj
289
298
 
290
299
 
291
300
  def self.setup_all_package_directories
292
- manifest = Autoproj.manifest
293
-
294
301
  # Override the package directories from our reused installations
295
302
  imported_packages = Set.new
296
- Autoproj.manifest.reused_installations.each do |imported_manifest|
303
+ manifest.reused_installations.each do |imported_manifest|
297
304
  imported_manifest.each do |imported_pkg|
298
305
  imported_packages << imported_pkg.name
299
306
  if pkg = manifest.find_package(imported_pkg.name)
@@ -365,9 +372,13 @@ module Autoproj
365
372
  end
366
373
 
367
374
  def self.update_environment
368
- Autoproj.manifest.reused_installations.each do |manifest|
369
- manifest.each do |pkg|
370
- Autobuild::Package[pkg.name].update_environment
375
+ manifest.reused_installations.each do |reused_manifest|
376
+ reused_manifest.each do |pkg|
377
+ # The reused installations might have packages we do not
378
+ # know about, just ignore them
379
+ if pkg = manifest.find_autobuild_package(pkg)
380
+ pkg.update_environment
381
+ end
371
382
  end
372
383
  end
373
384
 
@@ -526,8 +537,6 @@ module Autoproj
526
537
  # Returns the set of packages that are actually selected based on what
527
538
  # the user gave on the command line
528
539
  def self.resolve_user_selection(selected_packages, options = Hash.new)
529
- manifest = Autoproj.manifest
530
-
531
540
  if selected_packages.empty?
532
541
  return manifest.default_packages
533
542
  end
@@ -576,27 +585,56 @@ module Autoproj
576
585
  root = !reason
577
586
  chain.unshift pkg_name
578
587
  if root
579
- reason = Autoproj.manifest.exclusion_reason(pkg_name)
588
+ reason = manifest.exclusion_reason(pkg_name)
580
589
  else
581
590
  if chain.size == 1
582
- Autoproj.manifest.add_exclusion(pkg_name, "its dependency #{reason}")
591
+ manifest.add_exclusion(pkg_name, "its dependency #{reason}")
583
592
  else
584
- Autoproj.manifest.add_exclusion(pkg_name, "#{reason} (dependency chain: #{chain.join(">")})")
593
+ manifest.add_exclusion(pkg_name, "#{reason} (dependency chain: #{chain.join(">")})")
585
594
  end
586
595
  end
587
596
 
588
597
  return if !revdeps.has_key?(pkg_name)
589
598
  revdeps[pkg_name].each do |dep_name|
590
- if !Autoproj.manifest.excluded?(dep_name)
599
+ if !manifest.excluded?(dep_name)
591
600
  mark_exclusion_along_revdeps(dep_name, revdeps, chain.dup, reason)
592
601
  end
593
602
  end
594
603
  end
595
604
 
596
- def self.import_packages(selection)
605
+ def self.import_next_step(manifest, pkg, reverse_dependencies)
606
+ new_packages = []
607
+ pkg.dependencies.each do |dep_name|
608
+ reverse_dependencies[dep_name] << pkg.name
609
+ new_packages << manifest.find_autobuild_package(dep_name)
610
+ end
611
+ pkg_opt_deps, _ = pkg.partition_optional_dependencies
612
+ pkg_opt_deps.each do |dep_name|
613
+ new_packages << manifest.find_autobuild_package(dep_name)
614
+ end
615
+
616
+ new_packages.delete_if do |new_pkg|
617
+ if manifest.excluded?(new_pkg.name)
618
+ mark_exclusion_along_revdeps(new_pkg.name, reverse_dependencies)
619
+ true
620
+ elsif manifest.ignored?(new_pkg.name)
621
+ true
622
+ end
623
+ end
624
+ new_packages
625
+ end
626
+
627
+ def self.import_packages(selection, options = Hash.new)
628
+ options, import_options = Kernel.filter_options options,
629
+ warn_about_ignored_packages: true,
630
+ warn_about_excluded_packages: true
631
+ import_options = Hash[only_local: only_local?, reset: reset?, checkout_only: !Autobuild.do_update].
632
+ merge(import_options)
633
+
634
+ updated_packages = Array.new
597
635
  selected_packages = selection.packages.
598
636
  map do |pkg_name|
599
- pkg = Autobuild::Package[pkg_name]
637
+ pkg = manifest.find_autobuild_package(pkg_name)
600
638
  if !pkg
601
639
  raise ConfigError.new, "selected package #{pkg_name} does not exist"
602
640
  end
@@ -626,21 +664,33 @@ module Autoproj
626
664
  raise ConfigError.new, "#{pkg.name} has no VCS, but is not checked out in #{pkg.srcdir}"
627
665
  end
628
666
 
667
+ # Try to auto-exclude the package early. If the autobuild file
668
+ # contained some information that allows us to exclude it now,
669
+ # then let's just do it
670
+ import_next_step(manifest, pkg, reverse_dependencies)
671
+ if manifest.excluded?(pkg.name)
672
+ selection.filter_excluded_and_ignored_packages(manifest)
673
+ next
674
+ end
675
+
629
676
  ## COMPLETELY BYPASS RAKE HERE
630
677
  # The reason is that the ordering of import/prepare between
631
678
  # packages is not important BUT the ordering of import vs.
632
679
  # prepare in one package IS important: prepare is the method
633
680
  # that takes into account dependencies.
634
- pkg.import(only_local?)
681
+ pkg.import(import_options)
682
+ if pkg.updated?
683
+ updated_packages << pkg.name
684
+ end
635
685
  Rake::Task["#{pkg.name}-import"].instance_variable_set(:@already_invoked, true)
636
686
  manifest.load_package_manifest(pkg.name)
637
687
 
638
688
  # The package setup mechanisms might have added an exclusion
639
689
  # on this package. Handle this.
640
- if Autoproj.manifest.excluded?(pkg.name)
690
+ if manifest.excluded?(pkg.name)
641
691
  mark_exclusion_along_revdeps(pkg.name, reverse_dependencies)
642
692
  # Run a filter now, to have errors as early as possible
643
- selection.filter_excluded_and_ignored_packages(Autoproj.manifest)
693
+ selection.filter_excluded_and_ignored_packages(manifest)
644
694
  # Delete this package from the current_packages set
645
695
  next
646
696
  end
@@ -650,32 +700,17 @@ module Autoproj
650
700
  end
651
701
  pkg.update_environment
652
702
 
653
- # Verify that its dependencies are there, and add
654
- # them to the selected_packages set so that they get
655
- # imported as well
656
- new_packages = []
657
- pkg.dependencies.each do |dep_name|
658
- reverse_dependencies[dep_name] << pkg.name
659
- new_packages << Autobuild::Package[dep_name]
660
- end
661
- pkg_opt_deps, _ = pkg.partition_optional_dependencies
662
- pkg_opt_deps.each do |dep_name|
663
- new_packages << Autobuild::Package[dep_name]
664
- end
665
-
666
- new_packages.delete_if do |pkg|
667
- if Autoproj.manifest.excluded?(pkg.name)
668
- mark_exclusion_along_revdeps(pkg.name, reverse_dependencies)
669
- true
670
- elsif Autoproj.manifest.ignored?(pkg.name)
671
- true
672
- end
703
+ new_packages = import_next_step(manifest, pkg, reverse_dependencies)
704
+ # Excluded dependencies might have caused the package to be
705
+ # excluded as well ... do not add any dependency to the
706
+ # processing queue if it is the case
707
+ if !manifest.excluded?(pkg.name)
708
+ package_queue.concat(new_packages.sort_by(&:name))
673
709
  end
674
- package_queue.concat(new_packages.sort_by(&:name))
675
710
 
676
711
  # Verify that everything is still OK with the new
677
712
  # exclusions/ignores
678
- selection.filter_excluded_and_ignored_packages(Autoproj.manifest)
713
+ selection.filter_excluded_and_ignored_packages(manifest)
679
714
  end
680
715
 
681
716
  all_enabled_packages = Set.new
@@ -720,18 +755,35 @@ module Autoproj
720
755
  end
721
756
  end
722
757
 
723
- selection.exclusions.each do |sel, pkg_names|
724
- pkg_names.sort.each do |pkg_name|
725
- Autoproj.warn "#{pkg_name}, which was selected for #{sel}, cannot be built: #{Autoproj.manifest.exclusion_reason(pkg_name)}", :bold
758
+ if options[:warn_about_excluded_packages]
759
+ selection.exclusions.each do |sel, pkg_names|
760
+ pkg_names.sort.each do |pkg_name|
761
+ Autoproj.warn "#{pkg_name}, which was selected for #{sel}, cannot be built: #{manifest.exclusion_reason(pkg_name)}", :bold
762
+ end
726
763
  end
727
764
  end
728
- selection.ignores.each do |sel, pkg_names|
729
- pkg_names.sort.each do |pkg_name|
730
- Autoproj.warn "#{pkg_name}, which was selected for #{sel}, is ignored", :bold
765
+ if options[:warn_about_ignored_packages]
766
+ selection.ignores.each do |sel, pkg_names|
767
+ pkg_names.sort.each do |pkg_name|
768
+ Autoproj.warn "#{pkg_name}, which was selected for #{sel}, is ignored", :bold
769
+ end
731
770
  end
732
771
  end
733
772
 
734
773
  return all_enabled_packages
774
+
775
+ ensure
776
+ if !updated_packages.empty?
777
+ failure_message =
778
+ if $!
779
+ " (#{$!.message.split("\n").first})"
780
+ end
781
+ ops = Ops::Snapshot.new(manifest, keep_going: true)
782
+
783
+ ops.update_package_import_state(
784
+ "#{$0} #{argv.join(" ")}#{failure_message}",
785
+ updated_packages)
786
+ end
735
787
  end
736
788
 
737
789
  def self.build_packages(selected_packages, all_enabled_packages, phases = [])
@@ -779,6 +831,7 @@ module Autoproj
779
831
  def self.manifest; Autoproj.manifest end
780
832
  def self.only_status?; !!@only_status end
781
833
  def self.only_local?; !!@only_local end
834
+ def self.reset?; !!@reset end
782
835
  def self.check?; !!@check end
783
836
  def self.manifest_update?; !!@manifest_update end
784
837
  def self.only_config?; !!@only_config end
@@ -846,6 +899,7 @@ module Autoproj
846
899
  @force_re_build_with_depends = false
847
900
  force_re_build_with_depends = nil
848
901
  @only_config = false
902
+ @reset = false
849
903
  @color = true
850
904
  Autobuild.color = true
851
905
  Autobuild.do_update = nil
@@ -997,9 +1051,13 @@ where 'mode' is one of:
997
1051
  opts.on("--none", "in osdeps mode, do not install any package but display information about them, regardless of the otherwise selected mode") do
998
1052
  @osdeps_forced_mode = 'none'
999
1053
  end
1000
- opts.on("--local", "for status, do not access the network") do
1054
+ opts.on("--local", "in status and update modes, do not access the network") do
1001
1055
  @only_local = true
1002
1056
  end
1057
+ opts.on("--reset", "in update mode, reset the repositories to the state requested by the VCS configuration") do
1058
+ @reset = true
1059
+ end
1060
+
1003
1061
  opts.on('--exit-code', 'in status mode, exit with a code that reflects the status of the installation (see documentation for details)') do
1004
1062
  @status_exit_code = true
1005
1063
  end
@@ -1255,7 +1313,7 @@ where 'mode' is one of:
1255
1313
  end
1256
1314
 
1257
1315
  def self.status(packages)
1258
- pkg_sets = Autoproj.manifest.each_package_set.map(&:create_autobuild_package)
1316
+ pkg_sets = manifest.each_package_set.map(&:create_autobuild_package)
1259
1317
  if !pkg_sets.empty?
1260
1318
  Autoproj.message("autoproj: displaying status of configuration", :bold)
1261
1319
  display_status(pkg_sets)
@@ -1270,7 +1328,7 @@ where 'mode' is one of:
1270
1328
  end
1271
1329
 
1272
1330
  def self.missing_dependencies(pkg)
1273
- manifest = Autoproj.manifest.package_manifests[pkg.name]
1331
+ manifest = manifest.package_manifests[pkg.name]
1274
1332
  all_deps = pkg.dependencies.map do |dep_name|
1275
1333
  dep_pkg = Autobuild::Package[dep_name]
1276
1334
  if dep_pkg then dep_pkg.name
@@ -1298,7 +1356,7 @@ where 'mode' is one of:
1298
1356
  result = []
1299
1357
 
1300
1358
  pkg = Autobuild::Package[pkg_name]
1301
- manifest = Autoproj.manifest.package_manifests[pkg.name]
1359
+ manifest = manifest.package_manifests[pkg.name]
1302
1360
 
1303
1361
  # Check if the manifest contains rosdep tags
1304
1362
  # if manifest && !manifest.each_os_dependency.to_a.empty?
@@ -1320,7 +1378,7 @@ where 'mode' is one of:
1320
1378
  def self.manifest_update(packages)
1321
1379
  packages.sort.each do |pkg_name|
1322
1380
  pkg = Autobuild::Package[pkg_name]
1323
- manifest = Autoproj.manifest.package_manifests[pkg.name]
1381
+ manifest = manifest.package_manifests[pkg.name]
1324
1382
 
1325
1383
  xml =
1326
1384
  if !manifest
@@ -1358,87 +1416,10 @@ where 'mode' is one of:
1358
1416
  end
1359
1417
  end
1360
1418
 
1361
- def self.snapshot(manifest, target_dir, packages)
1362
- # First, copy the configuration directory to create target_dir
1363
- if File.exists?(target_dir)
1364
- raise ArgumentError, "#{target_dir} already exists"
1365
- end
1366
- FileUtils.cp_r Autoproj.config_dir, target_dir
1367
- # Finally, remove the remotes/ directory from the generated
1368
- # buildconf, it is obsolete now
1369
- FileUtils.rm_rf File.join(target_dir, 'remotes')
1370
-
1371
- # Pin package sets
1372
- package_sets = Array.new
1373
- manifest.each_package_set do |pkg_set|
1374
- next if pkg_set.name == 'local'
1375
- if pkg_set.local?
1376
- package_sets << Pathname.new(pkg_set.local_dir).
1377
- relative_path_from(Pathname.new(manifest.file).dirname).
1378
- to_s
1379
- else
1380
- vcs_info = pkg_set.vcs.to_hash
1381
- if pin_info = pkg_set.snapshot(target_dir)
1382
- vcs_info = vcs_info.merge(pin_info)
1383
- end
1384
- package_sets << vcs_info
1385
- end
1386
- end
1387
- manifest_path = File.join(target_dir, 'manifest')
1388
- manifest_data = YAML.load(File.read(manifest_path))
1389
- manifest_data['package_sets'] = package_sets
1390
- File.open(manifest_path, 'w') do |io|
1391
- YAML.dump(manifest_data, io)
1392
- end
1393
-
1394
- # Now, create snapshot information for each of the packages
1395
- version_control_info = []
1396
- overrides_info = []
1397
- packages.each do |package_name|
1398
- package = manifest.packages[package_name]
1399
- if !package
1400
- raise ArgumentError, "#{package_name} is not a known package"
1401
- end
1402
- package_set = package.package_set
1403
- importer = package.autobuild.importer
1404
- if !importer
1405
- Autoproj.message "cannot snapshot #{package_name} as it has no importer"
1406
- next
1407
- elsif !importer.respond_to?(:snapshot)
1408
- Autoproj.message "cannot snapshot #{package_name} as the #{importer.class} importer does not support it"
1409
- next
1410
- end
1411
-
1412
- vcs_info = importer.snapshot(package.autobuild, target_dir)
1413
- if vcs_info
1414
- if package_set.name == 'local'
1415
- version_control_info << Hash[package_name, vcs_info]
1416
- else
1417
- overrides_info << Hash[package_name, vcs_info]
1418
- end
1419
- end
1420
- end
1421
-
1422
- overrides_path = File.join(target_dir, 'overrides.yml')
1423
- if File.exists?(overrides_path)
1424
- overrides = YAML.load(File.read(overrides_path))
1425
- end
1426
- # In Ruby 1.9, an empty file results in YAML.load returning false
1427
- overrides ||= Hash.new
1428
- (overrides['version_control'] ||= Array.new).
1429
- concat(version_control_info)
1430
- (overrides['overrides'] ||= Array.new).
1431
- concat(overrides_info)
1432
-
1433
- File.open(overrides_path, 'w') do |io|
1434
- io.write YAML.dump(overrides)
1435
- end
1436
- end
1437
-
1438
1419
  # Displays the reverse OS dependencies (i.e. for each osdeps package,
1439
1420
  # who depends on it and where it is defined)
1440
1421
  def self.revshow_osdeps(packages)
1441
- _, ospkg_to_pkg = Autoproj.manifest.list_os_dependencies(packages)
1422
+ _, ospkg_to_pkg = manifest.list_os_dependencies(packages)
1442
1423
 
1443
1424
  # A mapping from a package name to
1444
1425
  # [is_os_pkg, is_gem_pkg, definitions, used_by]
@@ -1489,7 +1470,7 @@ where 'mode' is one of:
1489
1470
 
1490
1471
  # Displays the OS dependencies required by the given packages
1491
1472
  def self.show_osdeps(packages)
1492
- _, ospkg_to_pkg = Autoproj.manifest.list_os_dependencies(packages)
1473
+ _, ospkg_to_pkg = manifest.list_os_dependencies(packages)
1493
1474
 
1494
1475
  # ospkg_to_pkg is the reverse mapping to what we want. Invert it
1495
1476
  mapping = Hash.new { |h, k| h[k] = Set.new }
@@ -1546,6 +1527,7 @@ where 'mode' is one of:
1546
1527
  Autoproj::CmdLine.setup_all_package_directories
1547
1528
  Autoproj::CmdLine.finalize_package_setup
1548
1529
 
1530
+
1549
1531
  load_all_available_package_manifests
1550
1532
  update_environment
1551
1533
  remaining_arguments
@@ -1609,18 +1591,23 @@ where 'mode' is one of:
1609
1591
 
1610
1592
  def self.export_installation_manifest
1611
1593
  File.open(File.join(Autoproj.root_dir, ".autoproj-installation-manifest"), 'w') do |io|
1612
- Autoproj.manifest.all_selected_packages.each do |pkg_name|
1594
+ manifest.all_selected_packages.each do |pkg_name|
1613
1595
  pkg = Autobuild::Package[pkg_name]
1614
1596
  io.puts "#{pkg_name},#{pkg.srcdir},#{pkg.prefix}"
1615
1597
  end
1616
1598
  end
1617
1599
  end
1618
1600
 
1619
- def self.report
1601
+ def self.report(options = Hash.new)
1602
+ options = Kernel.validate_options options,
1603
+ silent: false
1604
+
1620
1605
  Autobuild::Reporting.report do
1621
1606
  yield
1622
1607
  end
1623
- Autobuild::Reporting.success
1608
+ if !options[:silent]
1609
+ Autobuild::Reporting.success
1610
+ end
1624
1611
 
1625
1612
  rescue ConfigError => e
1626
1613
  STDERR.puts