git-fastclone 1.3.1 → 1.3.3

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d83fead53c699b625667b994e06ab9cfe0c25ed62c01239c054ec1523109f986
4
- data.tar.gz: 9e4513fe51d1e1deb357a1781fadd1df723997df527402c12beb436103ce7b2a
3
+ metadata.gz: cef4cf9ee8a10c9fb00ccb58382046fa71298ad8263985156f8e1b7c3dc85af4
4
+ data.tar.gz: 53dbb091ce1e6f02db4ee9aa89b03791aae4f790d816e33b1f792b9912fde28f
5
5
  SHA512:
6
- metadata.gz: ecc286e3180698eab52e06e61d3bf62c27af6524a3ab398d86cf1bbbe336dd9c547609ec6744264be506ea9f41920cf68210b08d6fad752f5d8fc589b069e2be
7
- data.tar.gz: 653a21b17f4a033ee23bd77f1953a72df9176006ebb320a33ed179e4f7f2a957133a4569f1d91722c65d2d638ee727eae15d41b6b73f5b133d138823365e6937
6
+ metadata.gz: 184ddbefb71a17d2521f898ebf6f2f7887249d7f61423bb55b85e58ce1d3d637c5c7246fdf34058957274fbc3ee62e65be37bcb41b8e803143035c5ff0a13c4f
7
+ data.tar.gz: 1d8b9882c5f1b3f48044cd4c71e8cae8d14c747f52ad7314a5897e137430a7e6af8bc215e8296b722cc5208fe4aac4d04f22d4bb7c1e173ca64719bbb76fad06
@@ -2,5 +2,5 @@
2
2
 
3
3
  # Version string for git-fastclone
4
4
  module GitFastCloneVersion
5
- VERSION = '1.3.1'
5
+ VERSION = '1.3.3'
6
6
  end
data/lib/git-fastclone.rb CHANGED
@@ -154,7 +154,7 @@ module GitFastClone
154
154
 
155
155
  opts.on('--lock-timeout N', 'Timeout in seconds to acquire a lock on any reference repo.
156
156
  Default is 0 which waits indefinitely.') do |timeout_secs|
157
- self.flock_timeout_secs = timeout_secs
157
+ self.flock_timeout_secs = timeout_secs.to_i
158
158
  end
159
159
  end.parse!
160
160
  end
@@ -379,8 +379,9 @@ module GitFastClone
379
379
  # To avoid corruption of the cache, if we failed to update or check out we remove
380
380
  # the cache directory entirely. This may cause the current clone to fail, but if the
381
381
  # underlying error from git is transient it will not affect future clones.
382
- def clear_cache(dir)
382
+ def clear_cache(dir, url)
383
383
  FileUtils.remove_entry_secure(dir, force: true)
384
+ reference_updated.delete(reference_repo_name(url))
384
385
  end
385
386
 
386
387
  # This command will create and bring the mirror up-to-date on-demand,
@@ -391,33 +392,31 @@ module GitFastClone
391
392
  # moment means we only need to synchronize our own threads in case a single
392
393
  # submodule url is included twice via multiple dependency paths
393
394
  def with_git_mirror(url)
395
+ retries_allowed ||= 1
396
+ attempt_number ||= 0
397
+
394
398
  update_reference_repo(url, true)
399
+ dir = reference_repo_dir(url, reference_dir, using_local_repo)
395
400
 
396
401
  # Sometimes remote updates involve re-packing objects on a different thread
397
402
  # We grab the reference repo lock here just to make sure whatever thread
398
403
  # ended up doing the update is done with its housekeeping.
399
404
  # This makes sure we have control and unlock when the block returns:
400
405
  with_reference_repo_lock(url) do
401
- dir = reference_repo_dir(url, reference_dir, using_local_repo)
402
- retries_allowed = 1
403
- attempt_number = 0
404
-
405
- begin
406
- yield dir, attempt_number
407
- rescue Terrapin::ExitStatusError => e
408
- if retriable_error?(e)
409
- print_formatted_error(e)
410
- clear_cache(dir)
411
-
412
- if attempt_number < retries_allowed
413
- attempt_number += 1
414
- retry
415
- end
416
- end
406
+ yield dir, attempt_number
407
+ end
408
+ rescue Terrapin::ExitStatusError => e
409
+ if retriable_error?(e)
410
+ print_formatted_error(e)
411
+ clear_cache(dir, url)
417
412
 
418
- raise
413
+ if attempt_number < retries_allowed
414
+ attempt_number += 1
415
+ retry
419
416
  end
420
417
  end
418
+
419
+ raise
421
420
  end
422
421
 
423
422
  def usage
@@ -24,7 +24,7 @@ describe GitFastClone::Runner do
24
24
  let(:test_reference_repo_dir) { '/var/tmp/git-fastclone/reference/test_reference_dir' }
25
25
  let(:placeholder_arg) { 'PH' }
26
26
 
27
- let(:lockfile) do
27
+ def create_lockfile_double
28
28
  lockfile = double
29
29
  expect(lockfile).to receive(:flock).with(File::LOCK_EX).once
30
30
  expect(lockfile).to receive(:flock).with(File::LOCK_UN).once
@@ -32,6 +32,8 @@ describe GitFastClone::Runner do
32
32
  lockfile
33
33
  end
34
34
 
35
+ let(:lockfile) { create_lockfile_double }
36
+
35
37
  before do
36
38
  stub_const('ARGV', ['ssh://git@git.com/git-fastclone.git', 'test_reference_dir'])
37
39
  end
@@ -331,13 +333,6 @@ describe GitFastClone::Runner do
331
333
  end
332
334
 
333
335
  describe '.with_git_mirror' do
334
- before(:each) do
335
- allow(subject).to receive(:update_reference_repo) {}
336
- allow(subject).to receive(:print_formatted_error) {}
337
- expect(subject).to receive(:reference_repo_dir).and_return(test_reference_repo_dir)
338
- expect(subject).to receive(:reference_repo_lock_file).and_return(lockfile)
339
- end
340
-
341
336
  def retriable_error
342
337
  %(
343
338
  STDOUT:
@@ -370,28 +365,81 @@ describe GitFastClone::Runner do
370
365
  expect(yielded).to eq(results)
371
366
  end
372
367
 
373
- it 'should yield properly' do
374
- expect(subject).not_to receive(:clear_cache)
375
- try_with_git_mirror([true], [[test_reference_repo_dir, 0]])
368
+ let(:expected_commands) { [] }
369
+ let(:expected_commands_args) { [] }
370
+
371
+ before(:each) do
372
+ expect(expected_commands.length).to eq(expected_commands_args.length)
373
+ allow(Terrapin::CommandLine).to receive(:new) do |*command|
374
+ expect(expected_commands.length).to be > 0
375
+ expected_command = expected_commands.shift
376
+ expected_args = expected_commands_args.shift
377
+ expect(command).to eq(expected_command)
378
+ stub = double(Terrapin::CommandLine)
379
+ expect(stub).to receive(:run).with(expected_args)
380
+ stub
381
+ end
382
+
383
+ allow(subject).to receive(:print_formatted_error) {}
384
+ allow(subject).to receive(:reference_repo_dir).and_return(test_reference_repo_dir)
385
+ allow(subject).to receive(:reference_repo_lock_file) { create_lockfile_double }
376
386
  end
377
387
 
378
- it 'should retry once for retriable errors' do
379
- expect(subject).to receive(:clear_cache).once {}
380
- try_with_git_mirror([retriable_error, true], [[test_reference_repo_dir, 1]])
388
+ after(:each) do
389
+ expect(expected_commands).to be_empty
381
390
  end
382
391
 
383
- it 'should only retry twice at most' do
384
- expect(subject).to receive(:clear_cache).twice {}
385
- expect do
386
- try_with_git_mirror([retriable_error, retriable_error], [])
387
- end.to raise_error(Terrapin::ExitStatusError)
392
+ def clone_cmds
393
+ [
394
+ ['git clone', '--mirror :url :mirror'],
395
+ ['cd', ':path; git remote update --prune']
396
+ ]
388
397
  end
389
398
 
390
- it 'should not retry for non-retriable errors' do
391
- expect(subject).not_to receive(:clear_cache)
392
- expect do
393
- try_with_git_mirror(['Some unexpected error message'], [])
394
- end.to raise_error(Terrapin::ExitStatusError)
399
+ def clone_args
400
+ [
401
+ {
402
+ mirror: test_reference_repo_dir,
403
+ url: test_url_valid
404
+ },
405
+ {
406
+ path: test_reference_repo_dir
407
+ }
408
+ ]
409
+ end
410
+
411
+ context 'expecting 1 clone attempt' do
412
+ let(:expected_commands) { clone_cmds }
413
+ let(:expected_commands_args) { clone_args }
414
+
415
+ it 'should succeed with a successful clone' do
416
+ expect(subject).not_to receive(:clear_cache)
417
+ try_with_git_mirror([true], [[test_reference_repo_dir, 0]])
418
+ end
419
+
420
+ it 'should fail after a non-retryable clone error' do
421
+ expect(subject).not_to receive(:clear_cache)
422
+ expect do
423
+ try_with_git_mirror(['Some unexpected error message'], [])
424
+ end.to raise_error(Terrapin::ExitStatusError)
425
+ end
426
+ end
427
+
428
+ context 'expecting 2 clone attempts' do
429
+ let(:expected_commands) { clone_cmds + clone_cmds }
430
+ let(:expected_commands_args) { clone_args + clone_args }
431
+
432
+ it 'should succeed after a single retryable clone failure' do
433
+ expect(subject).to receive(:clear_cache).and_call_original
434
+ try_with_git_mirror([retriable_error, true], [[test_reference_repo_dir, 1]])
435
+ end
436
+
437
+ it 'should fail after two retryable clone failures' do
438
+ expect(subject).to receive(:clear_cache).twice.and_call_original
439
+ expect do
440
+ try_with_git_mirror([retriable_error, retriable_error], [])
441
+ end.to raise_error(Terrapin::ExitStatusError)
442
+ end
395
443
  end
396
444
  end
397
445
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: git-fastclone
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.1
4
+ version: 1.3.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Tauraso
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2022-12-08 00:00:00.000000000 Z
12
+ date: 2023-03-03 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: colorize
@@ -78,7 +78,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
78
78
  - !ruby/object:Gem::Version
79
79
  version: '0'
80
80
  requirements: []
81
- rubygems_version: 3.3.7
81
+ rubygems_version: 3.1.6
82
82
  signing_key:
83
83
  specification_version: 4
84
84
  summary: git-clone --recursive on steroids!