16
16
17
17
module . exports = install
18
18
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' )
20
43
21
44
install . usage = usage (
22
45
'install' ,
@@ -34,8 +57,6 @@ install.usage = usage(
34
57
'[--save-prod|--save-dev|--save-optional] [--save-exact] [--no-save]'
35
58
)
36
59
37
- const npa = require ( 'npm-package-arg' )
38
-
39
60
install . completion = function ( opts , cb ) {
40
61
validate ( 'OF' , arguments )
41
62
// install can complete to a folder with a package.json, or any package.
@@ -95,69 +116,120 @@ install.completion = function (opts, cb) {
95
116
cb ( )
96
117
}
97
118
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 ) {
120
120
if ( ! cb ) {
121
121
cb = args
122
122
args = where
123
123
where = null
124
124
}
125
+
125
126
// the /path/to/node_modules/..
126
127
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 )
129
139
? globalTop
130
140
: npm . prefix
131
- }
132
- const { dryRun} = npm . flatOptions
141
+ : where
133
142
134
143
// TODO: Add warnings for other deprecated flags
135
144
if ( npm . config . get ( 'dev' ) ) {
136
145
log . warn ( 'install' , 'Usage of the `--dev` option is deprecated. Use `--include=dev` instead.' )
137
146
}
138
147
148
+ // If global install, and NO args passed; user meant "this directory context"
139
149
if ( where === globalTop && ! args . length ) {
140
150
args = [ '.' ]
141
151
}
152
+
153
+ // XXX What does this do?
142
154
args = args . filter ( a => path . resolve ( a ) !== npm . prefix )
143
155
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 } )
148
158
149
159
// TODO:
150
160
// - audit
151
161
// - funding
152
- // - more logging (archy-ize the tree for silly logging)
153
162
// - global installs in Arborist
154
163
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 )
161
192
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
163
235
}
0 commit comments