autobuild 1.18.1 → 1.22.0

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.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/lint.yml +25 -0
  3. data/.github/workflows/test.yml +30 -0
  4. data/.rubocop.yml +14 -7
  5. data/autobuild.gemspec +8 -6
  6. data/bin/autobuild +1 -1
  7. data/lib/autobuild/build_logfile.rb +1 -2
  8. data/lib/autobuild/config.rb +18 -5
  9. data/lib/autobuild/configurable.rb +3 -1
  10. data/lib/autobuild/environment.rb +28 -45
  11. data/lib/autobuild/exceptions.rb +11 -5
  12. data/lib/autobuild/import/archive.rb +31 -22
  13. data/lib/autobuild/import/cvs.rb +6 -6
  14. data/lib/autobuild/import/darcs.rb +4 -4
  15. data/lib/autobuild/import/git-lfs.rb +4 -4
  16. data/lib/autobuild/import/git.rb +153 -68
  17. data/lib/autobuild/import/hg.rb +7 -7
  18. data/lib/autobuild/import/svn.rb +15 -9
  19. data/lib/autobuild/importer.rb +38 -38
  20. data/lib/autobuild/mail_reporter.rb +5 -2
  21. data/lib/autobuild/package.rb +45 -35
  22. data/lib/autobuild/packages/autotools.rb +3 -8
  23. data/lib/autobuild/packages/cmake.rb +16 -7
  24. data/lib/autobuild/packages/dummy.rb +0 -4
  25. data/lib/autobuild/packages/gnumake.rb +1 -1
  26. data/lib/autobuild/packages/orogen.rb +11 -4
  27. data/lib/autobuild/packages/pkgconfig.rb +2 -2
  28. data/lib/autobuild/packages/python.rb +6 -8
  29. data/lib/autobuild/packages/ruby.rb +5 -5
  30. data/lib/autobuild/parallel.rb +20 -21
  31. data/lib/autobuild/pkgconfig.rb +1 -0
  32. data/lib/autobuild/progress_display.rb +130 -49
  33. data/lib/autobuild/rake_task_extension.rb +16 -5
  34. data/lib/autobuild/reporting.rb +20 -7
  35. data/lib/autobuild/subcommand.rb +24 -23
  36. data/lib/autobuild/test_utility.rb +2 -1
  37. data/lib/autobuild/timestamps.rb +3 -3
  38. data/lib/autobuild/utility.rb +54 -8
  39. data/lib/autobuild/version.rb +1 -1
  40. data/lib/autobuild.rb +0 -3
  41. metadata +42 -26
  42. data/.travis.yml +0 -19
@@ -106,6 +106,7 @@ module Autobuild
106
106
  @auto_update = (ENV['AUTOBUILD_ARCHIVE_AUTOUPDATE'] == '1')
107
107
 
108
108
  attr_writer :update_cached_file
109
+
109
110
  def update_cached_file?
110
111
  @update_cached_file
111
112
  end
@@ -118,15 +119,16 @@ module Autobuild
118
119
 
119
120
  Net::HTTP.start(
120
121
  uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http|
121
-
122
122
  http.request(request) do |resp|
123
123
  case resp
124
124
  when Net::HTTPNotModified
125
125
  return false
126
126
  when Net::HTTPSuccess
127
- if current_time && (last_modified = resp['last-modified'])
128
- return false if current_time >= Time.rfc2822(last_modified)
127
+ if current_time && (last_modified = resp['last-modified']) &&
128
+ (current_time >= Time.rfc2822(last_modified))
129
+ return false
129
130
  end
131
+
130
132
  if (length = resp['Content-Length'])
131
133
  length = Integer(length)
132
134
  expected_size = "/#{Autobuild.human_readable_size(length)}"
@@ -158,11 +160,12 @@ module Autobuild
158
160
  end
159
161
 
160
162
  return download_http(package, URI(redirect_uri), filename,
161
- user: user, password: password, current_time: current_time)
163
+ user: user, password: password,
164
+ current_time: current_time)
162
165
  else
163
166
  raise PackageException.new(package, 'import'),
164
- "failed download of #{package.name} from #{uri}: "\
165
- "#{resp.class}"
167
+ "failed download of #{package.name} from #{uri}: "\
168
+ "#{resp.class}"
166
169
  end
167
170
  end
168
171
  end
@@ -204,19 +207,19 @@ module Autobuild
204
207
  end
205
208
 
206
209
  if mtime && size
207
- return size != cached_size || mtime > cached_mtime
210
+ size != cached_size || mtime > cached_mtime
208
211
  elsif mtime
209
212
  package.warn "%s: archive size is not available for #{@url}, "\
210
213
  "relying on modification time"
211
- return mtime > cached_mtime
214
+ mtime > cached_mtime
212
215
  elsif size
213
216
  package.warn "%s: archive modification time "\
214
217
  "is not available for #{@url}, relying on size"
215
- return size != cached_size
218
+ size != cached_size
216
219
  else
217
220
  package.warn "%s: neither the archive size nor its modification time "\
218
221
  "are available for #{@url}, will always update"
219
- return true
222
+ true
220
223
  end
221
224
  end
222
225
 
@@ -231,8 +234,8 @@ module Autobuild
231
234
  end
232
235
 
233
236
  updated = download_http(package, @url, "#{cachefile}.partial",
234
- user: @user, password: @password,
235
- current_time: cached_mtime)
237
+ user: @user, password: @password,
238
+ current_time: cached_mtime)
236
239
  return false unless updated
237
240
  elsif Autobuild.bsd?
238
241
  return false unless update_needed?(package)
@@ -250,8 +253,8 @@ module Autobuild
250
253
  additional_options << "--tries" << retries
251
254
  end
252
255
  package.run(:import, Autobuild.tool('wget'), '-q', '-P', cachedir,
253
- *additional_options, @url, '-O', "#{cachefile}.partial",
254
- retry: true)
256
+ *additional_options, @url, '-O', "#{cachefile}.partial",
257
+ retry: true)
255
258
  end
256
259
  rescue Exception
257
260
  FileUtils.rm_f "#{cachefile}.partial"
@@ -264,13 +267,15 @@ module Autobuild
264
267
  # Updates the downloaded file in cache only if it is needed
265
268
  #
266
269
  # @return [Boolean] true if a new file was downloaded, false otherwise
267
- # @raises ConfigException if a expected digest was given in the source.yml file and it doesn't match
270
+ # @raises ConfigException if a expected digest was given in the
271
+ # source.yml file and it doesn't match
268
272
  def update_cache(package)
269
273
  updated = download_from_url(package)
270
274
  @cachefile_digest = read_cachefile_digest
271
275
 
272
276
  if @expected_digest && @expected_digest != @cachefile_digest
273
- raise ConfigException, "The archive #{@url.to_s} does not match the digest provided"
277
+ raise ConfigException,
278
+ "The archive #{@url} does not match the digest provided"
274
279
  end
275
280
 
276
281
  updated
@@ -279,11 +284,11 @@ module Autobuild
279
284
  def read_cachefile_digest
280
285
  Digest::SHA1.hexdigest File.read(cachefile)
281
286
  end
282
-
287
+
283
288
  # Fingerprint for archive importer, we are using
284
289
  # its digest whether is calculated or expected
285
290
  # @raises ConfigException if no digest is present
286
- def vcs_fingerprint(package)
291
+ def vcs_fingerprint(_package)
287
292
  if @cachefile_digest
288
293
  @cachefile_digest
289
294
  elsif File.file?(cachefile)
@@ -291,7 +296,9 @@ module Autobuild
291
296
  elsif @expected_digest
292
297
  @expected_digest
293
298
  else
294
- raise ConfigException, "There is no digest for archive #{@url.to_s}, make sure cache directories are configured correctly"
299
+ raise ConfigException,
300
+ "There is no digest for archive #{@url}, make sure "\
301
+ "cache directories are configured correctly"
295
302
  end
296
303
  end
297
304
 
@@ -378,9 +385,11 @@ module Autobuild
378
385
  # [:mode] The unpack mode: one of Zip, Bzip, Gzip or Plain, this is
379
386
  # usually automatically inferred from the filename
380
387
  def initialize(url, options = Hash.new)
381
- sourceopts, options = Kernel.filter_options options,
388
+ sourceopts, options = Kernel.filter_options(
389
+ options,
382
390
  :source_id, :repository_id, :filename, :mode, :update_cached_file,
383
391
  :user, :password, :expected_digest
392
+ )
384
393
  super(options)
385
394
 
386
395
  @filename = nil
@@ -452,7 +461,7 @@ module Autobuild
452
461
  end
453
462
 
454
463
  if needs_update || archive_changed?(package)
455
- return checkout(package, allow_interactive: options[:allow_interactive])
464
+ checkout(package, allow_interactive: options[:allow_interactive])
456
465
  else
457
466
  false
458
467
  end
@@ -477,7 +486,7 @@ module Autobuild
477
486
 
478
487
  def checkout(package, options = Hash.new) # :nodoc:
479
488
  options = Kernel.validate_options options,
480
- allow_interactive: true
489
+ allow_interactive: true
481
490
 
482
491
  update_cache(package)
483
492
 
@@ -10,7 +10,7 @@ module Autobuild
10
10
  # Autobuild.programs['cvs'] = 'my_cvs_tool'
11
11
  def initialize(root_name, options = {})
12
12
  cvsopts, common = Kernel.filter_options options,
13
- module: nil, cvsup: '-dP', cvsco: '-P'
13
+ module: nil, cvsup: '-dP', cvsco: '-P'
14
14
  @root = root_name
15
15
  @module = cvsopts[:module]
16
16
  raise ArgumentError, "no module given" unless @module
@@ -41,7 +41,7 @@ module Autobuild
41
41
 
42
42
  unless File.exist?("#{package.srcdir}/CVS/Root")
43
43
  raise ConfigException.new(package, 'import'),
44
- "#{package.srcdir} is not a CVS working copy"
44
+ "#{package.srcdir} is not a CVS working copy"
45
45
  end
46
46
 
47
47
  root = File.open("#{package.srcdir}/CVS/Root", &:read).chomp
@@ -56,8 +56,8 @@ module Autobuild
56
56
 
57
57
  if root != expected_root || mod != @module
58
58
  raise ConfigException.new(package, 'import'),
59
- "checkout in #{package.srcdir} is from #{root}:#{mod}, "\
60
- "was expecting #{expected_root}:#{@module}"
59
+ "checkout in #{package.srcdir} is from #{root}:#{mod}, "\
60
+ "was expecting #{expected_root}:#{@module}"
61
61
  end
62
62
  package.run(:import, Autobuild.tool(:cvs), 'up', *@options_up,
63
63
  retry: true, working_directory: package.importdir)
@@ -72,8 +72,8 @@ module Autobuild
72
72
 
73
73
  FileUtils.mkdir_p(head) unless File.directory?(head)
74
74
  package.run(:import, Autobuild.tool(:cvs), '-d', cvsroot, 'co',
75
- '-d', tail, *@options_co, modulename,
76
- retry: true, working_directory: head)
75
+ '-d', tail, *@options_co, modulename,
76
+ retry: true, working_directory: head)
77
77
  end
78
78
  end
79
79
 
@@ -28,12 +28,12 @@ module Autobuild
28
28
  end
29
29
  unless File.directory?(File.join(package.srcdir, '_darcs'))
30
30
  raise ConfigException.new(package, 'import'),
31
- "#{package.srcdir} is not a Darcs repository"
31
+ "#{package.srcdir} is not a Darcs repository"
32
32
  end
33
33
 
34
34
  package.run(:import, @program, 'pull', '--all',
35
- "--repodir=#{package.srcdir}", '--set-scripts-executable',
36
- @source, *@pull, retry: true)
35
+ "--repodir=#{package.srcdir}", '--set-scripts-executable',
36
+ @source, *@pull, retry: true)
37
37
  true # no easy to know if package was updated, keep previous behavior
38
38
  end
39
39
 
@@ -42,7 +42,7 @@ module Autobuild
42
42
  FileUtils.mkdir_p(basedir) unless File.directory?(basedir)
43
43
 
44
44
  package.run(:import, @program, 'get', '--set-scripts-executable',
45
- @source, package.srcdir, *@get, retry: true)
45
+ @source, package.srcdir, *@get, retry: true)
46
46
  end
47
47
  end
48
48
 
@@ -10,26 +10,26 @@ module Autobuild
10
10
  if includes.empty?
11
11
  begin
12
12
  importer.run_git_bare(package, 'config', '--local',
13
- '--unset', 'lfs.fetchinclude')
13
+ '--unset', 'lfs.fetchinclude')
14
14
  rescue SubcommandFailed => e
15
15
  raise if e.status != 5
16
16
  end
17
17
  else
18
18
  importer.run_git_bare(package, 'config', '--local',
19
- 'lfs.fetchinclude', includes)
19
+ 'lfs.fetchinclude', includes)
20
20
  end
21
21
 
22
22
  excludes = importer.options.fetch(:lfs_exclude, '')
23
23
  if excludes.empty?
24
24
  begin
25
25
  importer.run_git_bare(package, 'config', '--local',
26
- '--unset', 'lfs.fetchexclude')
26
+ '--unset', 'lfs.fetchexclude')
27
27
  rescue SubcommandFailed => e
28
28
  raise if e.status != 5
29
29
  end
30
30
  else
31
31
  importer.run_git_bare(package, 'config', '--local',
32
- 'lfs.fetchexclude', excludes)
32
+ 'lfs.fetchexclude', excludes)
33
33
  end
34
34
 
35
35
  if importer.options[:lfs] != false
@@ -7,6 +7,9 @@ require 'English'
7
7
 
8
8
  module Autobuild
9
9
  class Git < Importer
10
+ # Exception raised when a network access is needed while only_local is true
11
+ class NetworkAccessNeeded < RuntimeError; end
12
+
10
13
  class << self
11
14
  # Sets the default alternates path used by all Git importers
12
15
  #
@@ -24,6 +27,11 @@ module Autobuild
24
27
  # AUTOBUILD_GIT_CACHE_DIR and AUTOBUILD_CACHE_DIR environment
25
28
  # variables
26
29
  #
30
+ # Because of its role within the caching system in autobuild/autoproj,
31
+ # these defaults are not applied to git repositories that are using
32
+ # submodules. The autoproj cache builder does not generate repositories
33
+ # compatible with having submodules
34
+ #
27
35
  # @return [Array]
28
36
  # @see default_alternates=, Git#alternates
29
37
  def default_alternates
@@ -49,7 +57,7 @@ module Autobuild
49
57
  def self.version
50
58
  version = Subprocess.run('git', 'setup', Autobuild.tool(:git), '--version').
51
59
  first
52
- if version =~ /^git version (\d[\d\.]+)/
60
+ if version =~ /^git version (\d[\d.]+)/
53
61
  $1.split(".").map { |i| Integer(i) }
54
62
  else
55
63
  raise ArgumentError, "cannot parse git version string #{version}, "\
@@ -111,7 +119,6 @@ module Autobuild
111
119
  # workflow, it is recommended to not use submodules but checkout all
112
120
  # repositories separately instead.
113
121
  def initialize(repository, branch = nil, options = {})
114
- @alternates = Git.default_alternates.dup
115
122
  @git_dir_cache = Array.new
116
123
  @local_branch = @remote_branch = nil
117
124
  @tag = @commit = nil
@@ -135,16 +142,16 @@ module Autobuild
135
142
  end
136
143
 
137
144
  gitopts, common = Kernel.filter_options options,
138
- push_to: nil,
139
- branch: nil,
140
- local_branch: nil,
141
- remote_branch: nil,
142
- tag: nil,
143
- commit: nil,
144
- repository_id: nil,
145
- source_id: nil,
146
- with_submodules: false,
147
- single_branch: false
145
+ push_to: nil,
146
+ branch: nil,
147
+ local_branch: nil,
148
+ remote_branch: nil,
149
+ tag: nil,
150
+ commit: nil,
151
+ repository_id: nil,
152
+ source_id: nil,
153
+ with_submodules: false,
154
+ single_branch: false
148
155
  if gitopts[:branch] && branch
149
156
  raise ConfigException, "git branch specified with both the option hash "\
150
157
  "and the explicit parameter"
@@ -155,6 +162,13 @@ module Autobuild
155
162
 
156
163
  @single_branch = gitopts[:single_branch]
157
164
  @with_submodules = gitopts.delete(:with_submodules)
165
+ @alternates =
166
+ if @with_submodules
167
+ []
168
+ else
169
+ Git.default_alternates.dup
170
+ end
171
+
158
172
  @remote_name = 'autobuild'
159
173
  @push_to = nil
160
174
  relocate(repository, gitopts)
@@ -282,6 +296,66 @@ module Autobuild
282
296
  git_dir(package, true)
283
297
  end
284
298
 
299
+ # Return the remote head branch from local copy if exists, if not return nil
300
+ #
301
+ # @param [Package] package
302
+ def try_resolve_remote_head_from_local(package)
303
+ ls_local_string = run_git(package, 'symbolic-ref',
304
+ "refs/remotes/#{@remote_name}/HEAD").first.strip
305
+ local_remote_head = ls_local_string.match("refs/remotes/#{@remote_name}/(.*)")
306
+ local_remote_head ? local_remote_head[1] : nil
307
+ rescue Autobuild::SubcommandFailed # rubocop:disable Lint/SuppressedException
308
+ end
309
+
310
+ # Return the remote head branch from server if exists, if not return 'master'
311
+ #
312
+ # @param [Package] package
313
+ def try_resolve_remote_head_from_server(package)
314
+ ls_remote_string = package.run(
315
+ :import,
316
+ Autobuild.tool('git'), 'ls-remote', '--symref', repository
317
+ ).first.strip
318
+ server_remote_head =
319
+ ls_remote_string.match("ref:[^A-z]refs/heads/(.*)[^A-z]HEAD")
320
+ server_remote_head ? server_remote_head[1] : 'master'
321
+ end
322
+
323
+ # Return default local branch if exists, if not return the default remote branch
324
+ #
325
+ # @param [Package] package
326
+ def resolve_remote_head(package, only_local: false)
327
+ try_resolve_remote_head_from_local(package) ||
328
+ (!only_local && try_resolve_remote_head_from_server(package))
329
+ end
330
+
331
+ # Whether both the local and remote branches are known
332
+ #
333
+ # See documentation of {#resolve_all_branches}
334
+ def has_all_branches?
335
+ remote_branch && local_branch
336
+ end
337
+
338
+ # Resolve branches based on the remote's HEAD
339
+ #
340
+ # Since GitHub (and others) decided to change the name of the "default"
341
+ # branch, we can't assume that master is ... well ... master.
342
+ #
343
+ # For this reason, a Git importer does not have a built-in default.
344
+ # If the branch(es) are not provided explicitly, the importer will
345
+ # call this method to guess the name of the default branch instead.
346
+ #
347
+ # Call {#has_all_branches?} to determine whether it is necessary
348
+ def resolve_all_branches(package, only_local: false)
349
+ default_branch = resolve_remote_head(package, only_local: only_local)
350
+ unless default_branch
351
+ raise NetworkAccessNeeded,
352
+ "determining the remote branch would require access to "\
353
+ "the network, and only_local is true"
354
+ end
355
+
356
+ relocate(repository, default_branch: default_branch)
357
+ end
358
+
285
359
  # @api private
286
360
  #
287
361
  # Resolves the git directory associated with path, and tells whether it
@@ -355,12 +429,12 @@ module Autobuild
355
429
  def self.validate_git_dir(package, require_working_copy, _dir, style)
356
430
  if !style
357
431
  raise ConfigException.new(package, 'import', retry: false),
358
- "while importing #{package.name}, #{package.importdir} "\
359
- "does not point to a git repository"
432
+ "while importing #{package.name}, #{package.importdir} "\
433
+ "does not point to a git repository"
360
434
  elsif require_working_copy && (style == :bare)
361
435
  raise ConfigException.new(package, 'import', retry: false),
362
- "while importing #{package.name}, #{package.importdir} "\
363
- "points to a bare git repository but a working copy was required"
436
+ "while importing #{package.name}, #{package.importdir} "\
437
+ "points to a bare git repository but a working copy was required"
364
438
  end
365
439
  end
366
440
 
@@ -466,21 +540,24 @@ module Autobuild
466
540
  #
467
541
  # Set a remote up in the repositorie's configuration
468
542
  def setup_remote(package, remote_name, repository, push_to = repository)
543
+ resolve_all_branches(package, only_local: true) unless has_all_branches?
544
+
469
545
  run_git_bare(package, 'config', '--replace-all',
470
- "remote.#{remote_name}.url", repository)
546
+ "remote.#{remote_name}.url", repository)
471
547
  run_git_bare(package, 'config', '--replace-all',
472
- "remote.#{remote_name}.pushurl", push_to || repository)
548
+ "remote.#{remote_name}.pushurl", push_to || repository)
473
549
  run_git_bare(package, 'config', '--replace-all',
474
- "remote.#{remote_name}.fetch",
475
- "+refs/heads/*:refs/remotes/#{remote_name}/*")
550
+ "remote.#{remote_name}.fetch",
551
+ "+refs/heads/*:refs/remotes/#{remote_name}/*")
476
552
 
477
553
  if remote_branch && local_branch
554
+ remote_ref = remote_branch_to_ref(remote_branch)
478
555
  run_git_bare(package, 'config', '--replace-all',
479
- "remote.#{remote_name}.push",
480
- "refs/heads/#{local_branch}:#{remote_branch_to_ref(remote_branch)}")
556
+ "remote.#{remote_name}.push",
557
+ "refs/heads/#{local_branch}:#{remote_ref}")
481
558
  else
482
559
  run_git_bare(package, 'config', '--replace-all',
483
- "remote.#{remote_name}.push", "refs/heads/*:refs/heads/*")
560
+ "remote.#{remote_name}.push", "refs/heads/*:refs/heads/*")
484
561
  end
485
562
  end
486
563
 
@@ -506,16 +583,17 @@ module Autobuild
506
583
 
507
584
  if local_branch
508
585
  run_git_bare(package, 'config', '--replace-all',
509
- "branch.#{local_branch}.remote", remote_name)
586
+ "branch.#{local_branch}.remote", remote_name)
510
587
  run_git_bare(package, 'config', '--replace-all',
511
- "branch.#{local_branch}.merge", remote_branch_to_ref(local_branch))
588
+ "branch.#{local_branch}.merge",
589
+ remote_branch_to_ref(local_branch))
512
590
  end
513
591
  end
514
592
 
515
593
  # Resolve a commit ref to a tag or commit ID
516
594
  def describe_rev(package, rev)
517
595
  tag = run_git_bare(package, 'describe',
518
- '--tags', '--exact-match', rev).first.strip
596
+ '--tags', '--exact-match', rev).first.strip
519
597
  [true, tag.encode('UTF-8')]
520
598
  rescue Autobuild::SubcommandFailed
521
599
  commit = rev_parse(package, rev)
@@ -573,7 +651,7 @@ module Autobuild
573
651
  refspec.zip(fetched_commits).each do |spec, commit_id|
574
652
  if spec =~ %r{^refs/heads/(.*)$}
575
653
  run_git_bare(package, 'update-ref', "-m", "updated by autobuild",
576
- "refs/remotes/#{remote_name}/#{$1}", commit_id)
654
+ "refs/remotes/#{remote_name}/#{$1}", commit_id)
577
655
  end
578
656
  end
579
657
 
@@ -630,7 +708,7 @@ module Autobuild
630
708
  run_git_bare(package, 'show-ref', '-s', refspec).first.strip
631
709
  rescue SubcommandFailed
632
710
  raise PackageException.new(package, "import"),
633
- "cannot resolve #{refspec}"
711
+ "cannot resolve #{refspec}"
634
712
  end
635
713
  else
636
714
  refspec =
@@ -639,7 +717,7 @@ module Autobuild
639
717
  remote_branch_to_ref(remote_branch)
640
718
  begin fetch_remote(package, refspec: refspec)
641
719
  rescue Exception => e
642
- return fallback(e, package, :status, package, only_local)
720
+ fallback(e, package, :status, package, only_local)
643
721
  end
644
722
  end
645
723
  end
@@ -655,6 +733,8 @@ module Autobuild
655
733
  end
656
734
 
657
735
  validate_importdir(package)
736
+ resolve_all_branches(package, only_local: only_local) unless has_all_branches?
737
+
658
738
  _pinned_state, target_commit, = determine_target_state(
659
739
  package, only_local: only_local)
660
740
 
@@ -685,7 +765,7 @@ module Autobuild
685
765
 
686
766
  def has_branch?(package, branch_name)
687
767
  run_git_bare(package, 'show-ref', '-q', '--verify',
688
- remote_branch_to_ref(branch_name))
768
+ remote_branch_to_ref(branch_name))
689
769
  true
690
770
  rescue SubcommandFailed => e
691
771
  if e.status == 1
@@ -695,7 +775,7 @@ module Autobuild
695
775
  end
696
776
 
697
777
  def has_local_branch?(package)
698
- has_branch?(package, local_branch)
778
+ has_branch?(package, local_branch) if local_branch
699
779
  end
700
780
 
701
781
  def detached_head?(package)
@@ -703,6 +783,8 @@ module Autobuild
703
783
  end
704
784
 
705
785
  private def remote_branch_to_ref(branch)
786
+ return unless branch
787
+
706
788
  if branch.start_with?("refs/")
707
789
  branch
708
790
  else
@@ -739,9 +821,7 @@ module Autobuild
739
821
  #
740
822
  # This is the value returned by {Git#status}
741
823
  class Status < Importer::Status
742
- attr_reader :fetch_commit
743
- attr_reader :head_commit
744
- attr_reader :common_commit
824
+ attr_reader :fetch_commit, :head_commit, :common_commit
745
825
 
746
826
  def initialize(package, status, remote_commit, local_commit, common_commit)
747
827
  super()
@@ -786,8 +866,8 @@ module Autobuild
786
866
  run_git_bare(package, 'rev-parse', '-q', '--verify', name).first
787
867
  rescue Autobuild::SubcommandFailed
788
868
  raise PackageException.new(package, 'import'),
789
- "failed to resolve #{name}. "\
790
- "Are you sure this commit, branch or tag exists ?"
869
+ "failed to resolve #{name}. "\
870
+ "Are you sure this commit, branch or tag exists ?"
791
871
  end
792
872
 
793
873
  # Returns the file's conents at a certain commit
@@ -800,7 +880,7 @@ module Autobuild
800
880
  run_git_bare(package, 'show', "#{commit}:#{path}").join("\n")
801
881
  rescue Autobuild::SubcommandFailed
802
882
  raise PackageException.new(package, 'import'),
803
- "failed to either resolve commit #{commit} or file #{path}"
883
+ "failed to either resolve commit #{commit} or file #{path}"
804
884
  end
805
885
 
806
886
  # Tests whether a commit is already present in a given history
@@ -834,7 +914,7 @@ module Autobuild
834
914
  def describe_commit_on_remote(package, rev = 'HEAD', options = Hash.new)
835
915
  rev = rev.to_str
836
916
  options = Kernel.validate_options options,
837
- tags: true
917
+ tags: true
838
918
 
839
919
  commit_id = rev_parse(package, rev)
840
920
 
@@ -864,15 +944,13 @@ module Autobuild
864
944
  end
865
945
 
866
946
  remote_refs.delete_if do |rev_name, rev_id|
867
- begin
868
947
  if commit_present_in?(package, commit_id, rev_id)
869
948
  return rev_name
870
949
  else
871
950
  true
872
951
  end
873
- rescue PackageException
952
+ rescue PackageException
874
953
  false
875
- end
876
954
  end
877
955
 
878
956
  unless remote_refs.empty?
@@ -898,7 +976,7 @@ module Autobuild
898
976
  def merge_status(package, fetch_commit, reference_commit = "HEAD")
899
977
  begin
900
978
  common_commit = run_git_bare(package, 'merge-base',
901
- reference_commit, fetch_commit).first.strip
979
+ reference_commit, fetch_commit).first.strip
902
980
  rescue Exception
903
981
  raise PackageException.new(package, 'import'), "failed to find "\
904
982
  "the merge-base between #{reference_commit} and #{fetch_commit}. "\
@@ -931,7 +1009,7 @@ module Autobuild
931
1009
  # @return [void]
932
1010
  def update_alternates(package)
933
1011
  alternates_path = File.join(git_dir(package, false),
934
- 'objects', 'info', 'alternates')
1012
+ 'objects', 'info', 'alternates')
935
1013
  current_alternates =
936
1014
  if File.file?(alternates_path)
937
1015
  File.readlines(alternates_path)
@@ -996,18 +1074,18 @@ module Autobuild
996
1074
  # changes
997
1075
  unless commit_present_in?(package, current_head, fetch_commit)
998
1076
  raise ImporterCannotReset.new(package, 'import'),
999
- "branch #{local_branch} of #{package.name} contains"\
1000
- " commits that do not seem to be present on the branch"\
1001
- " #{remote_branch} of the remote repository. I can't"\
1002
- " go on as it could make you lose some stuff. Update"\
1003
- " the remote branch in your overrides, push your"\
1004
- " changes or reset to the remote commit manually"\
1005
- " before trying again"
1077
+ "branch #{local_branch} of #{package.name} contains"\
1078
+ " commits that do not seem to be present on the branch"\
1079
+ " #{remote_branch} of the remote repository. I can't"\
1080
+ " go on as it could make you lose some stuff. Update"\
1081
+ " the remote branch in your overrides, push your"\
1082
+ " changes or reset to the remote commit manually"\
1083
+ " before trying again"
1006
1084
  end
1007
1085
  end
1008
1086
 
1009
1087
  package.message format(" %%s: resetting branch %<branch>s to %<commit>s",
1010
- branch: local_branch, commit: target_commit)
1088
+ branch: local_branch, commit: target_commit)
1011
1089
  # I don't use a reset --hard here as it would add even more
1012
1090
  # restrictions on when we can do the operation (as we would refuse
1013
1091
  # doing it if there are local changes). The checkout creates a
@@ -1018,7 +1096,7 @@ module Autobuild
1018
1096
  begin
1019
1097
  run_git(package, 'checkout', target_commit)
1020
1098
  run_git(package, 'update-ref', "refs/heads/#{local_branch}",
1021
- resolved_target_commit)
1099
+ resolved_target_commit)
1022
1100
  run_git(package, 'symbolic-ref', "HEAD", "refs/heads/#{local_branch}")
1023
1101
  rescue ::Exception
1024
1102
  run_git(package, 'symbolic-ref', "HEAD", target_commit)
@@ -1054,6 +1132,9 @@ module Autobuild
1054
1132
  # @option (see Package#update)
1055
1133
  def update(package, options = Hash.new)
1056
1134
  validate_importdir(package)
1135
+
1136
+ resolve_all_branches(package) unless has_all_branches?
1137
+
1057
1138
  only_local = options.fetch(:only_local, false)
1058
1139
  reset = options.fetch(:reset, false)
1059
1140
 
@@ -1073,20 +1154,21 @@ module Autobuild
1073
1154
  end
1074
1155
 
1075
1156
  unless pin_is_uptodate
1076
- fetch_commit ||= current_remote_commit(package,
1077
- only_local: only_local,
1078
- refspec: [remote_branch_to_ref(remote_branch), tag])
1157
+ fetch_commit ||= current_remote_commit(
1158
+ package, only_local: only_local,
1159
+ refspec: [remote_branch_to_ref(remote_branch), tag]
1160
+ )
1079
1161
  did_update =
1080
1162
  if reset
1081
1163
  reset_head_to_commit(package, target_commit, fetch_commit,
1082
- force: (reset == :force))
1164
+ force: (reset == :force))
1083
1165
  else
1084
1166
  merge_if_simple(package, target_commit)
1085
1167
  end
1086
1168
  end
1087
1169
 
1088
1170
  if !only_local && with_submodules?
1089
- run_git(package, "submodule", "update", '--init')
1171
+ run_git(package, "submodule", "update", '--init', '--recursive')
1090
1172
  did_update = true
1091
1173
  end
1092
1174
 
@@ -1096,12 +1178,12 @@ module Autobuild
1096
1178
  private def ensure_on_local_branch(package, target_commit)
1097
1179
  if !has_local_branch?(package)
1098
1180
  package.message format("%%s: checking out branch %<branch>s",
1099
- branch: local_branch)
1181
+ branch: local_branch)
1100
1182
  run_git(package, 'checkout', '-b', local_branch, target_commit)
1101
1183
  true
1102
1184
  elsif !on_local_branch?(package)
1103
1185
  package.message format("%%s: switching to branch %<branch>s",
1104
- branch: local_branch)
1186
+ branch: local_branch)
1105
1187
  run_git(package, 'checkout', local_branch)
1106
1188
  true
1107
1189
  else
@@ -1184,27 +1266,30 @@ module Autobuild
1184
1266
  clone_options << "--config=#{key}=#{value}"
1185
1267
  end
1186
1268
  package.run(:import,
1187
- Autobuild.tool('git'), 'clone', '-o', remote_name, *clone_options,
1188
- repository, package.importdir, retry: true)
1269
+ Autobuild.tool('git'), 'clone', '-o', remote_name, *clone_options,
1270
+ repository, package.importdir, retry: true)
1189
1271
 
1190
1272
  update_remotes_configuration(package)
1191
- update(package, only_local: !remote_branch.start_with?("refs/"), reset: true)
1192
- run_git(package, "submodule", "update", '--init') if with_submodules?
1273
+ update(package, only_local: !remote_branch.start_with?("refs/"),
1274
+ reset: :force)
1275
+ if with_submodules?
1276
+ run_git(package, "submodule", "update", '--init', '--recursive')
1277
+ end
1193
1278
  end
1194
1279
 
1195
1280
  # Changes the repository this importer is pointing to
1196
1281
  def relocate(repository, options = Hash.new)
1197
- options = Hash[options.map { |k, v| [k.to_sym, v] }]
1282
+ options = options.transform_keys(&:to_sym)
1198
1283
 
1199
1284
  local_branch =
1200
1285
  options[:local_branch] || options[:branch] ||
1201
- self.local_branch || 'master'
1286
+ self.local_branch || options[:default_branch] || nil
1202
1287
  remote_branch =
1203
1288
  options[:remote_branch] || options[:branch] ||
1204
- self.remote_branch || 'master'
1205
- if local_branch.start_with?("refs/")
1289
+ self.remote_branch || options[:default_branch] || nil
1290
+ if local_branch&.start_with?("refs/")
1206
1291
  raise ArgumentError, "you cannot provide a full ref for"\
1207
- " the local branch, only for the remote branch"
1292
+ " the local branch, only for the remote branch"
1208
1293
  end
1209
1294
 
1210
1295
  @push_to = options[:push_to] || @push_to