autoproj 2.0.0.rc38 → 2.0.0.rc39

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.
@@ -174,6 +174,7 @@ def accept_unavailable_osdeps=(flag); @accept_unavailable_osdeps = flag end
174
174
 
175
175
  def initialize(ws, os_package_resolver: OSPackageResolver.new)
176
176
  @ws = ws
177
+ @vcs = VCSDefinition.none
177
178
  @file = nil
178
179
  @data = Hash.new
179
180
  @has_layout = false
@@ -181,6 +182,8 @@ def initialize(ws, os_package_resolver: OSPackageResolver.new)
181
182
  @packages = Hash.new
182
183
  @package_sets = []
183
184
  @os_package_resolver = os_package_resolver
185
+ # Cache for #ignored?
186
+ @ignored_package_names = nil
184
187
 
185
188
  @automatic_exclusions = Hash.new
186
189
  @constants_definitions = Hash.new
@@ -33,7 +33,7 @@ def remotes_user_dir
33
33
  #
34
34
  # @return [String]
35
35
  def manifest_path
36
- File.join(ws.config_dir, 'manifest')
36
+ ws.manifest_file_path
37
37
  end
38
38
 
39
39
  # @param [Manifest] manifest
@@ -50,20 +50,17 @@ def initialize(workspace, update_from: nil)
50
50
  # Imports or updates a source (remote or otherwise).
51
51
  #
52
52
  # See create_autobuild_package for informations about the arguments.
53
- def update_configuration_repository(vcs, name, into, options = Hash.new)
54
- options = Kernel.validate_options options,
53
+ def update_configuration_repository(vcs, name, into,
55
54
  only_local: false,
56
- checkout_only: !Autobuild.do_update,
57
- ignore_errors: false,
58
55
  reset: false,
59
- retry_count: nil
56
+ retry_count: nil)
60
57
 
61
58
  fake_package = Tools.create_autobuild_package(vcs, name, into)
62
59
  if update_from
63
60
  # Define a package in the installation manifest that points to
64
61
  # the desired folder in other_root
65
62
  relative_path = Pathname.new(into).
66
- relative_path_from(Pathname.new(root_dir)).to_s
63
+ relative_path_from(Pathname.new(ws.root_dir)).to_s
67
64
  other_dir = File.join(update_from.path, relative_path)
68
65
  if File.directory?(other_dir)
69
66
  update_from.packages.unshift(
@@ -79,10 +76,10 @@ def update_configuration_repository(vcs, name, into, options = Hash.new)
79
76
  fake_package.update = false
80
77
  end
81
78
  end
82
- if retry_count = options.delete(:retry_count)
79
+ if retry_count
83
80
  fake_package.importer.retry_count = retry_count
84
81
  end
85
- fake_package.import(options)
82
+ fake_package.import(only_local: only_local, reset: reset)
86
83
 
87
84
  rescue Autobuild::ConfigException => e
88
85
  raise ConfigError.new, "cannot import #{name}: #{e.message}", e.backtrace
@@ -92,22 +89,24 @@ def update_configuration_repository(vcs, name, into, options = Hash.new)
92
89
  #
93
90
  # @return [Boolean] true if something got updated or checked out,
94
91
  # and false otherwise
95
- def update_main_configuration(options = Hash.new)
96
- if !options.kind_of?(Hash)
97
- options = Hash[only_local: options]
92
+ def update_main_configuration(keep_going: false, checkout_only: !Autobuild.do_update, only_local: false, reset: false, retry_count: nil)
93
+ if checkout_only && File.exist?(ws.config_dir)
94
+ return []
98
95
  end
99
- options = validate_options options,
100
- only_local: false,
101
- checkout_only: !Autobuild.do_update,
102
- ignore_errors: false,
103
- reset: false,
104
- retry_count: nil
105
96
 
106
97
  update_configuration_repository(
107
- ws.manifest.vcs,
108
- "autoproj main configuration",
109
- ws.config_dir,
110
- options)
98
+ ws.manifest.vcs, "autoproj main configuration", ws.config_dir,
99
+ only_local: only_local, reset: reset, retry_count: retry_count
100
+ )
101
+ []
102
+ rescue Interrupt
103
+ raise
104
+ rescue Exception => e
105
+ if keep_going
106
+ [e]
107
+ else
108
+ raise e
109
+ end
111
110
  end
112
111
 
113
112
  # Update or checkout a remote package set, based on its VCS definition
@@ -115,22 +114,18 @@ def update_main_configuration(options = Hash.new)
115
114
  # @param [VCSDefinition] vcs the package set VCS
116
115
  # @return [Boolean] true if something got updated or checked out,
117
116
  # and false otherwise
118
- def update_remote_package_set(vcs, options = Hash.new)
119
- # BACKWARD
120
- if !options.kind_of?(Hash)
121
- options = Hash[only_local: options]
122
- end
123
- options = validate_options options,
124
- only_local: false,
117
+ def update_remote_package_set(vcs,
125
118
  checkout_only: !Autobuild.do_update,
126
- ignore_errors: false,
119
+ only_local: false,
127
120
  reset: false,
128
- retry_count: nil
121
+ retry_count: nil)
129
122
 
130
123
  name = PackageSet.name_of(ws, vcs)
131
124
  raw_local_dir = PackageSet.raw_local_dir_of(ws, vcs)
132
125
 
133
- return if options[:checkout_only] && File.exist?(raw_local_dir)
126
+ if checkout_only && File.exist?(raw_local_dir)
127
+ return
128
+ end
134
129
 
135
130
  # YUK. I am stopping there in the refactoring
136
131
  # TODO: figure out a better way
@@ -140,7 +135,10 @@ def update_remote_package_set(vcs, options = Hash.new)
140
135
  end
141
136
  ws.install_os_packages([vcs.type], all: nil)
142
137
  update_configuration_repository(
143
- vcs, name, raw_local_dir, options)
138
+ vcs, name, raw_local_dir,
139
+ only_local: only_local,
140
+ reset: reset,
141
+ retry_count: retry_count)
144
142
  end
145
143
 
146
144
  # Create the user-visible directory for a remote package set
@@ -200,20 +198,16 @@ def queue_auto_imports_if_needed(queue, pkg_set, root_set)
200
198
  #
201
199
  # @yieldparam [String] osdep the name of an osdep required to import the
202
200
  # package sets
203
- def load_and_update_package_sets(root_pkg_set, options = Hash.new)
204
- if !options.kind_of?(Hash)
205
- options = Hash[only_local: options]
206
- end
207
- options = validate_options options,
208
- only_local: false,
209
- checkout_only: !Autobuild.do_update,
210
- ignore_errors: false,
211
- reset: false,
212
- retry_count: nil
213
-
201
+ def load_and_update_package_sets(root_pkg_set,
202
+ only_local: false,
203
+ checkout_only: !Autobuild.do_update,
204
+ keep_going: false,
205
+ reset: false,
206
+ retry_count: nil)
214
207
  package_sets = [root_pkg_set]
215
208
  by_repository_id = Hash.new
216
209
  by_name = Hash.new
210
+ failures = Array.new
217
211
 
218
212
  required_remotes_dirs = Array.new
219
213
 
@@ -238,8 +232,21 @@ def load_and_update_package_sets(root_pkg_set, options = Hash.new)
238
232
  # Make sure the package set has been already checked out to
239
233
  # retrieve the actual name of the package set
240
234
  if !vcs.local?
241
- update_remote_package_set(vcs, options)
242
- required_remotes_dirs << PackageSet.raw_local_dir_of(ws, vcs)
235
+ failed = handle_keep_going(keep_going, vcs, failures) do
236
+ update_remote_package_set(
237
+ vcs, checkout_only: checkout_only,
238
+ only_local: only_local, reset: reset,
239
+ retry_count: retry_count)
240
+ end
241
+ raw_local_dir = PackageSet.raw_local_dir_of(ws, vcs)
242
+
243
+ # We really can't continue if the VCS was being checked out
244
+ # and that failed
245
+ if failed && !File.directory?(raw_local_dir)
246
+ raise failures.last
247
+ end
248
+
249
+ required_remotes_dirs << raw_local_dir
243
250
  end
244
251
 
245
252
  name = PackageSet.name_of(ws, vcs)
@@ -277,7 +284,7 @@ def load_and_update_package_sets(root_pkg_set, options = Hash.new)
277
284
  by_repository_id[repository_id][2] = pkg_set
278
285
  package_sets << pkg_set
279
286
 
280
- by_name[pkg_set.name] = [pkg_set, vcs, options, imported_from]
287
+ by_name[pkg_set.name] = [pkg_set, vcs, import_options, imported_from]
281
288
 
282
289
  # Finally, queue the imports
283
290
  queue_auto_imports_if_needed(queue, pkg_set, root_pkg_set)
@@ -286,7 +293,8 @@ def load_and_update_package_sets(root_pkg_set, options = Hash.new)
286
293
  required_user_dirs = by_name.collect { |k,v| k }
287
294
  cleanup_remotes_dir(package_sets, required_remotes_dirs)
288
295
  cleanup_remotes_user_dir(package_sets, required_user_dirs)
289
- package_sets
296
+
297
+ return package_sets, failures
290
298
  end
291
299
 
292
300
  # Removes from {remotes_dir} the directories that do not match a package
@@ -369,44 +377,228 @@ def sort_package_sets_by_import_order(package_sets, root_pkg_set)
369
377
  result
370
378
  end
371
379
 
372
- def load_package_sets(options = Hash.new)
373
- options = validate_options options,
380
+ def load_package_sets(
374
381
  only_local: false,
375
382
  checkout_only: true,
376
- ignore_errors: false,
383
+ keep_going: false,
377
384
  reset: false,
378
- retry_count: nil
379
- update_configuration(options)
385
+ retry_count: nil,
386
+ mainline: nil)
387
+ update_configuration(
388
+ only_local: only_local,
389
+ checkout_only: checkout_only,
390
+ keep_going: keep_going,
391
+ reset: reset,
392
+ retry_count: retry_count,
393
+ mainline: nil)
394
+ end
395
+
396
+ def report_import_failure(what, reason)
397
+ if !reason.kind_of?(Interrupt)
398
+ Autoproj.message "import of #{what} failed", :red
399
+ Autoproj.message reason.to_s, :red
400
+ end
401
+ end
402
+
403
+ def handle_keep_going(keep_going, vcs, failures)
404
+ yield
405
+ false
406
+ rescue Interrupt
407
+ raise
408
+ rescue Exception => failure_reason
409
+ if keep_going
410
+ report_import_failure(vcs, failure_reason)
411
+ failures << failure_reason
412
+ true
413
+ else
414
+ raise
415
+ end
380
416
  end
381
417
 
382
418
  def update_configuration(
383
419
  only_local: false,
384
420
  checkout_only: !Autobuild.do_update,
385
- ignore_errors: false,
421
+ keep_going: false,
386
422
  reset: false,
387
- retry_count: nil)
388
-
389
- update_options = Hash[
390
- only_local: only_local,
391
- checkout_only: checkout_only,
392
- ignore_errors: ignore_errors,
393
- reset: reset,
394
- retry_count: retry_count]
395
-
396
- if ws.manifest.vcs && !ws.manifest.vcs.local?
397
- update_main_configuration(**update_options)
423
+ retry_count: nil,
424
+ mainline: nil)
425
+
426
+ if ws.manifest.vcs.needs_import?
427
+ main_configuration_failure = update_main_configuration(
428
+ keep_going: keep_going,
429
+ checkout_only: checkout_only,
430
+ only_local: only_local,
431
+ reset: reset,
432
+ retry_count: retry_count)
433
+
434
+ main_configuration_failure.each do |e|
435
+ report_import_failure("main configuration", e)
436
+ end
437
+ else
438
+ main_configuration_failure = []
398
439
  end
399
440
  ws.load_main_initrb
400
441
  ws.manifest.load(manifest_path)
401
442
  root_pkg_set = ws.manifest.main_package_set
402
443
  root_pkg_set.load_description_file
403
444
  root_pkg_set.explicit = true
404
- update_package_sets(**update_options)
445
+
446
+ package_sets_failure = update_package_sets(
447
+ only_local: only_local,
448
+ checkout_only: checkout_only,
449
+ keep_going: keep_going,
450
+ reset: reset,
451
+ retry_count: retry_count)
452
+
453
+ load_package_set_information(mainline: mainline)
454
+
455
+ if !main_configuration_failure.empty? && !package_sets_failure.empty?
456
+ raise ImportFailed.new(main_configuration_failure + package_sets_failure)
457
+ elsif !main_configuration_failure.empty?
458
+ raise ImportFailed.new(main_configuration_failure)
459
+ elsif !package_sets_failure.empty?
460
+ raise ImportFailed.new(package_sets_failure)
461
+ end
462
+ end
463
+
464
+ def load_package_set_information(mainline: nil)
465
+ manifest = ws.manifest
466
+ manifest.each_package_set do |pkg_set|
467
+ if Gem::Version.new(pkg_set.required_autoproj_version) > Gem::Version.new(Autoproj::VERSION)
468
+ 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}"
469
+ end
470
+ end
471
+
472
+ # Loads OS package definitions once and for all
473
+ load_osdeps_from_package_sets
474
+
475
+ # Load the required autobuild definitions
476
+ Autoproj.message("autoproj: loading ...", :bold)
477
+ manifest.each_package_set do |pkg_set|
478
+ pkg_set.each_autobuild_file do |path|
479
+ ws.import_autobuild_file pkg_set, path
480
+ end
481
+ end
482
+
483
+ # Now, load the package's importer configurations (from the various
484
+ # source.yml files)
485
+ if mainline.respond_to?(:to_str)
486
+ mainline = manifest.package_set(mainline)
487
+ end
488
+ manifest.load_importers(mainline: mainline)
489
+
490
+ auto_add_packages_from_layout
491
+
492
+ manifest.each_autobuild_package do |pkg|
493
+ Autobuild.each_utility do |uname, _|
494
+ pkg.utility(uname).enabled =
495
+ ws.config.utility_enabled_for?(uname, pkg.name)
496
+ end
497
+ end
498
+
499
+ mark_unavailable_osdeps_as_excluded
500
+ end
501
+
502
+ # @api private
503
+ #
504
+ # Attempts to find packages mentioned in the layout but that are not
505
+ # defined, and auto-define them if they can be found on disk
506
+ #
507
+ # It only warns about packages that can't be defined that way are on
508
+ def auto_add_packages_from_layout
509
+ manifest = ws.manifest
510
+
511
+ # Auto-add packages that are
512
+ # * present on disk
513
+ # * listed in the layout part of the manifest
514
+ # * but have no definition
515
+ explicit = manifest.normalized_layout
516
+ explicit.each do |pkg_or_set, layout_level|
517
+ next if manifest.find_autobuild_package(pkg_or_set)
518
+ next if manifest.has_package_set?(pkg_or_set)
519
+ full_path = File.expand_path(File.join(ws.root_dir, layout_level, pkg_or_set))
520
+ next if !File.directory?(full_path)
521
+
522
+ if handler = auto_add_package(pkg_or_set, full_path)
523
+ Autoproj.message " auto-added #{pkg_or_set} #{"in #{layout_level} " if layout_level != "/"}using the #{handler.gsub(/_package/, '')} package handler"
524
+ else
525
+ Autoproj.warn "cannot auto-add #{pkg_or_set}: unknown package type"
526
+ end
527
+
528
+ end
405
529
  end
406
530
 
407
- def update_package_sets(**update_options)
531
+ # @api private
532
+ #
533
+ # Attempts to auto-add the package checked out at the given path
534
+ #
535
+ # @param [String] full_path
536
+ # @return [String,nil] either the name of the package handler used to
537
+ # define the package, or nil if no handler could be found
538
+ def auto_add_package(name, full_path)
539
+ manifest = ws.manifest
540
+ handler, _srcdir = Autoproj.package_handler_for(full_path)
541
+ if handler
542
+ ws.set_as_main_workspace do
543
+ ws.in_package_set(manifest.main_package_set, manifest.file) do
544
+ send(handler, name)
545
+ end
546
+ end
547
+ handler
548
+ end
549
+ end
550
+
551
+ def mark_unavailable_osdeps_as_excluded
552
+ os_package_resolver = ws.os_package_resolver
553
+ manifest = ws.manifest
554
+ os_package_resolver.all_package_names.each do |osdep_name|
555
+ # If the osdep can be replaced by source packages, there's
556
+ # nothing to do really. The exclusions of the source packages
557
+ # will work as expected
558
+ if manifest.osdeps_overrides[osdep_name] || manifest.find_autobuild_package(osdep_name)
559
+ next
560
+ end
561
+
562
+ case os_package_resolver.availability_of(osdep_name)
563
+ when OSPackageResolver::UNKNOWN_OS
564
+ manifest.exclude_package(osdep_name, "this operating system is unknown to autoproj")
565
+ when OSPackageResolver::WRONG_OS
566
+ manifest.exclude_package(osdep_name, "there are definitions for it, but not for this operating system")
567
+ when OSPackageResolver::NONEXISTENT
568
+ manifest.exclude_package(osdep_name, "it is marked as unavailable for this operating system")
569
+ end
570
+ end
571
+ end
572
+
573
+ # Load OS dependency information contained in our registered package
574
+ # sets into the provided osdep object
575
+ #
576
+ # This is included in {load_package_sets}
577
+ #
578
+ # @return [void]
579
+ def load_osdeps_from_package_sets
580
+ ws.manifest.each_package_set do |pkg_set|
581
+ pkg_set.each_osdeps_file do |file|
582
+ file_osdeps = pkg_set.load_osdeps(
583
+ file, operating_system: ws.operating_system)
584
+ ws.os_package_resolver.merge(file_osdeps)
585
+ end
586
+ end
587
+ end
588
+
589
+ def update_package_sets(only_local: false,
590
+ checkout_only: !Autobuild.do_update,
591
+ keep_going: false,
592
+ reset: false,
593
+ retry_count: nil)
408
594
  root_pkg_set = ws.manifest.main_package_set
409
- package_sets = load_and_update_package_sets(root_pkg_set, **update_options)
595
+ package_sets, failures = load_and_update_package_sets(
596
+ root_pkg_set,
597
+ only_local: only_local,
598
+ checkout_only: checkout_only,
599
+ keep_going: keep_going,
600
+ reset: reset,
601
+ retry_count: retry_count)
410
602
  root_pkg_set.imports.each do |pkg_set|
411
603
  pkg_set.explicit = true
412
604
  end
@@ -420,6 +612,8 @@ def update_package_sets(**update_options)
420
612
  if @remote_update_message_displayed
421
613
  Autoproj.message
422
614
  end
615
+
616
+ failures
423
617
  end
424
618
  end
425
619
  end