autobuild 1.18.1 → 1.22.0

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 +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