Skip to content

Commit e32956f

Browse files
author
Michael Perrotte
committed
feat: updated 'npm install' command
- functionality to get diff and explicitRequets from arborist instace requires @npmcli/[email protected] - create printResult function - output install action time (fairly naively) - added functionality to create and print archy dep tree
1 parent bf3370b commit e32956f

File tree

1 file changed

+113
-41
lines changed

1 file changed

+113
-41
lines changed

lib/install.js

Lines changed: 113 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,30 @@
1616

1717
module.exports = install
1818

19-
var usage = require('./utils/usage')
19+
// --- node core modules
20+
const fs = require('fs')
21+
// - @npmcli modules
22+
const Arborist = require('@npmcli/arborist')
23+
const log = require('npmlog')
24+
const validate = require('aproba')
25+
// - deps
26+
const asyncMap = require('slide').asyncMap // XXX remove this
27+
const archy = require('archy')
28+
// - npm internal utils
29+
const audit = require('./install/audit.js')
30+
const {
31+
getPrintFundingReport,
32+
getPrintFundingReportJSON
33+
} = require('./install/fund.js')
34+
const usage = require('./utils/usage')
35+
const npm = require('./npm.js')
36+
const output = require('./utils/output.js')
37+
const errorMessage = require('./utils/error-message.js')
38+
// XXX this file doesn't exist anymore; remove this
39+
// const sillyLogTree = require('./util/silly-log-tree.js')
40+
// ---
41+
42+
const path = require('path')
2043

2144
install.usage = usage(
2245
'install',
@@ -34,8 +57,6 @@ install.usage = usage(
3457
'[--save-prod|--save-dev|--save-optional] [--save-exact] [--no-save]'
3558
)
3659

37-
const npa = require('npm-package-arg')
38-
3960
install.completion = function (opts, cb) {
4061
validate('OF', arguments)
4162
// install can complete to a folder with a package.json, or any package.
@@ -95,69 +116,120 @@ install.completion = function (opts, cb) {
95116
cb()
96117
}
97118

98-
const Arborist = require('@npmcli/arborist')
99-
100-
// dependencies
101-
var log = require('npmlog')
102-
// const sillyLogTree = require('./util/silly-log-tree.js')
103-
104-
// npm internal utils
105-
var npm = require('./npm.js')
106-
var output = require('./utils/output.js')
107-
var saveMetrics = require('./utils/metrics.js').save
108-
109-
// install specific libraries
110-
var audit = require('./install/audit.js')
111-
var {
112-
getPrintFundingReport,
113-
getPrintFundingReportJSON
114-
} = require('./install/fund.js')
115-
var errorMessage = require('./utils/error-message.js')
116-
117-
const path = require('path')
118-
119-
function install (where, args, cb) {
119+
async function install (where, args, cb) {
120120
if (!cb) {
121121
cb = args
122122
args = where
123123
where = null
124124
}
125+
125126
// the /path/to/node_modules/..
126127
const globalTop = path.resolve(npm.globalDir, '..')
127-
if (!where) {
128-
where = npm.flatOptions.global
128+
const {
129+
dryRun,
130+
global: isGlobalInstall
131+
} = npm.flatOptions
132+
133+
// Determine where install is happening
134+
// - If `where` is NOT set, then we need to determine if it's a global install
135+
// or if it's a local context install (hence nested ternary)
136+
// - `where` IS SET, just use it
137+
where = (!where)
138+
? (isGlobalInstall)
129139
? globalTop
130140
: npm.prefix
131-
}
132-
const {dryRun} = npm.flatOptions
141+
: where
133142

134143
// TODO: Add warnings for other deprecated flags
135144
if (npm.config.get('dev')) {
136145
log.warn('install', 'Usage of the `--dev` option is deprecated. Use `--include=dev` instead.')
137146
}
138147

148+
// If global install, and NO args passed; user meant "this directory context"
139149
if (where === globalTop && !args.length) {
140150
args = ['.']
141151
}
152+
153+
// XXX What does this do?
142154
args = args.filter(a => path.resolve(a) !== npm.prefix)
143155

144-
const arb = new Arborist({
145-
...this.flatOptions,
146-
path: where,
147-
})
156+
// Create arborist object to work with
157+
const arb = new Arborist({ ...npm.flatOptions, path: where })
148158

149159
// TODO:
150160
// - audit
151161
// - funding
152-
// - more logging (archy-ize the tree for silly logging)
153162
// - global installs in Arborist
154163

155-
const opt = {
156-
...this.flatOptions,
157-
add: args,
158-
}
159-
arb[dryRun ? 'buildIdealTree' : 'reify'](opt).then(tree => {
160-
output('TREEEEEEEE', tree)
164+
const arbCallOpts = { ...npm.flatOptions, add: args }
165+
166+
try {
167+
const start = Date.now()
168+
169+
const tree = (dryRun)
170+
? await arb.buildIdealTree(arbCallOpts)
171+
: await arb.reify(arbCallOpts)
172+
173+
const stop = Date.now()
174+
175+
// Print list of installed packages and their version
176+
// Buffer with newline
177+
output('')
178+
arb.diff.children.forEach(diff => {
179+
const node = diff.ideal
180+
if (diff.action === 'ADD' && arb.explicitRequests.has(node.name)) {
181+
output(`+ ${node.name}@${node.package.version}`)
182+
}
183+
})
184+
185+
/**
186+
* TODO:
187+
* - Add audit
188+
* - Add funding
189+
*/
190+
191+
printResults({ start, stop }, tree, arb)
161192
cb()
162-
}, er => cb(er))
193+
} catch (err) {
194+
const msg = errorMessage(err)
195+
msg.summary.forEach(s => log.warn.apply(log, s))
196+
msg.detail.forEach(d => log.verbose.apply(log, d))
197+
cb(err)
198+
}
199+
}
200+
201+
function printResults (timing, tree, arb) {
202+
const { unicode } = npm.flatOptions
203+
204+
// Create archy tree from arborist tree
205+
const reducedTree = reduceArbTree(tree)
206+
const archyTree = archy(reducedTree, '', { unicode })
207+
208+
// Collect information about command action taken
209+
const pkgCount = arb.diff.children.length
210+
const contribCount = pkgCount
211+
const added = `added ${pkgCount}`
212+
213+
const from = `from ${contribCount} contributor${contribCount ? 's' : ''}`
214+
const audited = `audited ${0} package${'s'}`
215+
const time = (timing.stop - timing.start) / 1000
216+
217+
// Print summary of command action taken
218+
output(`${added}, ${from}, and ${audited} in ${time}s`)
219+
220+
// Optionally print the top level dependency tree
221+
log.silly('topLevelDepTree', archyTree)
222+
}
223+
224+
function reduceArbTree (rootNode) {
225+
const initialValue = {
226+
label: rootNode.name,
227+
nodes: []
228+
}
229+
const rootChildrenMap = rootNode.children
230+
for (const child of rootChildrenMap.keys()) {
231+
initialValue.nodes.push(child)
232+
}
233+
234+
return initialValue
163235
}

0 commit comments

Comments
 (0)