git-fastclone 1.3.1 → 1.3.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/git-fastclone/version.rb +1 -1
- data/lib/git-fastclone.rb +18 -19
- data/spec/git_fastclone_runner_spec.rb +72 -24
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cef4cf9ee8a10c9fb00ccb58382046fa71298ad8263985156f8e1b7c3dc85af4
|
4
|
+
data.tar.gz: 53dbb091ce1e6f02db4ee9aa89b03791aae4f790d816e33b1f792b9912fde28f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 184ddbefb71a17d2521f898ebf6f2f7887249d7f61423bb55b85e58ce1d3d637c5c7246fdf34058957274fbc3ee62e65be37bcb41b8e803143035c5ff0a13c4f
|
7
|
+
data.tar.gz: 1d8b9882c5f1b3f48044cd4c71e8cae8d14c747f52ad7314a5897e137430a7e6af8bc215e8296b722cc5208fe4aac4d04f22d4bb7c1e173ca64719bbb76fad06
|
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
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
374
|
-
|
375
|
-
|
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
|
-
|
379
|
-
expect(
|
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
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
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
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
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.
|
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:
|
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.
|
81
|
+
rubygems_version: 3.1.6
|
82
82
|
signing_key:
|
83
83
|
specification_version: 4
|
84
84
|
summary: git-clone --recursive on steroids!
|