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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f23af05975dc472665784e91a3e69112694837cbd2a873076a7fb3197828970f
4
- data.tar.gz: b3e2a26cbf1aff738c647eb37aa6b661975a396b680352288f68c0ba20da429d
3
+ metadata.gz: 8b86bd9aa9bc5a377dd7d5b7b456eb0de1aee7ffd1e746642775d08042e9714f
4
+ data.tar.gz: '08dff02e06757c022c7ee0fec4890261c3d3efbee76130f2c7f4e0c2cdd91361'
5
5
  SHA512:
6
- metadata.gz: b9f239ae1a6cdf02d8aef5944f4d704bffaeb0d410191d7f5b7c759ba1d525dca27dd8efcec2e19ac4ffee9787ff3706b16860d0e16ff493136bcb2378b70a7c
7
- data.tar.gz: fb954090b896bf41a396c956847133fc7d367fc564fbc8e3973ed61f2738b16f3926397b4526994d6c6d1781439970055f67e5c7d8137a0174a4f614b69f7a60
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 <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.0'
6
6
  end
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.5
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: 2023-12-14 00:00:00.000000000 Z
12
+ date: 2024-02-23 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: colorize