autobuild 1.19.0 → 1.22.1

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 +149 -70
  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 +24 -14
  22. data/lib/autobuild/packages/autotools.rb +4 -9
  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 +1 -2
  29. data/lib/autobuild/packages/ruby.rb +5 -5
  30. data/lib/autobuild/parallel.rb +12 -17
  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 +6 -0
  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 +29 -9
  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
  #
@@ -54,7 +57,7 @@ module Autobuild
54
57
  def self.version
55
58
  version = Subprocess.run('git', 'setup', Autobuild.tool(:git), '--version').
56
59
  first
57
- if version =~ /^git version (\d[\d\.]+)/
60
+ if version =~ /^git version (\d[\d.]+)/
58
61
  $1.split(".").map { |i| Integer(i) }
59
62
  else
60
63
  raise ArgumentError, "cannot parse git version string #{version}, "\
@@ -139,16 +142,16 @@ module Autobuild
139
142
  end
140
143
 
141
144
  gitopts, common = Kernel.filter_options options,
142
- push_to: nil,
143
- branch: nil,
144
- local_branch: nil,
145
- remote_branch: nil,
146
- tag: nil,
147
- commit: nil,
148
- repository_id: nil,
149
- source_id: nil,
150
- with_submodules: false,
151
- 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
152
155
  if gitopts[:branch] && branch
153
156
  raise ConfigException, "git branch specified with both the option hash "\
154
157
  "and the explicit parameter"
@@ -293,6 +296,68 @@ module Autobuild
293
296
  git_dir(package, true)
294
297
  end
295
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_bare(
304
+ package, 'symbolic-ref',
305
+ "refs/remotes/#{@remote_name}/HEAD"
306
+ ).first.strip
307
+ local_remote_head = ls_local_string.match("refs/remotes/#{@remote_name}/(.*)")
308
+ local_remote_head ? local_remote_head[1] : nil
309
+ rescue Autobuild::SubcommandFailed # rubocop:disable Lint/SuppressedException
310
+ end
311
+
312
+ # Return the remote head branch from server if exists, if not return 'master'
313
+ #
314
+ # @param [Package] package
315
+ def try_resolve_remote_head_from_server(package)
316
+ ls_remote_string = package.run(
317
+ :import,
318
+ Autobuild.tool('git'), 'ls-remote', '--symref', repository
319
+ ).first.strip
320
+ server_remote_head =
321
+ ls_remote_string.match("ref:[^A-z]refs/heads/(.*)[^A-z]HEAD")
322
+ server_remote_head ? server_remote_head[1] : 'master'
323
+ end
324
+
325
+ # Return default local branch if exists, if not return the default remote branch
326
+ #
327
+ # @param [Package] package
328
+ def resolve_remote_head(package, only_local: false)
329
+ try_resolve_remote_head_from_local(package) ||
330
+ (!only_local && try_resolve_remote_head_from_server(package))
331
+ end
332
+
333
+ # Whether both the local and remote branches are known
334
+ #
335
+ # See documentation of {#resolve_all_branches}
336
+ def has_all_branches?
337
+ remote_branch && local_branch
338
+ end
339
+
340
+ # Resolve branches based on the remote's HEAD
341
+ #
342
+ # Since GitHub (and others) decided to change the name of the "default"
343
+ # branch, we can't assume that master is ... well ... master.
344
+ #
345
+ # For this reason, a Git importer does not have a built-in default.
346
+ # If the branch(es) are not provided explicitly, the importer will
347
+ # call this method to guess the name of the default branch instead.
348
+ #
349
+ # Call {#has_all_branches?} to determine whether it is necessary
350
+ def resolve_all_branches(package, only_local: false)
351
+ default_branch = resolve_remote_head(package, only_local: only_local)
352
+ unless default_branch
353
+ raise NetworkAccessNeeded,
354
+ "determining the remote branch would require access to "\
355
+ "the network, and only_local is true"
356
+ end
357
+
358
+ relocate(repository, default_branch: default_branch)
359
+ end
360
+
296
361
  # @api private
297
362
  #
298
363
  # Resolves the git directory associated with path, and tells whether it
@@ -366,12 +431,12 @@ module Autobuild
366
431
  def self.validate_git_dir(package, require_working_copy, _dir, style)
367
432
  if !style
368
433
  raise ConfigException.new(package, 'import', retry: false),
369
- "while importing #{package.name}, #{package.importdir} "\
370
- "does not point to a git repository"
434
+ "while importing #{package.name}, #{package.importdir} "\
435
+ "does not point to a git repository"
371
436
  elsif require_working_copy && (style == :bare)
372
437
  raise ConfigException.new(package, 'import', retry: false),
373
- "while importing #{package.name}, #{package.importdir} "\
374
- "points to a bare git repository but a working copy was required"
438
+ "while importing #{package.name}, #{package.importdir} "\
439
+ "points to a bare git repository but a working copy was required"
375
440
  end
376
441
  end
377
442
 
@@ -476,22 +541,28 @@ module Autobuild
476
541
  # @api private
477
542
  #
478
543
  # Set a remote up in the repositorie's configuration
479
- def setup_remote(package, remote_name, repository, push_to = repository)
544
+ def setup_remote(
545
+ package, remote_name, repository, push_to = repository,
546
+ only_local: true
547
+ )
548
+ resolve_all_branches(package, only_local: only_local) unless has_all_branches?
549
+
480
550
  run_git_bare(package, 'config', '--replace-all',
481
- "remote.#{remote_name}.url", repository)
551
+ "remote.#{remote_name}.url", repository)
482
552
  run_git_bare(package, 'config', '--replace-all',
483
- "remote.#{remote_name}.pushurl", push_to || repository)
553
+ "remote.#{remote_name}.pushurl", push_to || repository)
484
554
  run_git_bare(package, 'config', '--replace-all',
485
- "remote.#{remote_name}.fetch",
486
- "+refs/heads/*:refs/remotes/#{remote_name}/*")
555
+ "remote.#{remote_name}.fetch",
556
+ "+refs/heads/*:refs/remotes/#{remote_name}/*")
487
557
 
488
558
  if remote_branch && local_branch
559
+ remote_ref = remote_branch_to_ref(remote_branch)
489
560
  run_git_bare(package, 'config', '--replace-all',
490
- "remote.#{remote_name}.push",
491
- "refs/heads/#{local_branch}:#{remote_branch_to_ref(remote_branch)}")
561
+ "remote.#{remote_name}.push",
562
+ "refs/heads/#{local_branch}:#{remote_ref}")
492
563
  else
493
564
  run_git_bare(package, 'config', '--replace-all',
494
- "remote.#{remote_name}.push", "refs/heads/*:refs/heads/*")
565
+ "remote.#{remote_name}.push", "refs/heads/*:refs/heads/*")
495
566
  end
496
567
  end
497
568
 
@@ -510,23 +581,24 @@ module Autobuild
510
581
  # @api private
511
582
  #
512
583
  # Updates the git repository's configuration for the target remote
513
- def update_remotes_configuration(package)
584
+ def update_remotes_configuration(package, only_local: true)
514
585
  each_configured_remote do |*args|
515
- setup_remote(package, *args)
586
+ setup_remote(package, *args, only_local: only_local)
516
587
  end
517
588
 
518
589
  if local_branch
519
590
  run_git_bare(package, 'config', '--replace-all',
520
- "branch.#{local_branch}.remote", remote_name)
591
+ "branch.#{local_branch}.remote", remote_name)
521
592
  run_git_bare(package, 'config', '--replace-all',
522
- "branch.#{local_branch}.merge", remote_branch_to_ref(local_branch))
593
+ "branch.#{local_branch}.merge",
594
+ remote_branch_to_ref(local_branch))
523
595
  end
524
596
  end
525
597
 
526
598
  # Resolve a commit ref to a tag or commit ID
527
599
  def describe_rev(package, rev)
528
600
  tag = run_git_bare(package, 'describe',
529
- '--tags', '--exact-match', rev).first.strip
601
+ '--tags', '--exact-match', rev).first.strip
530
602
  [true, tag.encode('UTF-8')]
531
603
  rescue Autobuild::SubcommandFailed
532
604
  commit = rev_parse(package, rev)
@@ -584,7 +656,7 @@ module Autobuild
584
656
  refspec.zip(fetched_commits).each do |spec, commit_id|
585
657
  if spec =~ %r{^refs/heads/(.*)$}
586
658
  run_git_bare(package, 'update-ref', "-m", "updated by autobuild",
587
- "refs/remotes/#{remote_name}/#{$1}", commit_id)
659
+ "refs/remotes/#{remote_name}/#{$1}", commit_id)
588
660
  end
589
661
  end
590
662
 
@@ -641,7 +713,7 @@ module Autobuild
641
713
  run_git_bare(package, 'show-ref', '-s', refspec).first.strip
642
714
  rescue SubcommandFailed
643
715
  raise PackageException.new(package, "import"),
644
- "cannot resolve #{refspec}"
716
+ "cannot resolve #{refspec}"
645
717
  end
646
718
  else
647
719
  refspec =
@@ -650,7 +722,7 @@ module Autobuild
650
722
  remote_branch_to_ref(remote_branch)
651
723
  begin fetch_remote(package, refspec: refspec)
652
724
  rescue Exception => e
653
- return fallback(e, package, :status, package, only_local)
725
+ fallback(e, package, :status, package, only_local)
654
726
  end
655
727
  end
656
728
  end
@@ -666,6 +738,8 @@ module Autobuild
666
738
  end
667
739
 
668
740
  validate_importdir(package)
741
+ resolve_all_branches(package, only_local: only_local) unless has_all_branches?
742
+
669
743
  _pinned_state, target_commit, = determine_target_state(
670
744
  package, only_local: only_local)
671
745
 
@@ -696,7 +770,7 @@ module Autobuild
696
770
 
697
771
  def has_branch?(package, branch_name)
698
772
  run_git_bare(package, 'show-ref', '-q', '--verify',
699
- remote_branch_to_ref(branch_name))
773
+ remote_branch_to_ref(branch_name))
700
774
  true
701
775
  rescue SubcommandFailed => e
702
776
  if e.status == 1
@@ -706,7 +780,7 @@ module Autobuild
706
780
  end
707
781
 
708
782
  def has_local_branch?(package)
709
- has_branch?(package, local_branch)
783
+ has_branch?(package, local_branch) if local_branch
710
784
  end
711
785
 
712
786
  def detached_head?(package)
@@ -714,6 +788,8 @@ module Autobuild
714
788
  end
715
789
 
716
790
  private def remote_branch_to_ref(branch)
791
+ return unless branch
792
+
717
793
  if branch.start_with?("refs/")
718
794
  branch
719
795
  else
@@ -750,9 +826,7 @@ module Autobuild
750
826
  #
751
827
  # This is the value returned by {Git#status}
752
828
  class Status < Importer::Status
753
- attr_reader :fetch_commit
754
- attr_reader :head_commit
755
- attr_reader :common_commit
829
+ attr_reader :fetch_commit, :head_commit, :common_commit
756
830
 
757
831
  def initialize(package, status, remote_commit, local_commit, common_commit)
758
832
  super()
@@ -797,8 +871,8 @@ module Autobuild
797
871
  run_git_bare(package, 'rev-parse', '-q', '--verify', name).first
798
872
  rescue Autobuild::SubcommandFailed
799
873
  raise PackageException.new(package, 'import'),
800
- "failed to resolve #{name}. "\
801
- "Are you sure this commit, branch or tag exists ?"
874
+ "failed to resolve #{name}. "\
875
+ "Are you sure this commit, branch or tag exists ?"
802
876
  end
803
877
 
804
878
  # Returns the file's conents at a certain commit
@@ -811,7 +885,7 @@ module Autobuild
811
885
  run_git_bare(package, 'show', "#{commit}:#{path}").join("\n")
812
886
  rescue Autobuild::SubcommandFailed
813
887
  raise PackageException.new(package, 'import'),
814
- "failed to either resolve commit #{commit} or file #{path}"
888
+ "failed to either resolve commit #{commit} or file #{path}"
815
889
  end
816
890
 
817
891
  # Tests whether a commit is already present in a given history
@@ -845,7 +919,7 @@ module Autobuild
845
919
  def describe_commit_on_remote(package, rev = 'HEAD', options = Hash.new)
846
920
  rev = rev.to_str
847
921
  options = Kernel.validate_options options,
848
- tags: true
922
+ tags: true
849
923
 
850
924
  commit_id = rev_parse(package, rev)
851
925
 
@@ -875,15 +949,13 @@ module Autobuild
875
949
  end
876
950
 
877
951
  remote_refs.delete_if do |rev_name, rev_id|
878
- begin
879
952
  if commit_present_in?(package, commit_id, rev_id)
880
953
  return rev_name
881
954
  else
882
955
  true
883
956
  end
884
- rescue PackageException
957
+ rescue PackageException
885
958
  false
886
- end
887
959
  end
888
960
 
889
961
  unless remote_refs.empty?
@@ -909,7 +981,7 @@ module Autobuild
909
981
  def merge_status(package, fetch_commit, reference_commit = "HEAD")
910
982
  begin
911
983
  common_commit = run_git_bare(package, 'merge-base',
912
- reference_commit, fetch_commit).first.strip
984
+ reference_commit, fetch_commit).first.strip
913
985
  rescue Exception
914
986
  raise PackageException.new(package, 'import'), "failed to find "\
915
987
  "the merge-base between #{reference_commit} and #{fetch_commit}. "\
@@ -942,7 +1014,7 @@ module Autobuild
942
1014
  # @return [void]
943
1015
  def update_alternates(package)
944
1016
  alternates_path = File.join(git_dir(package, false),
945
- 'objects', 'info', 'alternates')
1017
+ 'objects', 'info', 'alternates')
946
1018
  current_alternates =
947
1019
  if File.file?(alternates_path)
948
1020
  File.readlines(alternates_path)
@@ -1007,18 +1079,18 @@ module Autobuild
1007
1079
  # changes
1008
1080
  unless commit_present_in?(package, current_head, fetch_commit)
1009
1081
  raise ImporterCannotReset.new(package, 'import'),
1010
- "branch #{local_branch} of #{package.name} contains"\
1011
- " commits that do not seem to be present on the branch"\
1012
- " #{remote_branch} of the remote repository. I can't"\
1013
- " go on as it could make you lose some stuff. Update"\
1014
- " the remote branch in your overrides, push your"\
1015
- " changes or reset to the remote commit manually"\
1016
- " before trying again"
1082
+ "branch #{local_branch} of #{package.name} contains"\
1083
+ " commits that do not seem to be present on the branch"\
1084
+ " #{remote_branch} of the remote repository. I can't"\
1085
+ " go on as it could make you lose some stuff. Update"\
1086
+ " the remote branch in your overrides, push your"\
1087
+ " changes or reset to the remote commit manually"\
1088
+ " before trying again"
1017
1089
  end
1018
1090
  end
1019
1091
 
1020
1092
  package.message format(" %%s: resetting branch %<branch>s to %<commit>s",
1021
- branch: local_branch, commit: target_commit)
1093
+ branch: local_branch, commit: target_commit)
1022
1094
  # I don't use a reset --hard here as it would add even more
1023
1095
  # restrictions on when we can do the operation (as we would refuse
1024
1096
  # doing it if there are local changes). The checkout creates a
@@ -1029,7 +1101,7 @@ module Autobuild
1029
1101
  begin
1030
1102
  run_git(package, 'checkout', target_commit)
1031
1103
  run_git(package, 'update-ref', "refs/heads/#{local_branch}",
1032
- resolved_target_commit)
1104
+ resolved_target_commit)
1033
1105
  run_git(package, 'symbolic-ref', "HEAD", "refs/heads/#{local_branch}")
1034
1106
  rescue ::Exception
1035
1107
  run_git(package, 'symbolic-ref', "HEAD", target_commit)
@@ -1065,6 +1137,9 @@ module Autobuild
1065
1137
  # @option (see Package#update)
1066
1138
  def update(package, options = Hash.new)
1067
1139
  validate_importdir(package)
1140
+
1141
+ resolve_all_branches(package) unless has_all_branches?
1142
+
1068
1143
  only_local = options.fetch(:only_local, false)
1069
1144
  reset = options.fetch(:reset, false)
1070
1145
 
@@ -1084,20 +1159,21 @@ module Autobuild
1084
1159
  end
1085
1160
 
1086
1161
  unless pin_is_uptodate
1087
- fetch_commit ||= current_remote_commit(package,
1088
- only_local: only_local,
1089
- refspec: [remote_branch_to_ref(remote_branch), tag])
1162
+ fetch_commit ||= current_remote_commit(
1163
+ package, only_local: only_local,
1164
+ refspec: [remote_branch_to_ref(remote_branch), tag]
1165
+ )
1090
1166
  did_update =
1091
1167
  if reset
1092
1168
  reset_head_to_commit(package, target_commit, fetch_commit,
1093
- force: (reset == :force))
1169
+ force: (reset == :force))
1094
1170
  else
1095
1171
  merge_if_simple(package, target_commit)
1096
1172
  end
1097
1173
  end
1098
1174
 
1099
1175
  if !only_local && with_submodules?
1100
- run_git(package, "submodule", "update", '--init')
1176
+ run_git(package, "submodule", "update", '--init', '--recursive')
1101
1177
  did_update = true
1102
1178
  end
1103
1179
 
@@ -1107,12 +1183,12 @@ module Autobuild
1107
1183
  private def ensure_on_local_branch(package, target_commit)
1108
1184
  if !has_local_branch?(package)
1109
1185
  package.message format("%%s: checking out branch %<branch>s",
1110
- branch: local_branch)
1186
+ branch: local_branch)
1111
1187
  run_git(package, 'checkout', '-b', local_branch, target_commit)
1112
1188
  true
1113
1189
  elsif !on_local_branch?(package)
1114
1190
  package.message format("%%s: switching to branch %<branch>s",
1115
- branch: local_branch)
1191
+ branch: local_branch)
1116
1192
  run_git(package, 'checkout', local_branch)
1117
1193
  true
1118
1194
  else
@@ -1195,27 +1271,30 @@ module Autobuild
1195
1271
  clone_options << "--config=#{key}=#{value}"
1196
1272
  end
1197
1273
  package.run(:import,
1198
- Autobuild.tool('git'), 'clone', '-o', remote_name, *clone_options,
1199
- repository, package.importdir, retry: true)
1274
+ Autobuild.tool('git'), 'clone', '-o', remote_name, *clone_options,
1275
+ repository, package.importdir, retry: true)
1200
1276
 
1201
1277
  update_remotes_configuration(package)
1202
- update(package, only_local: !remote_branch.start_with?("refs/"), reset: true)
1203
- run_git(package, "submodule", "update", '--init') if with_submodules?
1278
+ update(package, only_local: !remote_branch.start_with?("refs/"),
1279
+ reset: :force)
1280
+ if with_submodules?
1281
+ run_git(package, "submodule", "update", '--init', '--recursive')
1282
+ end
1204
1283
  end
1205
1284
 
1206
1285
  # Changes the repository this importer is pointing to
1207
1286
  def relocate(repository, options = Hash.new)
1208
- options = Hash[options.map { |k, v| [k.to_sym, v] }]
1287
+ options = options.transform_keys(&:to_sym)
1209
1288
 
1210
1289
  local_branch =
1211
1290
  options[:local_branch] || options[:branch] ||
1212
- self.local_branch || 'master'
1291
+ self.local_branch || options[:default_branch] || nil
1213
1292
  remote_branch =
1214
1293
  options[:remote_branch] || options[:branch] ||
1215
- self.remote_branch || 'master'
1216
- if local_branch.start_with?("refs/")
1294
+ self.remote_branch || options[:default_branch] || nil
1295
+ if local_branch&.start_with?("refs/")
1217
1296
  raise ArgumentError, "you cannot provide a full ref for"\
1218
- " the local branch, only for the remote branch"
1297
+ " the local branch, only for the remote branch"
1219
1298
  end
1220
1299
 
1221
1300
  @push_to = options[:push_to] || @push_to