autobuild 1.19.0 → 1.22.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/lint.yml +25 -0
- data/.github/workflows/test.yml +30 -0
- data/.rubocop.yml +14 -7
- data/autobuild.gemspec +8 -6
- data/bin/autobuild +1 -1
- data/lib/autobuild/build_logfile.rb +1 -2
- data/lib/autobuild/config.rb +18 -5
- data/lib/autobuild/configurable.rb +3 -1
- data/lib/autobuild/environment.rb +28 -45
- data/lib/autobuild/exceptions.rb +11 -5
- data/lib/autobuild/import/archive.rb +31 -22
- data/lib/autobuild/import/cvs.rb +6 -6
- data/lib/autobuild/import/darcs.rb +4 -4
- data/lib/autobuild/import/git-lfs.rb +4 -4
- data/lib/autobuild/import/git.rb +149 -70
- data/lib/autobuild/import/hg.rb +7 -7
- data/lib/autobuild/import/svn.rb +15 -9
- data/lib/autobuild/importer.rb +38 -38
- data/lib/autobuild/mail_reporter.rb +5 -2
- data/lib/autobuild/package.rb +24 -14
- data/lib/autobuild/packages/autotools.rb +4 -9
- data/lib/autobuild/packages/cmake.rb +16 -7
- data/lib/autobuild/packages/dummy.rb +0 -4
- data/lib/autobuild/packages/gnumake.rb +1 -1
- data/lib/autobuild/packages/orogen.rb +11 -4
- data/lib/autobuild/packages/pkgconfig.rb +2 -2
- data/lib/autobuild/packages/python.rb +1 -2
- data/lib/autobuild/packages/ruby.rb +5 -5
- data/lib/autobuild/parallel.rb +12 -17
- data/lib/autobuild/pkgconfig.rb +1 -0
- data/lib/autobuild/progress_display.rb +130 -49
- data/lib/autobuild/rake_task_extension.rb +6 -0
- data/lib/autobuild/reporting.rb +20 -7
- data/lib/autobuild/subcommand.rb +24 -23
- data/lib/autobuild/test_utility.rb +2 -1
- data/lib/autobuild/timestamps.rb +3 -3
- data/lib/autobuild/utility.rb +29 -9
- data/lib/autobuild/version.rb +1 -1
- data/lib/autobuild.rb +0 -3
- metadata +42 -26
- data/.travis.yml +0 -19
data/lib/autobuild/import/hg.rb
CHANGED
@@ -17,9 +17,9 @@ module Autobuild
|
|
17
17
|
# @option options [String] :branch (default) the branch to track
|
18
18
|
def initialize(repository, options = {})
|
19
19
|
hgopts, _common = Kernel.filter_options options,
|
20
|
-
|
20
|
+
branch: 'default'
|
21
21
|
sourceopts, common = Kernel.filter_options options,
|
22
|
-
|
22
|
+
:repository_id, :source_id
|
23
23
|
|
24
24
|
super(common)
|
25
25
|
@branch = hgopts[:branch]
|
@@ -48,8 +48,8 @@ module Autobuild
|
|
48
48
|
def validate_importdir(package)
|
49
49
|
unless File.directory?(File.join(package.importdir, '.hg'))
|
50
50
|
raise ConfigException.new(package, 'import'),
|
51
|
-
|
52
|
-
|
51
|
+
"while importing #{package.name}, "\
|
52
|
+
"#{package.importdir} is not a hg repository"
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
@@ -61,9 +61,9 @@ module Autobuild
|
|
61
61
|
end
|
62
62
|
validate_importdir(package)
|
63
63
|
package.run(:import, Autobuild.tool('hg'), 'pull',
|
64
|
-
|
64
|
+
repository, retry: true, working_directory: package.importdir)
|
65
65
|
package.run(:import, Autobuild.tool('hg'), 'update',
|
66
|
-
|
66
|
+
branch, working_directory: package.importdir)
|
67
67
|
true # no easy to know if package was updated, keep previous behavior
|
68
68
|
end
|
69
69
|
|
@@ -72,7 +72,7 @@ module Autobuild
|
|
72
72
|
FileUtils.mkdir_p(base_dir) unless File.directory?(base_dir)
|
73
73
|
|
74
74
|
package.run(:import, Autobuild.tool('hg'), 'clone',
|
75
|
-
|
75
|
+
'-u', branch, repository, package.importdir, retry: true)
|
76
76
|
end
|
77
77
|
end
|
78
78
|
|
data/lib/autobuild/import/svn.rb
CHANGED
@@ -14,9 +14,11 @@ module Autobuild
|
|
14
14
|
# Autobuild.programs['svn'] = 'my_svn_tool'
|
15
15
|
def initialize(svnroot, options = {})
|
16
16
|
svnroot = [*svnroot].join("/")
|
17
|
-
svnopts, common = Kernel.filter_options
|
17
|
+
svnopts, common = Kernel.filter_options(
|
18
|
+
options,
|
18
19
|
:svnup => [], :svnco => [], :revision => nil,
|
19
20
|
:repository_id => "svn:#{svnroot}"
|
21
|
+
)
|
20
22
|
common[:repository_id] = svnopts.delete(:repository_id)
|
21
23
|
relocate(svnroot, svnopts)
|
22
24
|
super(common.merge(repository_id: svnopts[:repository_id]))
|
@@ -67,7 +69,7 @@ module Autobuild
|
|
67
69
|
revision = svninfo.grep(/^Revision: /).first
|
68
70
|
unless revision
|
69
71
|
raise ConfigException.new(package, 'import'),
|
70
|
-
|
72
|
+
"cannot get SVN information for #{package.importdir}"
|
71
73
|
end
|
72
74
|
revision =~ /Revision: (\d+)/
|
73
75
|
Integer($1)
|
@@ -79,7 +81,9 @@ module Autobuild
|
|
79
81
|
# @return [String]
|
80
82
|
# @raises (see svn_info)
|
81
83
|
def vcs_fingerprint(package)
|
82
|
-
Digest::SHA1.hexdigest(
|
84
|
+
Digest::SHA1.hexdigest(
|
85
|
+
svn_info(package).grep(/^(URL|Revision):/).sort.join("\n")
|
86
|
+
)
|
83
87
|
end
|
84
88
|
|
85
89
|
# Returns the URL of the remote SVN repository
|
@@ -93,7 +97,7 @@ module Autobuild
|
|
93
97
|
url = svninfo.grep(/^URL: /).first
|
94
98
|
unless url
|
95
99
|
raise ConfigException.new(package, 'import'),
|
96
|
-
|
100
|
+
"cannot get SVN information for #{package.importdir}"
|
97
101
|
end
|
98
102
|
url.chomp =~ /URL: (.+)/
|
99
103
|
$1
|
@@ -165,8 +169,9 @@ module Autobuild
|
|
165
169
|
Hash.new
|
166
170
|
end
|
167
171
|
|
168
|
-
options, other_options = Kernel.filter_options
|
169
|
-
working_directory: package.importdir, retry: true
|
172
|
+
options, other_options = Kernel.filter_options(
|
173
|
+
options, working_directory: package.importdir, retry: true
|
174
|
+
)
|
170
175
|
options = options.merge(other_options)
|
171
176
|
package.run(:import, Autobuild.tool(:svn), *args, options, &block)
|
172
177
|
end
|
@@ -203,7 +208,8 @@ module Autobuild
|
|
203
208
|
|
204
209
|
unless svninfo.grep(/is not a working copy/).empty?
|
205
210
|
raise ConfigException.new(package, 'import'),
|
206
|
-
|
211
|
+
"#{package.importdir} does not appear to be a "\
|
212
|
+
"Subversion working copy"
|
207
213
|
end
|
208
214
|
svninfo
|
209
215
|
ensure
|
@@ -241,8 +247,8 @@ module Autobuild
|
|
241
247
|
|
242
248
|
def checkout(package, _options = Hash.new) # :nodoc:
|
243
249
|
run_svn(package, 'co', "--non-interactive", *@options_co,
|
244
|
-
|
245
|
-
|
250
|
+
svnroot, package.importdir,
|
251
|
+
working_directory: nil)
|
246
252
|
end
|
247
253
|
end
|
248
254
|
|
data/lib/autobuild/importer.rb
CHANGED
@@ -107,7 +107,11 @@ module Autobuild
|
|
107
107
|
# @return [Array<String>,nil]
|
108
108
|
# @see .cache_dirs
|
109
109
|
def self.default_cache_dirs
|
110
|
-
|
110
|
+
if @default_cache_dirs
|
111
|
+
@default_cache_dirs
|
112
|
+
elsif (from_env = ENV['AUTOBUILD_CACHE_DIR'])
|
113
|
+
@default_cache_dirs = [from_env]
|
114
|
+
end
|
111
115
|
end
|
112
116
|
|
113
117
|
# Sets the cache directory for a given importer type
|
@@ -199,7 +203,8 @@ module Autobuild
|
|
199
203
|
|
200
204
|
patches_fingerprint_string = patches_fingerprint(package)
|
201
205
|
if patches_fingerprint_string
|
202
|
-
Digest::SHA1.hexdigest(vcs_fingerprint_string +
|
206
|
+
Digest::SHA1.hexdigest(vcs_fingerprint_string +
|
207
|
+
patches_fingerprint_string)
|
203
208
|
elsif patches.empty?
|
204
209
|
vcs_fingerprint_string
|
205
210
|
end
|
@@ -207,16 +212,19 @@ module Autobuild
|
|
207
212
|
|
208
213
|
# basic fingerprint of the package and its dependencies
|
209
214
|
def vcs_fingerprint(package)
|
210
|
-
#each importer type should implement its own
|
211
|
-
Autoproj.warn "Fingerprint in #{package.name} has not been implemented
|
212
|
-
|
215
|
+
# each importer type should implement its own
|
216
|
+
Autoproj.warn "Fingerprint in #{package.name} has not been implemented "\
|
217
|
+
"for this type of packages, results should be discarded"
|
218
|
+
nil
|
213
219
|
end
|
214
220
|
|
215
221
|
# fingerprint for patches associated to this package
|
216
222
|
def patches_fingerprint(package)
|
217
223
|
cur_patches = currently_applied_patches(package)
|
218
|
-
cur_patches.map(&:shift) #leave only level and source information
|
219
|
-
|
224
|
+
cur_patches.map(&:shift) # leave only level and source information
|
225
|
+
if !patches.empty? && cur_patches
|
226
|
+
Digest::SHA1.hexdigest(cur_patches.sort.flatten.join(""))
|
227
|
+
end
|
220
228
|
end
|
221
229
|
|
222
230
|
# Sets the number of times update / checkout should be retried before giving
|
@@ -310,12 +318,10 @@ module Autobuild
|
|
310
318
|
end
|
311
319
|
|
312
320
|
# Enumerate the post-import hooks for this importer
|
313
|
-
def each_post_hook(error: false)
|
321
|
+
def each_post_hook(error: false, &block)
|
314
322
|
return enum_for(__method__, error: false) unless block_given?
|
315
323
|
|
316
|
-
self.class.each_post_hook(error: error)
|
317
|
-
yield(callback)
|
318
|
-
end
|
324
|
+
self.class.each_post_hook(error: error, &block)
|
319
325
|
|
320
326
|
post_hooks.each do |hook|
|
321
327
|
yield(hook.callback) if hook.always || !error
|
@@ -353,9 +359,9 @@ module Autobuild
|
|
353
359
|
raise last_error
|
354
360
|
else raise
|
355
361
|
end
|
356
|
-
rescue ::Exception =>
|
362
|
+
rescue ::Exception => e
|
357
363
|
message = Autobuild.color('update failed', :red)
|
358
|
-
last_error =
|
364
|
+
last_error = e
|
359
365
|
# If the package is patched, it might be that the update
|
360
366
|
# failed because we needed to unpatch first. Try it out
|
361
367
|
#
|
@@ -374,11 +380,11 @@ module Autobuild
|
|
374
380
|
rescue Interrupt
|
375
381
|
raise
|
376
382
|
rescue ::Exception
|
377
|
-
raise
|
383
|
+
raise e
|
378
384
|
end
|
379
385
|
end
|
380
386
|
|
381
|
-
retry_count = update_retry_count(
|
387
|
+
retry_count = update_retry_count(e, retry_count)
|
382
388
|
raise unless retry_count
|
383
389
|
|
384
390
|
package.message "update failed in #{package.importdir}, "\
|
@@ -395,20 +401,20 @@ module Autobuild
|
|
395
401
|
fallback(e, package, :import, package)
|
396
402
|
end
|
397
403
|
|
398
|
-
def perform_checkout(package, options
|
404
|
+
def perform_checkout(package, **options)
|
399
405
|
last_error = nil
|
400
406
|
package.progress_start "checking out %s", :done_message => 'checked out %s' do
|
401
407
|
retry_count = 0
|
402
408
|
begin
|
403
|
-
checkout(package, options)
|
409
|
+
checkout(package, **options)
|
404
410
|
execute_post_hooks(package)
|
405
411
|
rescue Interrupt
|
406
412
|
if last_error then raise last_error
|
407
413
|
else raise
|
408
414
|
end
|
409
|
-
rescue ::Exception =>
|
410
|
-
last_error =
|
411
|
-
retry_count = update_retry_count(
|
415
|
+
rescue ::Exception => e
|
416
|
+
last_error = e
|
417
|
+
retry_count = update_retry_count(e, retry_count)
|
412
418
|
raise unless retry_count
|
413
419
|
|
414
420
|
package.message "checkout of %s failed, "\
|
@@ -452,31 +458,26 @@ module Autobuild
|
|
452
458
|
# ID is given will, in this mode, reset the repository to the requested ID
|
453
459
|
# (if that does not involve losing commits). Otherwise, it will only
|
454
460
|
# ensure that the requested commit ID is present in the current HEAD.
|
455
|
-
def import(
|
461
|
+
def import( # rubocop:disable Metrics/ParameterLists
|
462
|
+
package, *old_boolean,
|
463
|
+
ignore_errors: false, checkout_only: false, allow_interactive: true, **options
|
464
|
+
)
|
456
465
|
# Backward compatibility
|
457
|
-
unless
|
458
|
-
|
466
|
+
unless old_boolean.empty?
|
467
|
+
old_boolean = old_boolean.first
|
459
468
|
Autoproj.warn "calling #import with a boolean as second argument "\
|
460
469
|
"is deprecated, switch to the named argument interface instead"
|
461
|
-
Autoproj.warn " e.g. call import(package, only_local: #{
|
470
|
+
Autoproj.warn " e.g. call import(package, only_local: #{old_boolean})"
|
462
471
|
Autoproj.warn " #{caller(1..1).first}"
|
463
|
-
options =
|
472
|
+
options[:only_local] = old_boolean
|
464
473
|
end
|
465
474
|
|
466
|
-
options = Kernel.validate_options options,
|
467
|
-
only_local: false,
|
468
|
-
reset: false,
|
469
|
-
checkout_only: false,
|
470
|
-
ignore_errors: false,
|
471
|
-
allow_interactive: true
|
472
|
-
ignore_errors = options.delete(:ignore_errors)
|
473
|
-
|
474
475
|
importdir = package.importdir
|
475
476
|
if File.directory?(importdir)
|
476
477
|
package.isolate_errors(mark_as_failed: false,
|
477
478
|
ignore_errors: ignore_errors) do
|
478
|
-
if !
|
479
|
-
perform_update(package, options)
|
479
|
+
if !checkout_only && package.update?
|
480
|
+
perform_update(package, checkout_only: false, **options)
|
480
481
|
elsif Autobuild.verbose
|
481
482
|
package.message "%s: not updating"
|
482
483
|
end
|
@@ -484,12 +485,11 @@ module Autobuild
|
|
484
485
|
|
485
486
|
elsif File.exist?(importdir)
|
486
487
|
raise ConfigException.new(package, 'import'),
|
487
|
-
|
488
|
+
"#{importdir} exists but is not a directory"
|
488
489
|
else
|
489
490
|
package.isolate_errors(mark_as_failed: true,
|
490
491
|
ignore_errors: ignore_errors) do
|
491
|
-
perform_checkout(package,
|
492
|
-
allow_interactive: options[:allow_interactive])
|
492
|
+
perform_checkout(package, allow_interactive: allow_interactive)
|
493
493
|
true
|
494
494
|
end
|
495
495
|
end
|
@@ -22,8 +22,11 @@ if Autobuild::HAS_RMAIL
|
|
22
22
|
end
|
23
23
|
|
24
24
|
attr_reader :from_email, :to_email, :smtp_hostname, :smtp_port,
|
25
|
-
|
25
|
+
:subject, :only_errors
|
26
|
+
|
26
27
|
def initialize(config)
|
28
|
+
super()
|
29
|
+
|
27
30
|
@from_email = (config[:from] || default_mail)
|
28
31
|
@to_email = (config[:to] || default_mail)
|
29
32
|
@subject =
|
@@ -78,7 +81,7 @@ if Autobuild::HAS_RMAIL
|
|
78
81
|
to_email.each do |email|
|
79
82
|
mail.header.to = email
|
80
83
|
smtp.send_mail(RMail::Serialize.write('', mail),
|
81
|
-
|
84
|
+
from_email, email)
|
82
85
|
end
|
83
86
|
end
|
84
87
|
|
data/lib/autobuild/package.rb
CHANGED
@@ -64,7 +64,7 @@ module Autobuild
|
|
64
64
|
# Some statistics about the commands that have been run
|
65
65
|
attr_reader :statistics
|
66
66
|
|
67
|
-
EnvOp = Struct.new :type, :name, :values
|
67
|
+
EnvOp = Struct.new :type, :name, :values # rubocop:disable Lint/StructNewOverride
|
68
68
|
|
69
69
|
# List of environment values added by this package with {#env_add},
|
70
70
|
# {#env_add_path} or {#env_set}
|
@@ -150,6 +150,7 @@ module Autobuild
|
|
150
150
|
@imported = false
|
151
151
|
@prepared = false
|
152
152
|
@built = false
|
153
|
+
@disabled = nil
|
153
154
|
|
154
155
|
if Hash === spec
|
155
156
|
name, depends = spec.to_a.first
|
@@ -402,8 +403,8 @@ module Autobuild
|
|
402
403
|
def isolate_errors(options = Hash.new)
|
403
404
|
options = Hash[mark_as_failed: true] unless options.kind_of?(Hash)
|
404
405
|
options = validate_options options,
|
405
|
-
|
406
|
-
|
406
|
+
mark_as_failed: true,
|
407
|
+
ignore_errors: Autobuild.ignore_errors
|
407
408
|
|
408
409
|
# Don't do anything if we already have failed
|
409
410
|
if failed?
|
@@ -448,12 +449,12 @@ module Autobuild
|
|
448
449
|
# be done there as well.
|
449
450
|
#
|
450
451
|
# (see Importer#import)
|
451
|
-
def import(options
|
452
|
-
options =
|
452
|
+
def import(*old_boolean, **options)
|
453
|
+
options = { only_local: old_boolean.first } unless old_boolean.empty?
|
453
454
|
|
454
455
|
@import_invoked = true
|
455
456
|
if @importer
|
456
|
-
result = @importer.import(self, options)
|
457
|
+
result = @importer.import(self, **options)
|
457
458
|
elsif update?
|
458
459
|
message "%s: no importer defined, doing nothing"
|
459
460
|
end
|
@@ -495,12 +496,12 @@ module Autobuild
|
|
495
496
|
end
|
496
497
|
end
|
497
498
|
if suffix.empty?
|
498
|
-
|
499
|
+
msg
|
499
500
|
elsif prefix_style.empty?
|
500
|
-
|
501
|
+
(prefix + suffix).join(" ")
|
501
502
|
else
|
502
503
|
colorized_prefix = Autobuild.color(prefix.join(" "), *prefix_style)
|
503
|
-
|
504
|
+
[colorized_prefix, *suffix].join(" ")
|
504
505
|
end
|
505
506
|
end
|
506
507
|
|
@@ -527,7 +528,7 @@ module Autobuild
|
|
527
528
|
args[0] = process_formatting_string(args[0], :bold)
|
528
529
|
done_message = process_formatting_string(done_message) if done_message
|
529
530
|
Autobuild.progress_start(self, *args,
|
530
|
-
|
531
|
+
done_message: done_message, **raw_options, &block)
|
531
532
|
end
|
532
533
|
|
533
534
|
def progress(*args)
|
@@ -663,6 +664,10 @@ module Autobuild
|
|
663
664
|
end
|
664
665
|
end
|
665
666
|
|
667
|
+
def self_fingerprint
|
668
|
+
importer.fingerprint(self)
|
669
|
+
end
|
670
|
+
|
666
671
|
# Returns a unique hash representing a state of the package and
|
667
672
|
# its dependencies, if any dependency can't calculate its own
|
668
673
|
# fingerprint the result will be nil
|
@@ -670,18 +675,23 @@ module Autobuild
|
|
670
675
|
def fingerprint(recursive: true, memo: {})
|
671
676
|
return memo[name] if memo.key?(name)
|
672
677
|
|
673
|
-
self_fingerprint =
|
678
|
+
self_fingerprint = self.self_fingerprint
|
674
679
|
return unless self_fingerprint
|
675
|
-
|
680
|
+
if dependencies.empty?
|
681
|
+
return (memo[name] = self_fingerprint)
|
682
|
+
elsif !recursive
|
683
|
+
return self_fingerprint
|
684
|
+
end
|
676
685
|
|
677
686
|
dependency_fingerprints = dependencies.sort.map do |pkg_name|
|
678
687
|
pkg = Autobuild::Package[pkg_name]
|
679
688
|
unless (fingerprint = memo[pkg.name])
|
680
689
|
fingerprint = pkg.fingerprint(recursive: true, memo: memo)
|
681
|
-
|
690
|
+
break unless fingerprint
|
682
691
|
end
|
683
692
|
fingerprint
|
684
693
|
end
|
694
|
+
return unless dependency_fingerprints
|
685
695
|
|
686
696
|
memo[name] = Digest::SHA1.hexdigest(
|
687
697
|
self_fingerprint + dependency_fingerprints.join(""))
|
@@ -829,7 +839,7 @@ module Autobuild
|
|
829
839
|
end
|
830
840
|
|
831
841
|
# Make sure that this package will be ignored in the build
|
832
|
-
def disable(
|
842
|
+
def disable(_phases = Autobuild.all_phases)
|
833
843
|
@disabled = true
|
834
844
|
end
|
835
845
|
|
@@ -25,13 +25,8 @@ module Autobuild
|
|
25
25
|
# To override this default behaviour on a per-package basis, use Autotools#use
|
26
26
|
#
|
27
27
|
class Autotools < Configurable
|
28
|
-
attr_accessor
|
29
|
-
|
30
|
-
attr_accessor :aclocal_flags
|
31
|
-
attr_accessor :autoheader_flags
|
32
|
-
attr_accessor :autoconf_flags
|
33
|
-
attr_accessor :automake_flags
|
34
|
-
attr_accessor :bear_flags
|
28
|
+
attr_accessor :using, :configureflags, :aclocal_flags, :autoheader_flags,
|
29
|
+
:autoconf_flags, :automake_flags, :bear_flags
|
35
30
|
|
36
31
|
@builddir = 'build'
|
37
32
|
@@enable_bear_globally = false
|
@@ -151,7 +146,7 @@ module Autobuild
|
|
151
146
|
FileUtils.rm_f configurestamp
|
152
147
|
end
|
153
148
|
|
154
|
-
def import(options
|
149
|
+
def import(**options)
|
155
150
|
# We force a regen after the first checkout. The issue is that
|
156
151
|
# autotools is less robust than it should, and very often it is
|
157
152
|
# better to generate the build system for the system on which we
|
@@ -278,7 +273,7 @@ module Autobuild
|
|
278
273
|
file conffile => "#{conffile}#{confext}"
|
279
274
|
elsif using[:autoconf]
|
280
275
|
raise PackageException.new(self, 'prepare'),
|
281
|
-
|
276
|
+
"neither configure.ac nor configure.in present in #{srcdir}"
|
282
277
|
end
|
283
278
|
|
284
279
|
file conffile do
|