11cb0ef41Sopenharmony_ciconst { resolve } = require('path')
21cb0ef41Sopenharmony_ciconst npa = require('npm-package-arg')
31cb0ef41Sopenharmony_ciconst semver = require('semver')
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ciconst ArboristWorkspaceCmd = require('../arborist-cmd.js')
61cb0ef41Sopenharmony_ciclass Rebuild extends ArboristWorkspaceCmd {
71cb0ef41Sopenharmony_ci  static description = 'Rebuild a package'
81cb0ef41Sopenharmony_ci  static name = 'rebuild'
91cb0ef41Sopenharmony_ci  static params = [
101cb0ef41Sopenharmony_ci    'global',
111cb0ef41Sopenharmony_ci    'bin-links',
121cb0ef41Sopenharmony_ci    'foreground-scripts',
131cb0ef41Sopenharmony_ci    'ignore-scripts',
141cb0ef41Sopenharmony_ci    ...super.params,
151cb0ef41Sopenharmony_ci  ]
161cb0ef41Sopenharmony_ci
171cb0ef41Sopenharmony_ci  static usage = ['[<package-spec>] ...]']
181cb0ef41Sopenharmony_ci
191cb0ef41Sopenharmony_ci  // TODO
201cb0ef41Sopenharmony_ci  /* istanbul ignore next */
211cb0ef41Sopenharmony_ci  static async completion (opts, npm) {
221cb0ef41Sopenharmony_ci    const completion = require('../utils/completion/installed-deep.js')
231cb0ef41Sopenharmony_ci    return completion(npm, opts)
241cb0ef41Sopenharmony_ci  }
251cb0ef41Sopenharmony_ci
261cb0ef41Sopenharmony_ci  async exec (args) {
271cb0ef41Sopenharmony_ci    const globalTop = resolve(this.npm.globalDir, '..')
281cb0ef41Sopenharmony_ci    const where = this.npm.global ? globalTop : this.npm.prefix
291cb0ef41Sopenharmony_ci    const Arborist = require('@npmcli/arborist')
301cb0ef41Sopenharmony_ci    const arb = new Arborist({
311cb0ef41Sopenharmony_ci      ...this.npm.flatOptions,
321cb0ef41Sopenharmony_ci      path: where,
331cb0ef41Sopenharmony_ci      // TODO when extending ReifyCmd
341cb0ef41Sopenharmony_ci      // workspaces: this.workspaceNames,
351cb0ef41Sopenharmony_ci    })
361cb0ef41Sopenharmony_ci
371cb0ef41Sopenharmony_ci    if (args.length) {
381cb0ef41Sopenharmony_ci      // get the set of nodes matching the name that we want rebuilt
391cb0ef41Sopenharmony_ci      const tree = await arb.loadActual()
401cb0ef41Sopenharmony_ci      const specs = args.map(arg => {
411cb0ef41Sopenharmony_ci        const spec = npa(arg)
421cb0ef41Sopenharmony_ci        if (spec.rawSpec === '*') {
431cb0ef41Sopenharmony_ci          return spec
441cb0ef41Sopenharmony_ci        }
451cb0ef41Sopenharmony_ci
461cb0ef41Sopenharmony_ci        if (spec.type !== 'range' && spec.type !== 'version' && spec.type !== 'directory') {
471cb0ef41Sopenharmony_ci          throw new Error('`npm rebuild` only supports SemVer version/range specifiers')
481cb0ef41Sopenharmony_ci        }
491cb0ef41Sopenharmony_ci
501cb0ef41Sopenharmony_ci        return spec
511cb0ef41Sopenharmony_ci      })
521cb0ef41Sopenharmony_ci      const nodes = tree.inventory.filter(node => this.isNode(specs, node))
531cb0ef41Sopenharmony_ci
541cb0ef41Sopenharmony_ci      await arb.rebuild({ nodes })
551cb0ef41Sopenharmony_ci    } else {
561cb0ef41Sopenharmony_ci      await arb.rebuild()
571cb0ef41Sopenharmony_ci    }
581cb0ef41Sopenharmony_ci
591cb0ef41Sopenharmony_ci    this.npm.output('rebuilt dependencies successfully')
601cb0ef41Sopenharmony_ci  }
611cb0ef41Sopenharmony_ci
621cb0ef41Sopenharmony_ci  isNode (specs, node) {
631cb0ef41Sopenharmony_ci    return specs.some(spec => {
641cb0ef41Sopenharmony_ci      if (spec.type === 'directory') {
651cb0ef41Sopenharmony_ci        return node.path === spec.fetchSpec
661cb0ef41Sopenharmony_ci      }
671cb0ef41Sopenharmony_ci
681cb0ef41Sopenharmony_ci      if (spec.name !== node.name) {
691cb0ef41Sopenharmony_ci        return false
701cb0ef41Sopenharmony_ci      }
711cb0ef41Sopenharmony_ci
721cb0ef41Sopenharmony_ci      if (spec.rawSpec === '' || spec.rawSpec === '*') {
731cb0ef41Sopenharmony_ci        return true
741cb0ef41Sopenharmony_ci      }
751cb0ef41Sopenharmony_ci
761cb0ef41Sopenharmony_ci      const { version } = node.package
771cb0ef41Sopenharmony_ci      // TODO: add tests for a package with missing version
781cb0ef41Sopenharmony_ci      return semver.satisfies(version, spec.fetchSpec)
791cb0ef41Sopenharmony_ci    })
801cb0ef41Sopenharmony_ci  }
811cb0ef41Sopenharmony_ci}
821cb0ef41Sopenharmony_cimodule.exports = Rebuild
83