1 | const spawn = require('@npmcli/promise-spawn')
|
---|
2 | const promiseRetry = require('promise-retry')
|
---|
3 | const makeError = require('./make-error.js')
|
---|
4 | const whichGit = require('./which.js')
|
---|
5 | const makeOpts = require('./opts.js')
|
---|
6 | const procLog = require('./proc-log.js')
|
---|
7 |
|
---|
8 | module.exports = (gitArgs, opts = {}) => {
|
---|
9 | const gitPath = whichGit(opts)
|
---|
10 |
|
---|
11 | if (gitPath instanceof Error) { return Promise.reject(gitPath) }
|
---|
12 |
|
---|
13 | // undocumented option, mostly only here for tests
|
---|
14 | const args = opts.allowReplace || gitArgs[0] === '--no-replace-objects'
|
---|
15 | ? gitArgs
|
---|
16 | : ['--no-replace-objects', ...gitArgs]
|
---|
17 |
|
---|
18 | const log = opts.log || procLog
|
---|
19 | let retry = opts.retry
|
---|
20 | if (retry === null || retry === undefined) {
|
---|
21 | retry = {
|
---|
22 | retries: opts.fetchRetries || 2,
|
---|
23 | factor: opts.fetchRetryFactor || 10,
|
---|
24 | maxTimeout: opts.fetchRetryMaxtimeout || 60000,
|
---|
25 | minTimeout: opts.fetchRetryMintimeout || 1000
|
---|
26 | }
|
---|
27 | }
|
---|
28 | return promiseRetry((retry, number) => {
|
---|
29 | if (number !== 1) {
|
---|
30 | log.silly('git', `Retrying git command: ${
|
---|
31 | args.join(' ')} attempt # ${number}`)
|
---|
32 | }
|
---|
33 |
|
---|
34 | return spawn(gitPath, args, makeOpts(opts))
|
---|
35 | .catch(er => {
|
---|
36 | const gitError = makeError(er)
|
---|
37 | if (!gitError.shouldRetry(number)) {
|
---|
38 | throw gitError
|
---|
39 | }
|
---|
40 | retry(gitError)
|
---|
41 | })
|
---|
42 | }, retry)
|
---|
43 | }
|
---|