11cb0ef41Sopenharmony_ciconst Fetcher = require('./fetcher.js')
21cb0ef41Sopenharmony_ciconst FileFetcher = require('./file.js')
31cb0ef41Sopenharmony_ciconst RemoteFetcher = require('./remote.js')
41cb0ef41Sopenharmony_ciconst DirFetcher = require('./dir.js')
51cb0ef41Sopenharmony_ciconst hashre = /^[a-f0-9]{40}$/
61cb0ef41Sopenharmony_ciconst git = require('@npmcli/git')
71cb0ef41Sopenharmony_ciconst pickManifest = require('npm-pick-manifest')
81cb0ef41Sopenharmony_ciconst npa = require('npm-package-arg')
91cb0ef41Sopenharmony_ciconst { Minipass } = require('minipass')
101cb0ef41Sopenharmony_ciconst cacache = require('cacache')
111cb0ef41Sopenharmony_ciconst log = require('proc-log')
121cb0ef41Sopenharmony_ciconst npm = require('./util/npm.js')
131cb0ef41Sopenharmony_ci
141cb0ef41Sopenharmony_ciconst _resolvedFromRepo = Symbol('_resolvedFromRepo')
151cb0ef41Sopenharmony_ciconst _resolvedFromHosted = Symbol('_resolvedFromHosted')
161cb0ef41Sopenharmony_ciconst _resolvedFromClone = Symbol('_resolvedFromClone')
171cb0ef41Sopenharmony_ciconst _tarballFromResolved = Symbol.for('pacote.Fetcher._tarballFromResolved')
181cb0ef41Sopenharmony_ciconst _addGitSha = Symbol('_addGitSha')
191cb0ef41Sopenharmony_ciconst addGitSha = require('./util/add-git-sha.js')
201cb0ef41Sopenharmony_ciconst _clone = Symbol('_clone')
211cb0ef41Sopenharmony_ciconst _cloneHosted = Symbol('_cloneHosted')
221cb0ef41Sopenharmony_ciconst _cloneRepo = Symbol('_cloneRepo')
231cb0ef41Sopenharmony_ciconst _setResolvedWithSha = Symbol('_setResolvedWithSha')
241cb0ef41Sopenharmony_ciconst _prepareDir = Symbol('_prepareDir')
251cb0ef41Sopenharmony_ciconst _readPackageJson = Symbol.for('package.Fetcher._readPackageJson')
261cb0ef41Sopenharmony_ci
271cb0ef41Sopenharmony_ci// get the repository url.
281cb0ef41Sopenharmony_ci// prefer https if there's auth, since ssh will drop that.
291cb0ef41Sopenharmony_ci// otherwise, prefer ssh if available (more secure).
301cb0ef41Sopenharmony_ci// We have to add the git+ back because npa suppresses it.
311cb0ef41Sopenharmony_ciconst repoUrl = (h, opts) =>
321cb0ef41Sopenharmony_ci  h.sshurl && !(h.https && h.auth) && addGitPlus(h.sshurl(opts)) ||
331cb0ef41Sopenharmony_ci  h.https && addGitPlus(h.https(opts))
341cb0ef41Sopenharmony_ci
351cb0ef41Sopenharmony_ci// add git+ to the url, but only one time.
361cb0ef41Sopenharmony_ciconst addGitPlus = url => url && `git+${url}`.replace(/^(git\+)+/, 'git+')
371cb0ef41Sopenharmony_ci
381cb0ef41Sopenharmony_ciclass GitFetcher extends Fetcher {
391cb0ef41Sopenharmony_ci  constructor (spec, opts) {
401cb0ef41Sopenharmony_ci    super(spec, opts)
411cb0ef41Sopenharmony_ci
421cb0ef41Sopenharmony_ci    // we never want to compare integrity for git dependencies: npm/rfcs#525
431cb0ef41Sopenharmony_ci    if (this.opts.integrity) {
441cb0ef41Sopenharmony_ci      delete this.opts.integrity
451cb0ef41Sopenharmony_ci      log.warn(`skipping integrity check for git dependency ${this.spec.fetchSpec}`)
461cb0ef41Sopenharmony_ci    }
471cb0ef41Sopenharmony_ci
481cb0ef41Sopenharmony_ci    this.resolvedRef = null
491cb0ef41Sopenharmony_ci    if (this.spec.hosted) {
501cb0ef41Sopenharmony_ci      this.from = this.spec.hosted.shortcut({ noCommittish: false })
511cb0ef41Sopenharmony_ci    }
521cb0ef41Sopenharmony_ci
531cb0ef41Sopenharmony_ci    // shortcut: avoid full clone when we can go straight to the tgz
541cb0ef41Sopenharmony_ci    // if we have the full sha and it's a hosted git platform
551cb0ef41Sopenharmony_ci    if (this.spec.gitCommittish && hashre.test(this.spec.gitCommittish)) {
561cb0ef41Sopenharmony_ci      this.resolvedSha = this.spec.gitCommittish
571cb0ef41Sopenharmony_ci      // use hosted.tarball() when we shell to RemoteFetcher later
581cb0ef41Sopenharmony_ci      this.resolved = this.spec.hosted
591cb0ef41Sopenharmony_ci        ? repoUrl(this.spec.hosted, { noCommittish: false })
601cb0ef41Sopenharmony_ci        : this.spec.rawSpec
611cb0ef41Sopenharmony_ci    } else {
621cb0ef41Sopenharmony_ci      this.resolvedSha = ''
631cb0ef41Sopenharmony_ci    }
641cb0ef41Sopenharmony_ci
651cb0ef41Sopenharmony_ci    this.Arborist = opts.Arborist || null
661cb0ef41Sopenharmony_ci  }
671cb0ef41Sopenharmony_ci
681cb0ef41Sopenharmony_ci  // just exposed to make it easier to test all the combinations
691cb0ef41Sopenharmony_ci  static repoUrl (hosted, opts) {
701cb0ef41Sopenharmony_ci    return repoUrl(hosted, opts)
711cb0ef41Sopenharmony_ci  }
721cb0ef41Sopenharmony_ci
731cb0ef41Sopenharmony_ci  get types () {
741cb0ef41Sopenharmony_ci    return ['git']
751cb0ef41Sopenharmony_ci  }
761cb0ef41Sopenharmony_ci
771cb0ef41Sopenharmony_ci  resolve () {
781cb0ef41Sopenharmony_ci    // likely a hosted git repo with a sha, so get the tarball url
791cb0ef41Sopenharmony_ci    // but in general, no reason to resolve() more than necessary!
801cb0ef41Sopenharmony_ci    if (this.resolved) {
811cb0ef41Sopenharmony_ci      return super.resolve()
821cb0ef41Sopenharmony_ci    }
831cb0ef41Sopenharmony_ci
841cb0ef41Sopenharmony_ci    // fetch the git repo and then look at the current hash
851cb0ef41Sopenharmony_ci    const h = this.spec.hosted
861cb0ef41Sopenharmony_ci    // try to use ssh, fall back to git.
871cb0ef41Sopenharmony_ci    return h ? this[_resolvedFromHosted](h)
881cb0ef41Sopenharmony_ci      : this[_resolvedFromRepo](this.spec.fetchSpec)
891cb0ef41Sopenharmony_ci  }
901cb0ef41Sopenharmony_ci
911cb0ef41Sopenharmony_ci  // first try https, since that's faster and passphrase-less for
921cb0ef41Sopenharmony_ci  // public repos, and supports private repos when auth is provided.
931cb0ef41Sopenharmony_ci  // Fall back to SSH to support private repos
941cb0ef41Sopenharmony_ci  // NB: we always store the https url in resolved field if auth
951cb0ef41Sopenharmony_ci  // is present, otherwise ssh if the hosted type provides it
961cb0ef41Sopenharmony_ci  [_resolvedFromHosted] (hosted) {
971cb0ef41Sopenharmony_ci    return this[_resolvedFromRepo](hosted.https && hosted.https())
981cb0ef41Sopenharmony_ci      .catch(er => {
991cb0ef41Sopenharmony_ci        // Throw early since we know pathspec errors will fail again if retried
1001cb0ef41Sopenharmony_ci        if (er instanceof git.errors.GitPathspecError) {
1011cb0ef41Sopenharmony_ci          throw er
1021cb0ef41Sopenharmony_ci        }
1031cb0ef41Sopenharmony_ci        const ssh = hosted.sshurl && hosted.sshurl()
1041cb0ef41Sopenharmony_ci        // no fallthrough if we can't fall through or have https auth
1051cb0ef41Sopenharmony_ci        if (!ssh || hosted.auth) {
1061cb0ef41Sopenharmony_ci          throw er
1071cb0ef41Sopenharmony_ci        }
1081cb0ef41Sopenharmony_ci        return this[_resolvedFromRepo](ssh)
1091cb0ef41Sopenharmony_ci      })
1101cb0ef41Sopenharmony_ci  }
1111cb0ef41Sopenharmony_ci
1121cb0ef41Sopenharmony_ci  [_resolvedFromRepo] (gitRemote) {
1131cb0ef41Sopenharmony_ci    // XXX make this a custom error class
1141cb0ef41Sopenharmony_ci    if (!gitRemote) {
1151cb0ef41Sopenharmony_ci      return Promise.reject(new Error(`No git url for ${this.spec}`))
1161cb0ef41Sopenharmony_ci    }
1171cb0ef41Sopenharmony_ci    const gitRange = this.spec.gitRange
1181cb0ef41Sopenharmony_ci    const name = this.spec.name
1191cb0ef41Sopenharmony_ci    return git.revs(gitRemote, this.opts).then(remoteRefs => {
1201cb0ef41Sopenharmony_ci      return gitRange ? pickManifest({
1211cb0ef41Sopenharmony_ci        versions: remoteRefs.versions,
1221cb0ef41Sopenharmony_ci        'dist-tags': remoteRefs['dist-tags'],
1231cb0ef41Sopenharmony_ci        name,
1241cb0ef41Sopenharmony_ci      }, gitRange, this.opts)
1251cb0ef41Sopenharmony_ci        : this.spec.gitCommittish ?
1261cb0ef41Sopenharmony_ci          remoteRefs.refs[this.spec.gitCommittish] ||
1271cb0ef41Sopenharmony_ci          remoteRefs.refs[remoteRefs.shas[this.spec.gitCommittish]]
1281cb0ef41Sopenharmony_ci          : remoteRefs.refs.HEAD // no git committish, get default head
1291cb0ef41Sopenharmony_ci    }).then(revDoc => {
1301cb0ef41Sopenharmony_ci      // the committish provided isn't in the rev list
1311cb0ef41Sopenharmony_ci      // things like HEAD~3 or @yesterday can land here.
1321cb0ef41Sopenharmony_ci      if (!revDoc || !revDoc.sha) {
1331cb0ef41Sopenharmony_ci        return this[_resolvedFromClone]()
1341cb0ef41Sopenharmony_ci      }
1351cb0ef41Sopenharmony_ci
1361cb0ef41Sopenharmony_ci      this.resolvedRef = revDoc
1371cb0ef41Sopenharmony_ci      this.resolvedSha = revDoc.sha
1381cb0ef41Sopenharmony_ci      this[_addGitSha](revDoc.sha)
1391cb0ef41Sopenharmony_ci      return this.resolved
1401cb0ef41Sopenharmony_ci    })
1411cb0ef41Sopenharmony_ci  }
1421cb0ef41Sopenharmony_ci
1431cb0ef41Sopenharmony_ci  [_setResolvedWithSha] (withSha) {
1441cb0ef41Sopenharmony_ci    // we haven't cloned, so a tgz download is still faster
1451cb0ef41Sopenharmony_ci    // of course, if it's not a known host, we can't do that.
1461cb0ef41Sopenharmony_ci    this.resolved = !this.spec.hosted ? withSha
1471cb0ef41Sopenharmony_ci      : repoUrl(npa(withSha).hosted, { noCommittish: false })
1481cb0ef41Sopenharmony_ci  }
1491cb0ef41Sopenharmony_ci
1501cb0ef41Sopenharmony_ci  // when we get the git sha, we affix it to our spec to build up
1511cb0ef41Sopenharmony_ci  // either a git url with a hash, or a tarball download URL
1521cb0ef41Sopenharmony_ci  [_addGitSha] (sha) {
1531cb0ef41Sopenharmony_ci    this[_setResolvedWithSha](addGitSha(this.spec, sha))
1541cb0ef41Sopenharmony_ci  }
1551cb0ef41Sopenharmony_ci
1561cb0ef41Sopenharmony_ci  [_resolvedFromClone] () {
1571cb0ef41Sopenharmony_ci    // do a full or shallow clone, then look at the HEAD
1581cb0ef41Sopenharmony_ci    // kind of wasteful, but no other option, really
1591cb0ef41Sopenharmony_ci    return this[_clone](dir => this.resolved)
1601cb0ef41Sopenharmony_ci  }
1611cb0ef41Sopenharmony_ci
1621cb0ef41Sopenharmony_ci  [_prepareDir] (dir) {
1631cb0ef41Sopenharmony_ci    return this[_readPackageJson](dir + '/package.json').then(mani => {
1641cb0ef41Sopenharmony_ci      // no need if we aren't going to do any preparation.
1651cb0ef41Sopenharmony_ci      const scripts = mani.scripts
1661cb0ef41Sopenharmony_ci      if (!mani.workspaces && (!scripts || !(
1671cb0ef41Sopenharmony_ci        scripts.postinstall ||
1681cb0ef41Sopenharmony_ci          scripts.build ||
1691cb0ef41Sopenharmony_ci          scripts.preinstall ||
1701cb0ef41Sopenharmony_ci          scripts.install ||
1711cb0ef41Sopenharmony_ci          scripts.prepack ||
1721cb0ef41Sopenharmony_ci          scripts.prepare))) {
1731cb0ef41Sopenharmony_ci        return
1741cb0ef41Sopenharmony_ci      }
1751cb0ef41Sopenharmony_ci
1761cb0ef41Sopenharmony_ci      // to avoid cases where we have an cycle of git deps that depend
1771cb0ef41Sopenharmony_ci      // on one another, we only ever do preparation for one instance
1781cb0ef41Sopenharmony_ci      // of a given git dep along the chain of installations.
1791cb0ef41Sopenharmony_ci      // Note that this does mean that a dependency MAY in theory end up
1801cb0ef41Sopenharmony_ci      // trying to run its prepare script using a dependency that has not
1811cb0ef41Sopenharmony_ci      // been properly prepared itself, but that edge case is smaller
1821cb0ef41Sopenharmony_ci      // and less hazardous than a fork bomb of npm and git commands.
1831cb0ef41Sopenharmony_ci      const noPrepare = !process.env._PACOTE_NO_PREPARE_ ? []
1841cb0ef41Sopenharmony_ci        : process.env._PACOTE_NO_PREPARE_.split('\n')
1851cb0ef41Sopenharmony_ci      if (noPrepare.includes(this.resolved)) {
1861cb0ef41Sopenharmony_ci        log.info('prepare', 'skip prepare, already seen', this.resolved)
1871cb0ef41Sopenharmony_ci        return
1881cb0ef41Sopenharmony_ci      }
1891cb0ef41Sopenharmony_ci      noPrepare.push(this.resolved)
1901cb0ef41Sopenharmony_ci
1911cb0ef41Sopenharmony_ci      // the DirFetcher will do its own preparation to run the prepare scripts
1921cb0ef41Sopenharmony_ci      // All we have to do is put the deps in place so that it can succeed.
1931cb0ef41Sopenharmony_ci      return npm(
1941cb0ef41Sopenharmony_ci        this.npmBin,
1951cb0ef41Sopenharmony_ci        [].concat(this.npmInstallCmd).concat(this.npmCliConfig),
1961cb0ef41Sopenharmony_ci        dir,
1971cb0ef41Sopenharmony_ci        { ...process.env, _PACOTE_NO_PREPARE_: noPrepare.join('\n') },
1981cb0ef41Sopenharmony_ci        { message: 'git dep preparation failed' }
1991cb0ef41Sopenharmony_ci      )
2001cb0ef41Sopenharmony_ci    })
2011cb0ef41Sopenharmony_ci  }
2021cb0ef41Sopenharmony_ci
2031cb0ef41Sopenharmony_ci  [_tarballFromResolved] () {
2041cb0ef41Sopenharmony_ci    const stream = new Minipass()
2051cb0ef41Sopenharmony_ci    stream.resolved = this.resolved
2061cb0ef41Sopenharmony_ci    stream.from = this.from
2071cb0ef41Sopenharmony_ci
2081cb0ef41Sopenharmony_ci    // check it out and then shell out to the DirFetcher tarball packer
2091cb0ef41Sopenharmony_ci    this[_clone](dir => this[_prepareDir](dir)
2101cb0ef41Sopenharmony_ci      .then(() => new Promise((res, rej) => {
2111cb0ef41Sopenharmony_ci        if (!this.Arborist) {
2121cb0ef41Sopenharmony_ci          throw new Error('GitFetcher requires an Arborist constructor to pack a tarball')
2131cb0ef41Sopenharmony_ci        }
2141cb0ef41Sopenharmony_ci        const df = new DirFetcher(`file:${dir}`, {
2151cb0ef41Sopenharmony_ci          ...this.opts,
2161cb0ef41Sopenharmony_ci          Arborist: this.Arborist,
2171cb0ef41Sopenharmony_ci          resolved: null,
2181cb0ef41Sopenharmony_ci          integrity: null,
2191cb0ef41Sopenharmony_ci        })
2201cb0ef41Sopenharmony_ci        const dirStream = df[_tarballFromResolved]()
2211cb0ef41Sopenharmony_ci        dirStream.on('error', rej)
2221cb0ef41Sopenharmony_ci        dirStream.on('end', res)
2231cb0ef41Sopenharmony_ci        dirStream.pipe(stream)
2241cb0ef41Sopenharmony_ci      }))).catch(
2251cb0ef41Sopenharmony_ci      /* istanbul ignore next: very unlikely and hard to test */
2261cb0ef41Sopenharmony_ci      er => stream.emit('error', er)
2271cb0ef41Sopenharmony_ci    )
2281cb0ef41Sopenharmony_ci    return stream
2291cb0ef41Sopenharmony_ci  }
2301cb0ef41Sopenharmony_ci
2311cb0ef41Sopenharmony_ci  // clone a git repo into a temp folder (or fetch and unpack if possible)
2321cb0ef41Sopenharmony_ci  // handler accepts a directory, and returns a promise that resolves
2331cb0ef41Sopenharmony_ci  // when we're done with it, at which point, cacache deletes it
2341cb0ef41Sopenharmony_ci  //
2351cb0ef41Sopenharmony_ci  // TODO: after cloning, create a tarball of the folder, and add to the cache
2361cb0ef41Sopenharmony_ci  // with cacache.put.stream(), using a key that's deterministic based on the
2371cb0ef41Sopenharmony_ci  // spec and repo, so that we don't ever clone the same thing multiple times.
2381cb0ef41Sopenharmony_ci  [_clone] (handler, tarballOk = true) {
2391cb0ef41Sopenharmony_ci    const o = { tmpPrefix: 'git-clone' }
2401cb0ef41Sopenharmony_ci    const ref = this.resolvedSha || this.spec.gitCommittish
2411cb0ef41Sopenharmony_ci    const h = this.spec.hosted
2421cb0ef41Sopenharmony_ci    const resolved = this.resolved
2431cb0ef41Sopenharmony_ci
2441cb0ef41Sopenharmony_ci    // can be set manually to false to fall back to actual git clone
2451cb0ef41Sopenharmony_ci    tarballOk = tarballOk &&
2461cb0ef41Sopenharmony_ci      h && resolved === repoUrl(h, { noCommittish: false }) && h.tarball
2471cb0ef41Sopenharmony_ci
2481cb0ef41Sopenharmony_ci    return cacache.tmp.withTmp(this.cache, o, async tmp => {
2491cb0ef41Sopenharmony_ci      // if we're resolved, and have a tarball url, shell out to RemoteFetcher
2501cb0ef41Sopenharmony_ci      if (tarballOk) {
2511cb0ef41Sopenharmony_ci        const nameat = this.spec.name ? `${this.spec.name}@` : ''
2521cb0ef41Sopenharmony_ci        return new RemoteFetcher(h.tarball({ noCommittish: false }), {
2531cb0ef41Sopenharmony_ci          ...this.opts,
2541cb0ef41Sopenharmony_ci          allowGitIgnore: true,
2551cb0ef41Sopenharmony_ci          pkgid: `git:${nameat}${this.resolved}`,
2561cb0ef41Sopenharmony_ci          resolved: this.resolved,
2571cb0ef41Sopenharmony_ci          integrity: null, // it'll always be different, if we have one
2581cb0ef41Sopenharmony_ci        }).extract(tmp).then(() => handler(tmp), er => {
2591cb0ef41Sopenharmony_ci          // fall back to ssh download if tarball fails
2601cb0ef41Sopenharmony_ci          if (er.constructor.name.match(/^Http/)) {
2611cb0ef41Sopenharmony_ci            return this[_clone](handler, false)
2621cb0ef41Sopenharmony_ci          } else {
2631cb0ef41Sopenharmony_ci            throw er
2641cb0ef41Sopenharmony_ci          }
2651cb0ef41Sopenharmony_ci        })
2661cb0ef41Sopenharmony_ci      }
2671cb0ef41Sopenharmony_ci
2681cb0ef41Sopenharmony_ci      const sha = await (
2691cb0ef41Sopenharmony_ci        h ? this[_cloneHosted](ref, tmp)
2701cb0ef41Sopenharmony_ci        : this[_cloneRepo](this.spec.fetchSpec, ref, tmp)
2711cb0ef41Sopenharmony_ci      )
2721cb0ef41Sopenharmony_ci      this.resolvedSha = sha
2731cb0ef41Sopenharmony_ci      if (!this.resolved) {
2741cb0ef41Sopenharmony_ci        await this[_addGitSha](sha)
2751cb0ef41Sopenharmony_ci      }
2761cb0ef41Sopenharmony_ci      return handler(tmp)
2771cb0ef41Sopenharmony_ci    })
2781cb0ef41Sopenharmony_ci  }
2791cb0ef41Sopenharmony_ci
2801cb0ef41Sopenharmony_ci  // first try https, since that's faster and passphrase-less for
2811cb0ef41Sopenharmony_ci  // public repos, and supports private repos when auth is provided.
2821cb0ef41Sopenharmony_ci  // Fall back to SSH to support private repos
2831cb0ef41Sopenharmony_ci  // NB: we always store the https url in resolved field if auth
2841cb0ef41Sopenharmony_ci  // is present, otherwise ssh if the hosted type provides it
2851cb0ef41Sopenharmony_ci  [_cloneHosted] (ref, tmp) {
2861cb0ef41Sopenharmony_ci    const hosted = this.spec.hosted
2871cb0ef41Sopenharmony_ci    return this[_cloneRepo](hosted.https({ noCommittish: true }), ref, tmp)
2881cb0ef41Sopenharmony_ci      .catch(er => {
2891cb0ef41Sopenharmony_ci        // Throw early since we know pathspec errors will fail again if retried
2901cb0ef41Sopenharmony_ci        if (er instanceof git.errors.GitPathspecError) {
2911cb0ef41Sopenharmony_ci          throw er
2921cb0ef41Sopenharmony_ci        }
2931cb0ef41Sopenharmony_ci        const ssh = hosted.sshurl && hosted.sshurl({ noCommittish: true })
2941cb0ef41Sopenharmony_ci        // no fallthrough if we can't fall through or have https auth
2951cb0ef41Sopenharmony_ci        if (!ssh || hosted.auth) {
2961cb0ef41Sopenharmony_ci          throw er
2971cb0ef41Sopenharmony_ci        }
2981cb0ef41Sopenharmony_ci        return this[_cloneRepo](ssh, ref, tmp)
2991cb0ef41Sopenharmony_ci      })
3001cb0ef41Sopenharmony_ci  }
3011cb0ef41Sopenharmony_ci
3021cb0ef41Sopenharmony_ci  [_cloneRepo] (repo, ref, tmp) {
3031cb0ef41Sopenharmony_ci    const { opts, spec } = this
3041cb0ef41Sopenharmony_ci    return git.clone(repo, ref, tmp, { ...opts, spec })
3051cb0ef41Sopenharmony_ci  }
3061cb0ef41Sopenharmony_ci
3071cb0ef41Sopenharmony_ci  manifest () {
3081cb0ef41Sopenharmony_ci    if (this.package) {
3091cb0ef41Sopenharmony_ci      return Promise.resolve(this.package)
3101cb0ef41Sopenharmony_ci    }
3111cb0ef41Sopenharmony_ci
3121cb0ef41Sopenharmony_ci    return this.spec.hosted && this.resolved
3131cb0ef41Sopenharmony_ci      ? FileFetcher.prototype.manifest.apply(this)
3141cb0ef41Sopenharmony_ci      : this[_clone](dir =>
3151cb0ef41Sopenharmony_ci        this[_readPackageJson](dir + '/package.json')
3161cb0ef41Sopenharmony_ci          .then(mani => this.package = {
3171cb0ef41Sopenharmony_ci            ...mani,
3181cb0ef41Sopenharmony_ci            _resolved: this.resolved,
3191cb0ef41Sopenharmony_ci            _from: this.from,
3201cb0ef41Sopenharmony_ci          }))
3211cb0ef41Sopenharmony_ci  }
3221cb0ef41Sopenharmony_ci
3231cb0ef41Sopenharmony_ci  packument () {
3241cb0ef41Sopenharmony_ci    return FileFetcher.prototype.packument.apply(this)
3251cb0ef41Sopenharmony_ci  }
3261cb0ef41Sopenharmony_ci}
3271cb0ef41Sopenharmony_cimodule.exports = GitFetcher
328