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.
- checksums.yaml +4 -4
- data/.travis.yml +9 -7
- data/lib/autoproj/cli/build.rb +5 -7
- data/lib/autoproj/cli/main.rb +5 -0
- data/lib/autoproj/cli/manifest.rb +52 -0
- data/lib/autoproj/cli/patcher.rb +1 -1
- data/lib/autoproj/cli/query.rb +1 -1
- data/lib/autoproj/cli/update.rb +122 -61
- data/lib/autoproj/cli/versions.rb +1 -1
- data/lib/autoproj/exceptions.rb +20 -0
- data/lib/autoproj/find_workspace.rb +1 -2
- data/lib/autoproj/manifest.rb +3 -0
- data/lib/autoproj/ops/configuration.rb +262 -68
- data/lib/autoproj/ops/import.rb +38 -32
- data/lib/autoproj/ops/main_config_switcher.rb +1 -1
- data/lib/autoproj/ops/snapshot.rb +10 -21
- data/lib/autoproj/os_package_installer.rb +1 -0
- data/lib/autoproj/os_package_resolver.rb +35 -19
- data/lib/autoproj/system.rb +3 -0
- data/lib/autoproj/test.rb +17 -0
- data/lib/autoproj/version.rb +1 -1
- data/lib/autoproj/workspace.rb +37 -131
- metadata +3 -2
data/lib/autoproj/manifest.rb
CHANGED
@@ -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
|
-
|
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,
|
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
|
79
|
+
if retry_count
|
83
80
|
fake_package.importer.retry_count = retry_count
|
84
81
|
end
|
85
|
-
fake_package.import(
|
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(
|
96
|
-
if
|
97
|
-
|
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
|
-
|
109
|
-
|
110
|
-
|
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,
|
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
|
-
|
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
|
-
|
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,
|
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,
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
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
|
-
|
242
|
-
|
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,
|
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
|
-
|
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(
|
373
|
-
options = validate_options options,
|
380
|
+
def load_package_sets(
|
374
381
|
only_local: false,
|
375
382
|
checkout_only: true,
|
376
|
-
|
383
|
+
keep_going: false,
|
377
384
|
reset: false,
|
378
|
-
retry_count: nil
|
379
|
-
|
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
|
-
|
421
|
+
keep_going: false,
|
386
422
|
reset: false,
|
387
|
-
retry_count: nil
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
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
|
-
|
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
|
-
|
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(
|
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
|