autoproj 2.0.0.rc38 → 2.0.0.rc39

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