1const { resolve } = require('path') 2const npa = require('npm-package-arg') 3const semver = require('semver') 4 5const ArboristWorkspaceCmd = require('../arborist-cmd.js') 6class Rebuild extends ArboristWorkspaceCmd { 7 static description = 'Rebuild a package' 8 static name = 'rebuild' 9 static params = [ 10 'global', 11 'bin-links', 12 'foreground-scripts', 13 'ignore-scripts', 14 ...super.params, 15 ] 16 17 static usage = ['[<package-spec>] ...]'] 18 19 // TODO 20 /* istanbul ignore next */ 21 static async completion (opts, npm) { 22 const completion = require('../utils/completion/installed-deep.js') 23 return completion(npm, opts) 24 } 25 26 async exec (args) { 27 const globalTop = resolve(this.npm.globalDir, '..') 28 const where = this.npm.global ? globalTop : this.npm.prefix 29 const Arborist = require('@npmcli/arborist') 30 const arb = new Arborist({ 31 ...this.npm.flatOptions, 32 path: where, 33 // TODO when extending ReifyCmd 34 // workspaces: this.workspaceNames, 35 }) 36 37 if (args.length) { 38 // get the set of nodes matching the name that we want rebuilt 39 const tree = await arb.loadActual() 40 const specs = args.map(arg => { 41 const spec = npa(arg) 42 if (spec.rawSpec === '*') { 43 return spec 44 } 45 46 if (spec.type !== 'range' && spec.type !== 'version' && spec.type !== 'directory') { 47 throw new Error('`npm rebuild` only supports SemVer version/range specifiers') 48 } 49 50 return spec 51 }) 52 const nodes = tree.inventory.filter(node => this.isNode(specs, node)) 53 54 await arb.rebuild({ nodes }) 55 } else { 56 await arb.rebuild() 57 } 58 59 this.npm.output('rebuilt dependencies successfully') 60 } 61 62 isNode (specs, node) { 63 return specs.some(spec => { 64 if (spec.type === 'directory') { 65 return node.path === spec.fetchSpec 66 } 67 68 if (spec.name !== node.name) { 69 return false 70 } 71 72 if (spec.rawSpec === '' || spec.rawSpec === '*') { 73 return true 74 } 75 76 const { version } = node.package 77 // TODO: add tests for a package with missing version 78 return semver.satisfies(version, spec.fetchSpec) 79 }) 80 } 81} 82module.exports = Rebuild 83