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