git-fastclone 1.4.5 → 1.5.0
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 +4 -4
- data/README.md +17 -5
- data/lib/git-fastclone/version.rb +1 -1
- data/lib/git-fastclone.rb +20 -7
- data/spec/git_fastclone_runner_spec.rb +57 -9
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8b86bd9aa9bc5a377dd7d5b7b456eb0de1aee7ffd1e746642775d08042e9714f
|
|
4
|
+
data.tar.gz: '08dff02e06757c022c7ee0fec4890261c3d3efbee76130f2c7f4e0c2cdd91361'
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ce36dfc95ed1d5621fc32df5721d1b796e1cdbb58c11952351dd124bf14a784bef8624e23bde74be3a3c848fff320201639b0e7737be44c8860860a0fb99a019
|
|
7
|
+
data.tar.gz: 77a296e5b3c6ea817fef4c0ca6df39c4f33e8f35626fd896d4f41ff9c201bf8de15c57a0543e7a8aac4cf63f7de352a00b01844c964657fb20192abbce3790a4
|
data/README.md
CHANGED
|
@@ -43,17 +43,29 @@ Usage
|
|
|
43
43
|
gem install git-fastclone
|
|
44
44
|
git fastclone [options] <git-repo-url>
|
|
45
45
|
|
|
46
|
-
-b, --branch
|
|
47
|
-
-v, --verbose
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
--
|
|
46
|
+
-b, --branch BRANCH Checkout this branch rather than the default
|
|
47
|
+
-v, --verbose Verbose mode
|
|
48
|
+
--print_git_errors Print git output if a command fails
|
|
49
|
+
-c, --color Display colored output
|
|
50
|
+
--config CONFIG Git config applied to the cloned repo
|
|
51
|
+
--lock-timeout N Timeout in seconds to acquire a lock on any reference repo.
|
|
52
|
+
Default is 0 which waits indefinitely.
|
|
53
|
+
--pre-clone-hook command An optional command that should be invoked before cloning mirror repo
|
|
51
54
|
|
|
52
55
|
Change the default `REFERENCE_REPO_DIR` environment variable if necessary.
|
|
53
56
|
|
|
54
57
|
Cygwin users need to add `~/bin` to PATH.
|
|
55
58
|
|
|
56
59
|
|
|
60
|
+
Hooks
|
|
61
|
+
-----
|
|
62
|
+
|
|
63
|
+
- `pre-clone-hook` is invoked right before cloning a new mirror repo, which gives a change to prepopulate git's mirror from a different source.
|
|
64
|
+
The hook is invoked with given arguments:
|
|
65
|
+
1. cloning repo url
|
|
66
|
+
1. path to the repo mirror location
|
|
67
|
+
1. attempt number, 0-indexed
|
|
68
|
+
|
|
57
69
|
How to test?
|
|
58
70
|
------------
|
|
59
71
|
Manual testing:
|
data/lib/git-fastclone.rb
CHANGED
|
@@ -166,6 +166,11 @@ module GitFastClone
|
|
|
166
166
|
Default is 0 which waits indefinitely.') do |timeout_secs|
|
|
167
167
|
self.flock_timeout_secs = timeout_secs.to_i
|
|
168
168
|
end
|
|
169
|
+
|
|
170
|
+
opts.on('--pre-clone-hook command',
|
|
171
|
+
'An optional command that should be invoked before cloning mirror repo') do |command|
|
|
172
|
+
options[:pre_clone_hook] = command
|
|
173
|
+
end
|
|
169
174
|
end.parse!
|
|
170
175
|
end
|
|
171
176
|
|
|
@@ -324,7 +329,7 @@ module GitFastClone
|
|
|
324
329
|
# overall checkout or not. When we pre-fetch based off of cached information,
|
|
325
330
|
# fail_hard is false. When we fetch based off info in a repository directly,
|
|
326
331
|
# fail_hard is true.
|
|
327
|
-
def update_reference_repo(url, fail_hard)
|
|
332
|
+
def update_reference_repo(url, fail_hard, attempt_number)
|
|
328
333
|
repo_name = reference_repo_name(url)
|
|
329
334
|
mirror = reference_repo_dir(url, reference_dir, using_local_repo)
|
|
330
335
|
|
|
@@ -333,24 +338,26 @@ module GitFastClone
|
|
|
333
338
|
submodule_file = reference_repo_submodule_file(url, reference_dir, using_local_repo)
|
|
334
339
|
|
|
335
340
|
# if prefetch is on, then grab children immediately to frontload network requests
|
|
336
|
-
prefetch(submodule_file) if File.exist?(submodule_file) && prefetch_submodules
|
|
341
|
+
prefetch(submodule_file, attempt_number) if File.exist?(submodule_file) && prefetch_submodules
|
|
337
342
|
|
|
338
343
|
# Store the fact that our repo has been updated if necessary
|
|
339
|
-
store_updated_repo(url, mirror, repo_name, fail_hard) unless reference_updated[repo_name]
|
|
344
|
+
store_updated_repo(url, mirror, repo_name, fail_hard, attempt_number) unless reference_updated[repo_name]
|
|
340
345
|
end
|
|
341
346
|
end
|
|
342
347
|
|
|
343
348
|
# Grab the children in the event of a prefetch
|
|
344
|
-
def prefetch(submodule_file)
|
|
349
|
+
def prefetch(submodule_file, attempt_number)
|
|
345
350
|
File.readlines(submodule_file).each do |line|
|
|
346
351
|
# We don't join these threads explicitly
|
|
347
|
-
Thread.new { update_reference_repo(line.strip, false) }
|
|
352
|
+
Thread.new { update_reference_repo(line.strip, false, attempt_number) }
|
|
348
353
|
end
|
|
349
354
|
end
|
|
350
355
|
|
|
351
356
|
# Creates or updates the mirror repo then stores an indication
|
|
352
357
|
# that this repo has been updated on this run of fastclone
|
|
353
|
-
def store_updated_repo(url, mirror, repo_name, fail_hard)
|
|
358
|
+
def store_updated_repo(url, mirror, repo_name, fail_hard, attempt_number)
|
|
359
|
+
trigger_pre_clone_hook_if_needed(url, mirror, attempt_number)
|
|
360
|
+
# If pre_clone_hook correctly creates a mirror directory, we don't want to clone, but just update it
|
|
354
361
|
unless Dir.exist?(mirror)
|
|
355
362
|
fail_on_error('git', 'clone', verbose ? '--verbose' : '--quiet', '--mirror', url.to_s, mirror.to_s,
|
|
356
363
|
quiet: !verbose, print_on_failure: print_git_errors)
|
|
@@ -414,7 +421,7 @@ module GitFastClone
|
|
|
414
421
|
retries_allowed ||= 1
|
|
415
422
|
attempt_number ||= 0
|
|
416
423
|
|
|
417
|
-
update_reference_repo(url, true)
|
|
424
|
+
update_reference_repo(url, true, attempt_number)
|
|
418
425
|
dir = reference_repo_dir(url, reference_dir, using_local_repo)
|
|
419
426
|
|
|
420
427
|
# Sometimes remote updates involve re-packing objects on a different thread
|
|
@@ -441,5 +448,11 @@ module GitFastClone
|
|
|
441
448
|
def usage
|
|
442
449
|
'Usage: git fastclone [options] <git-url> [path]'
|
|
443
450
|
end
|
|
451
|
+
|
|
452
|
+
private def trigger_pre_clone_hook_if_needed(url, mirror, attempt_number)
|
|
453
|
+
return if Dir.exist?(mirror) || !options.include?(:pre_clone_hook)
|
|
454
|
+
|
|
455
|
+
popen2e_wrapper(options[:pre_clone_hook], url.to_s, mirror.to_s, attempt_number.to_s, quiet: !verbose)
|
|
456
|
+
end
|
|
444
457
|
end
|
|
445
458
|
end
|
|
@@ -145,6 +145,54 @@ describe GitFastClone::Runner do
|
|
|
145
145
|
subject.clone(placeholder_arg, nil, '.', 'config')
|
|
146
146
|
end
|
|
147
147
|
end
|
|
148
|
+
|
|
149
|
+
context 'with pre-clone-hook errors' do
|
|
150
|
+
let(:pre_clone_hook) { '/some/command' }
|
|
151
|
+
before(:each) do
|
|
152
|
+
subject.options[:pre_clone_hook] = pre_clone_hook
|
|
153
|
+
subject.reference_dir = placeholder_arg
|
|
154
|
+
allow(subject).to receive(:with_git_mirror).and_call_original
|
|
155
|
+
allow(subject).to receive(:with_reference_repo_lock) do |_url, &block|
|
|
156
|
+
block.call
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
it 'invokes hook command' do
|
|
161
|
+
allow(subject).to receive(:fail_on_error)
|
|
162
|
+
expect(subject).to receive(:popen2e_wrapper).with(
|
|
163
|
+
pre_clone_hook, 'PH', 'PH/PH', '0',
|
|
164
|
+
{ quiet: true }
|
|
165
|
+
) { runner_execution_double }
|
|
166
|
+
|
|
167
|
+
subject.clone(placeholder_arg, nil, '.', 'config')
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
it 'does not call clone if hook creates mirror' do
|
|
171
|
+
allow(subject).to receive(:popen2e_wrapper).with(
|
|
172
|
+
pre_clone_hook, 'PH', 'PH/PH', '0',
|
|
173
|
+
{ quiet: true }
|
|
174
|
+
) do
|
|
175
|
+
# Emulate creating mirror dir
|
|
176
|
+
allow(Dir).to receive(:exist?).with('PH/PH').and_return(true)
|
|
177
|
+
end
|
|
178
|
+
allow(subject).to receive(:fail_on_error)
|
|
179
|
+
|
|
180
|
+
subject.clone(placeholder_arg, nil, '.', 'config')
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
it 'does not call pre-clone hook if mirror is already created' do
|
|
184
|
+
# Emulate already created mirror dir
|
|
185
|
+
allow(Dir).to receive(:exist?).and_call_original
|
|
186
|
+
allow(Dir).to receive(:exist?).with('PH/PH').and_return(true)
|
|
187
|
+
expect(subject).not_to receive(:popen2e_wrapper).with(
|
|
188
|
+
pre_clone_hook, 'PH', 'PH/PH', '0',
|
|
189
|
+
{ quiet: true }
|
|
190
|
+
)
|
|
191
|
+
allow(subject).to receive(:fail_on_error)
|
|
192
|
+
|
|
193
|
+
subject.clone(placeholder_arg, nil, '.', 'config')
|
|
194
|
+
end
|
|
195
|
+
end
|
|
148
196
|
end
|
|
149
197
|
|
|
150
198
|
describe '.clear_clone_dest_if_needed' do
|
|
@@ -249,7 +297,7 @@ describe GitFastClone::Runner do
|
|
|
249
297
|
allow(File).to receive(:exist?) { true }
|
|
250
298
|
subject.prefetch_submodules = true
|
|
251
299
|
subject.reference_dir = placeholder_arg
|
|
252
|
-
subject.update_reference_repo(test_url_valid, false)
|
|
300
|
+
subject.update_reference_repo(test_url_valid, false, 0)
|
|
253
301
|
end
|
|
254
302
|
end
|
|
255
303
|
|
|
@@ -262,7 +310,7 @@ describe GitFastClone::Runner do
|
|
|
262
310
|
allow(File).to receive(:exist?) { true }
|
|
263
311
|
subject.prefetch_submodules = false
|
|
264
312
|
subject.reference_dir = placeholder_arg
|
|
265
|
-
subject.update_reference_repo(placeholder_arg, false)
|
|
313
|
+
subject.update_reference_repo(placeholder_arg, false, 0)
|
|
266
314
|
end
|
|
267
315
|
end
|
|
268
316
|
|
|
@@ -277,7 +325,7 @@ describe GitFastClone::Runner do
|
|
|
277
325
|
allow(subject).to receive(:reference_repo_dir) { placeholder_arg }
|
|
278
326
|
subject.reference_updated = placeholder_hash
|
|
279
327
|
subject.prefetch_submodules = false
|
|
280
|
-
subject.update_reference_repo(placeholder_arg, false)
|
|
328
|
+
subject.update_reference_repo(placeholder_arg, false, 0)
|
|
281
329
|
end
|
|
282
330
|
end
|
|
283
331
|
|
|
@@ -291,7 +339,7 @@ describe GitFastClone::Runner do
|
|
|
291
339
|
subject.reference_updated = placeholder_hash
|
|
292
340
|
subject.reference_dir = placeholder_arg
|
|
293
341
|
subject.prefetch_submodules = false
|
|
294
|
-
subject.update_reference_repo(placeholder_arg, false)
|
|
342
|
+
subject.update_reference_repo(placeholder_arg, false, 0)
|
|
295
343
|
end
|
|
296
344
|
end
|
|
297
345
|
end
|
|
@@ -302,7 +350,7 @@ describe GitFastClone::Runner do
|
|
|
302
350
|
|
|
303
351
|
allow(File).to receive(:readlines) { %w[1 2 3] }
|
|
304
352
|
subject.prefetch_submodules = true
|
|
305
|
-
subject.prefetch(placeholder_arg)
|
|
353
|
+
subject.prefetch(placeholder_arg, 0)
|
|
306
354
|
end
|
|
307
355
|
end
|
|
308
356
|
|
|
@@ -315,7 +363,7 @@ describe GitFastClone::Runner do
|
|
|
315
363
|
allow(subject).to receive(:fail_on_error) { raise ex }
|
|
316
364
|
expect(FileUtils).to receive(:remove_entry_secure).with(placeholder_arg, force: true)
|
|
317
365
|
expect do
|
|
318
|
-
subject.store_updated_repo(placeholder_arg, placeholder_arg, placeholder_arg, true)
|
|
366
|
+
subject.store_updated_repo(placeholder_arg, placeholder_arg, placeholder_arg, true, 0)
|
|
319
367
|
end.to raise_error(ex)
|
|
320
368
|
end
|
|
321
369
|
|
|
@@ -327,7 +375,7 @@ describe GitFastClone::Runner do
|
|
|
327
375
|
allow(subject).to receive(:fail_on_error) { raise ex }
|
|
328
376
|
expect(FileUtils).to_not receive(:remove_entry_secure).with(placeholder_arg, force: true)
|
|
329
377
|
expect do
|
|
330
|
-
subject.store_updated_repo(placeholder_arg, placeholder_arg, placeholder_arg, true)
|
|
378
|
+
subject.store_updated_repo(placeholder_arg, placeholder_arg, placeholder_arg, true, 0)
|
|
331
379
|
end.to raise_error(ex)
|
|
332
380
|
end
|
|
333
381
|
end
|
|
@@ -340,7 +388,7 @@ describe GitFastClone::Runner do
|
|
|
340
388
|
allow(subject).to receive(:fail_on_error) { raise ex }
|
|
341
389
|
expect(FileUtils).to receive(:remove_entry_secure).with(placeholder_arg, force: true)
|
|
342
390
|
expect do
|
|
343
|
-
subject.store_updated_repo(placeholder_arg, placeholder_arg, placeholder_arg, false)
|
|
391
|
+
subject.store_updated_repo(placeholder_arg, placeholder_arg, placeholder_arg, false, 0)
|
|
344
392
|
end.to_not raise_error
|
|
345
393
|
end
|
|
346
394
|
end
|
|
@@ -351,7 +399,7 @@ describe GitFastClone::Runner do
|
|
|
351
399
|
allow(subject).to receive(:fail_on_error)
|
|
352
400
|
|
|
353
401
|
subject.reference_updated = placeholder_hash
|
|
354
|
-
subject.store_updated_repo(placeholder_arg, placeholder_arg, placeholder_arg, false)
|
|
402
|
+
subject.store_updated_repo(placeholder_arg, placeholder_arg, placeholder_arg, false, 0)
|
|
355
403
|
expect(subject.reference_updated).to eq(placeholder_arg => true)
|
|
356
404
|
end
|
|
357
405
|
end
|
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.
|
|
4
|
+
version: 1.5.0
|
|
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: 2024-02-23 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: colorize
|