autobuild 1.19.0 → 1.22.1

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