1 2module.exports = rebuild 3 4var readInstalled = require('read-installed') 5var semver = require('semver') 6var log = require('npmlog') 7var npm = require('./npm.js') 8var npa = require('npm-package-arg') 9var usage = require('./utils/usage') 10var output = require('./utils/output.js') 11 12rebuild.usage = usage( 13 'rebuild', 14 'npm rebuild [[<@scope>/<name>]...]' 15) 16 17rebuild.completion = require('./utils/completion/installed-deep.js') 18 19function rebuild (args, cb) { 20 var opt = { depth: npm.config.get('depth'), dev: true } 21 readInstalled(npm.prefix, opt, function (er, data) { 22 log.info('readInstalled', typeof data) 23 if (er) return cb(er) 24 var set = filter(data, args) 25 var folders = Object.keys(set).filter(function (f) { 26 return f !== npm.prefix 27 }) 28 if (!folders.length) return cb() 29 log.silly('rebuild set', folders) 30 cleanBuild(folders, set, cb) 31 }) 32} 33 34function cleanBuild (folders, set, cb) { 35 npm.commands.build(folders, function (er) { 36 if (er) return cb(er) 37 output(folders.map(function (f) { 38 return set[f] + ' ' + f 39 }).join('\n')) 40 cb() 41 }) 42} 43 44function filter (data, args, set, seen) { 45 if (!set) set = {} 46 if (!seen) seen = new Set() 47 if (set.hasOwnProperty(data.path)) return set 48 if (seen.has(data)) return set 49 seen.add(data) 50 var pass 51 if (!args.length) pass = true // rebuild everything 52 else if (data.name && data._id) { 53 for (var i = 0, l = args.length; i < l; i++) { 54 var arg = args[i] 55 var nv = npa(arg) 56 var n = nv.name 57 var v = nv.rawSpec 58 if (n !== data.name) continue 59 if (!semver.satisfies(data.version, v, true)) continue 60 pass = true 61 break 62 } 63 } 64 if (pass && data._id) { 65 log.verbose('rebuild', 'path, id', [data.path, data._id]) 66 set[data.path] = data._id 67 } 68 // need to also dive through kids, always. 69 // since this isn't an install these won't get auto-built unless 70 // they're not dependencies. 71 Object.keys(data.dependencies || {}).forEach(function (d) { 72 // return 73 var dep = data.dependencies[d] 74 if (typeof dep === 'string') return 75 filter(dep, args, set, seen) 76 }) 77 return set 78} 79