git-fastclone 1.4.5 → 1.5.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f23af05975dc472665784e91a3e69112694837cbd2a873076a7fb3197828970f
4
- data.tar.gz: b3e2a26cbf1aff738c647eb37aa6b661975a396b680352288f68c0ba20da429d
3
+ metadata.gz: 62066971856b4d6e34def960d0ec1214082d546f94a5ffe58b048eb5715511f0
4
+ data.tar.gz: d04c4ac8c866a011b3b6b279b3a9f2e719c6d284314086f91f4c73b189443f50
5
5
  SHA512:
6
- metadata.gz: b9f239ae1a6cdf02d8aef5944f4d704bffaeb0d410191d7f5b7c759ba1d525dca27dd8efcec2e19ac4ffee9787ff3706b16860d0e16ff493136bcb2378b70a7c
7
- data.tar.gz: fb954090b896bf41a396c956847133fc7d367fc564fbc8e3973ed61f2738b16f3926397b4526994d6c6d1781439970055f67e5c7d8137a0174a4f614b69f7a60
6
+ metadata.gz: d807b912fd16fc82e3ce6ea2a3d568f37d1a946efdb750e7279baafa2a0c8206b2b6b298165321a0dd6306a975aacc873f0863c7ff18259b0b0126dd3c83f299
7
+ data.tar.gz: 0dde85446cad33944b3e1e61327b4656c435312fd6ef169b2b82fc4506d6e6bcedebdb0c808b5bdb52e7b0249472c2f033fa86647cadb6626dbcc953efaa6645
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 <branch> Clone a specific branch
47
- -v, --verbose Verbose mode
48
- -c, --color Display colored output
49
- --config CONFIG Git config applied to the cloned repo
50
- --lock-timeout N Timeout in seconds to acquire a lock on any reference repo.
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:
@@ -2,5 +2,5 @@
2
2
 
3
3
  # Version string for git-fastclone
4
4
  module GitFastCloneVersion
5
- VERSION = '1.4.5'
5
+ VERSION = '1.5.1'
6
6
  end
data/lib/git-fastclone.rb CHANGED
@@ -162,10 +162,16 @@ module GitFastClone
162
162
  options[:config] = config
163
163
  end
164
164
 
165
- opts.on('--lock-timeout N', 'Timeout in seconds to acquire a lock on any reference repo.
166
- Default is 0 which waits indefinitely.') do |timeout_secs|
165
+ opts.on('--lock-timeout N', 'Timeout in seconds to acquire a lock on any reference repo.',
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 script_file',
171
+ 'An optional file that should be invoked before cloning mirror repo',
172
+ 'No-op when a file is missing') do |script_file|
173
+ options[:pre_clone_hook] = script_file
174
+ end
169
175
  end.parse!
170
176
  end
171
177
 
@@ -324,7 +330,7 @@ module GitFastClone
324
330
  # overall checkout or not. When we pre-fetch based off of cached information,
325
331
  # fail_hard is false. When we fetch based off info in a repository directly,
326
332
  # fail_hard is true.
327
- def update_reference_repo(url, fail_hard)
333
+ def update_reference_repo(url, fail_hard, attempt_number)
328
334
  repo_name = reference_repo_name(url)
329
335
  mirror = reference_repo_dir(url, reference_dir, using_local_repo)
330
336
 
@@ -333,24 +339,26 @@ module GitFastClone
333
339
  submodule_file = reference_repo_submodule_file(url, reference_dir, using_local_repo)
334
340
 
335
341
  # if prefetch is on, then grab children immediately to frontload network requests
336
- prefetch(submodule_file) if File.exist?(submodule_file) && prefetch_submodules
342
+ prefetch(submodule_file, attempt_number) if File.exist?(submodule_file) && prefetch_submodules
337
343
 
338
344
  # 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]
345
+ store_updated_repo(url, mirror, repo_name, fail_hard, attempt_number) unless reference_updated[repo_name]
340
346
  end
341
347
  end
342
348
 
343
349
  # Grab the children in the event of a prefetch
344
- def prefetch(submodule_file)
350
+ def prefetch(submodule_file, attempt_number)
345
351
  File.readlines(submodule_file).each do |line|
346
352
  # We don't join these threads explicitly
347
- Thread.new { update_reference_repo(line.strip, false) }
353
+ Thread.new { update_reference_repo(line.strip, false, attempt_number) }
348
354
  end
349
355
  end
350
356
 
351
357
  # Creates or updates the mirror repo then stores an indication
352
358
  # that this repo has been updated on this run of fastclone
353
- def store_updated_repo(url, mirror, repo_name, fail_hard)
359
+ def store_updated_repo(url, mirror, repo_name, fail_hard, attempt_number)
360
+ trigger_pre_clone_hook_if_needed(url, mirror, attempt_number)
361
+ # If pre_clone_hook correctly creates a mirror directory, we don't want to clone, but just update it
354
362
  unless Dir.exist?(mirror)
355
363
  fail_on_error('git', 'clone', verbose ? '--verbose' : '--quiet', '--mirror', url.to_s, mirror.to_s,
356
364
  quiet: !verbose, print_on_failure: print_git_errors)
@@ -414,7 +422,7 @@ module GitFastClone
414
422
  retries_allowed ||= 1
415
423
  attempt_number ||= 0
416
424
 
417
- update_reference_repo(url, true)
425
+ update_reference_repo(url, true, attempt_number)
418
426
  dir = reference_repo_dir(url, reference_dir, using_local_repo)
419
427
 
420
428
  # Sometimes remote updates involve re-packing objects on a different thread
@@ -441,5 +449,17 @@ module GitFastClone
441
449
  def usage
442
450
  'Usage: git fastclone [options] <git-url> [path]'
443
451
  end
452
+
453
+ private def trigger_pre_clone_hook_if_needed(url, mirror, attempt_number)
454
+ return if Dir.exist?(mirror) || !options.include?(:pre_clone_hook)
455
+
456
+ hook_command = options[:pre_clone_hook]
457
+ unless File.exist?(File.expand_path(hook_command))
458
+ puts 'pre_clone_hook script is missing' if verbose
459
+ return
460
+ end
461
+
462
+ popen2e_wrapper(hook_command, url.to_s, mirror.to_s, attempt_number.to_s, quiet: !verbose)
463
+ end
444
464
  end
445
465
  end
@@ -145,6 +145,72 @@ 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' 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(File).to receive(:exist?).and_call_original
155
+ allow(File).to receive(:exist?).with(pre_clone_hook).and_return(true)
156
+ allow(subject).to receive(:with_git_mirror).and_call_original
157
+ allow(subject).to receive(:with_reference_repo_lock) do |_url, &block|
158
+ block.call
159
+ end
160
+ end
161
+
162
+ it 'invokes hook command' do
163
+ allow(subject).to receive(:fail_on_error)
164
+ expect(subject).to receive(:popen2e_wrapper).with(
165
+ pre_clone_hook, 'PH', 'PH/PH', '0',
166
+ { quiet: true }
167
+ ) { runner_execution_double }
168
+
169
+ subject.clone(placeholder_arg, nil, '.', 'config')
170
+ end
171
+
172
+ it 'does not call clone if hook creates mirror' do
173
+ allow(subject).to receive(:popen2e_wrapper).with(
174
+ pre_clone_hook, 'PH', 'PH/PH', '0',
175
+ { quiet: true }
176
+ ) do
177
+ # Emulate creating mirror dir
178
+ allow(Dir).to receive(:exist?).with('PH/PH').and_return(true)
179
+ end
180
+ allow(subject).to receive(:fail_on_error)
181
+
182
+ subject.clone(placeholder_arg, nil, '.', 'config')
183
+ end
184
+
185
+ it 'does not call pre-clone hook if mirror is already created' do
186
+ # Emulate already created mirror dir
187
+ allow(Dir).to receive(:exist?).and_call_original
188
+ allow(Dir).to receive(:exist?).with('PH/PH').and_return(true)
189
+ expect(subject).not_to receive(:popen2e_wrapper).with(
190
+ pre_clone_hook, 'PH', 'PH/PH', '0',
191
+ { quiet: true }
192
+ )
193
+ allow(subject).to receive(:fail_on_error)
194
+
195
+ subject.clone(placeholder_arg, nil, '.', 'config')
196
+ end
197
+
198
+ context 'non-existing script' do
199
+ before(:each) do
200
+ allow(File).to receive(:exist?).with(pre_clone_hook).and_return(false)
201
+ end
202
+
203
+ it 'does not invoke hook command' do
204
+ allow(subject).to receive(:fail_on_error)
205
+ expect(subject).not_to receive(:popen2e_wrapper).with(
206
+ pre_clone_hook, 'PH', 'PH/PH', '0',
207
+ { quiet: true }
208
+ )
209
+
210
+ subject.clone(placeholder_arg, nil, '.', 'config')
211
+ end
212
+ end
213
+ end
148
214
  end
149
215
 
150
216
  describe '.clear_clone_dest_if_needed' do
@@ -249,7 +315,7 @@ describe GitFastClone::Runner do
249
315
  allow(File).to receive(:exist?) { true }
250
316
  subject.prefetch_submodules = true
251
317
  subject.reference_dir = placeholder_arg
252
- subject.update_reference_repo(test_url_valid, false)
318
+ subject.update_reference_repo(test_url_valid, false, 0)
253
319
  end
254
320
  end
255
321
 
@@ -262,7 +328,7 @@ describe GitFastClone::Runner do
262
328
  allow(File).to receive(:exist?) { true }
263
329
  subject.prefetch_submodules = false
264
330
  subject.reference_dir = placeholder_arg
265
- subject.update_reference_repo(placeholder_arg, false)
331
+ subject.update_reference_repo(placeholder_arg, false, 0)
266
332
  end
267
333
  end
268
334
 
@@ -277,7 +343,7 @@ describe GitFastClone::Runner do
277
343
  allow(subject).to receive(:reference_repo_dir) { placeholder_arg }
278
344
  subject.reference_updated = placeholder_hash
279
345
  subject.prefetch_submodules = false
280
- subject.update_reference_repo(placeholder_arg, false)
346
+ subject.update_reference_repo(placeholder_arg, false, 0)
281
347
  end
282
348
  end
283
349
 
@@ -291,7 +357,7 @@ describe GitFastClone::Runner do
291
357
  subject.reference_updated = placeholder_hash
292
358
  subject.reference_dir = placeholder_arg
293
359
  subject.prefetch_submodules = false
294
- subject.update_reference_repo(placeholder_arg, false)
360
+ subject.update_reference_repo(placeholder_arg, false, 0)
295
361
  end
296
362
  end
297
363
  end
@@ -302,7 +368,7 @@ describe GitFastClone::Runner do
302
368
 
303
369
  allow(File).to receive(:readlines) { %w[1 2 3] }
304
370
  subject.prefetch_submodules = true
305
- subject.prefetch(placeholder_arg)
371
+ subject.prefetch(placeholder_arg, 0)
306
372
  end
307
373
  end
308
374
 
@@ -315,7 +381,7 @@ describe GitFastClone::Runner do
315
381
  allow(subject).to receive(:fail_on_error) { raise ex }
316
382
  expect(FileUtils).to receive(:remove_entry_secure).with(placeholder_arg, force: true)
317
383
  expect do
318
- subject.store_updated_repo(placeholder_arg, placeholder_arg, placeholder_arg, true)
384
+ subject.store_updated_repo(placeholder_arg, placeholder_arg, placeholder_arg, true, 0)
319
385
  end.to raise_error(ex)
320
386
  end
321
387
 
@@ -327,7 +393,7 @@ describe GitFastClone::Runner do
327
393
  allow(subject).to receive(:fail_on_error) { raise ex }
328
394
  expect(FileUtils).to_not receive(:remove_entry_secure).with(placeholder_arg, force: true)
329
395
  expect do
330
- subject.store_updated_repo(placeholder_arg, placeholder_arg, placeholder_arg, true)
396
+ subject.store_updated_repo(placeholder_arg, placeholder_arg, placeholder_arg, true, 0)
331
397
  end.to raise_error(ex)
332
398
  end
333
399
  end
@@ -340,7 +406,7 @@ describe GitFastClone::Runner do
340
406
  allow(subject).to receive(:fail_on_error) { raise ex }
341
407
  expect(FileUtils).to receive(:remove_entry_secure).with(placeholder_arg, force: true)
342
408
  expect do
343
- subject.store_updated_repo(placeholder_arg, placeholder_arg, placeholder_arg, false)
409
+ subject.store_updated_repo(placeholder_arg, placeholder_arg, placeholder_arg, false, 0)
344
410
  end.to_not raise_error
345
411
  end
346
412
  end
@@ -351,7 +417,7 @@ describe GitFastClone::Runner do
351
417
  allow(subject).to receive(:fail_on_error)
352
418
 
353
419
  subject.reference_updated = placeholder_hash
354
- subject.store_updated_repo(placeholder_arg, placeholder_arg, placeholder_arg, false)
420
+ subject.store_updated_repo(placeholder_arg, placeholder_arg, placeholder_arg, false, 0)
355
421
  expect(subject.reference_updated).to eq(placeholder_arg => true)
356
422
  end
357
423
  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.5
4
+ version: 1.5.1
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: 2023-12-14 00:00:00.000000000 Z
12
+ date: 2024-03-18 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: colorize