Skip to content

Commit b37a22f

Browse files
committed
wip: Add workspaces functionality to reify commands
Not 100% confident in this approach, but seems like it works, and keeps the duplication within a reasonable level. One big downside is that now we have two base classes.
1 parent 5514837 commit b37a22f

19 files changed

+80
-18
lines changed

lib/audit.js

+4-2
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ const Arborist = require('@npmcli/arborist')
22
const auditReport = require('npm-audit-report')
33
const reifyFinish = require('./utils/reify-finish.js')
44
const auditError = require('./utils/audit-error.js')
5-
const BaseCommand = require('./base-command.js')
5+
const BaseReifyCommand = require('./base-reify-command.js')
66

7-
class Audit extends BaseCommand {
7+
class Audit extends BaseReifyCommand {
88
/* istanbul ignore next - see test/lib/load-all-commands.js */
99
static get description () {
1010
return 'Run a security audit'
@@ -57,7 +57,9 @@ class Audit extends BaseCommand {
5757
audit: true,
5858
path: this.npm.prefix,
5959
reporter,
60+
workspaces: this.workspaces,
6061
}
62+
6163
const arb = new Arborist(opts)
6264
const fix = args[0] === 'fix'
6365
await arb.audit({ fix })

lib/base-command.js

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ class BaseCommand {
66
constructor (npm) {
77
this.wrapWidth = 80
88
this.npm = npm
9+
this.workspaces = null
910
}
1011

1112
get name () {

lib/base-reify-command.js

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// This is the base for all commands whose execWorkspaces just gets
2+
// a list of workspace names and passes it on to new Arborist() to
3+
// be able to run a filtered Arborist.reify() at some point.
4+
5+
const BaseCommand = require('./base-command.js')
6+
const getWorkspaces = require('./workspaces/get-workspaces.js')
7+
class BaseReifyCommand extends BaseCommand {
8+
execWorkspaces (args, filters, cb) {
9+
getWorkspaces(filters, { path: this.npm.localPrefix })
10+
.then(workspaces => {
11+
this.workspaces = workspaces.map(([name]) => name)
12+
this.exec(args, cb)
13+
})
14+
}
15+
}
16+
17+
module.exports = BaseReifyCommand

lib/ci.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ const removeNodeModules = async where => {
1717
await Promise.all(entries.map(f => rimraf(`${path}/${f}`, rimrafOpts)))
1818
process.emit('timeEnd', 'npm-ci:rm')
1919
}
20-
const BaseCommand = require('./base-command.js')
20+
const BaseReifyCommand = require('./base-reify-command.js')
2121

22-
class CI extends BaseCommand {
22+
class CI extends BaseReifyCommand {
2323
/* istanbul ignore next - see test/lib/load-all-commands.js */
2424
static get description () {
2525
return 'Install a project with a clean slate'
@@ -47,6 +47,7 @@ class CI extends BaseCommand {
4747
path: where,
4848
log: this.npm.log,
4949
save: false, // npm ci should never modify the lockfile or package.json
50+
workspaces: this.workspaces,
5051
}
5152

5253
const arb = new Arborist(opts)

lib/dedupe.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
const Arborist = require('@npmcli/arborist')
33
const reifyFinish = require('./utils/reify-finish.js')
44

5-
const BaseCommand = require('./base-command.js')
5+
const BaseReifyCommand = require('./base-reify-command.js')
66

7-
class Dedupe extends BaseCommand {
7+
class Dedupe extends BaseReifyCommand {
88
/* istanbul ignore next - see test/lib/load-all-commands.js */
99
static get description () {
1010
return 'Reduce duplication in the package tree'
@@ -33,6 +33,7 @@ class Dedupe extends BaseCommand {
3333
log: this.npm.log,
3434
path: where,
3535
dryRun,
36+
workspaces: this.workspaces,
3637
}
3738
const arb = new Arborist(opts)
3839
await arb.dedupe(opts)

lib/install.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ const { resolve, join } = require('path')
99
const Arborist = require('@npmcli/arborist')
1010
const runScript = require('@npmcli/run-script')
1111

12-
const BaseCommand = require('./base-command.js')
13-
class Install extends BaseCommand {
12+
const BaseReifyCommand = require('./base-reify-command.js')
13+
class Install extends BaseReifyCommand {
1414
/* istanbul ignore next - see test/lib/load-all-commands.js */
1515
static get description () {
1616
return 'Install a package'
@@ -132,6 +132,7 @@ class Install extends BaseCommand {
132132
auditLevel: null,
133133
path: where,
134134
add: args,
135+
workspaces: this.workspaces,
135136
}
136137
const arb = new Arborist(opts)
137138
await arb.reify(opts)

lib/prune.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
const Arborist = require('@npmcli/arborist')
33
const reifyFinish = require('./utils/reify-finish.js')
44

5-
const BaseCommand = require('./base-command.js')
6-
class Prune extends BaseCommand {
5+
const BaseReifyCommand = require('./base-reify-command.js')
6+
class Prune extends BaseReifyCommand {
77
/* istanbul ignore next - see test/lib/load-all-commands.js */
88
static get description () {
99
return 'Remove extraneous packages'
@@ -34,6 +34,7 @@ class Prune extends BaseCommand {
3434
...this.npm.flatOptions,
3535
path: where,
3636
log: this.npm.log,
37+
workspaces: this.workspaces,
3738
}
3839
const arb = new Arborist(opts)
3940
await arb.prune(opts)

lib/rebuild.js

+4
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ const npa = require('npm-package-arg')
44
const semver = require('semver')
55
const completion = require('./utils/completion/installed-deep.js')
66

7+
// TODO: make Arborist.rebuild() understand the workspaces option
8+
// and then extend BaseReifyCommand instead
79
const BaseCommand = require('./base-command.js')
810
class Rebuild extends BaseCommand {
911
/* istanbul ignore next - see test/lib/load-all-commands.js */
@@ -36,6 +38,8 @@ class Rebuild extends BaseCommand {
3638
const arb = new Arborist({
3739
...this.npm.flatOptions,
3840
path: where,
41+
// TODO when extending BaseReifyCommand
42+
// workspaces: this.workspaces,
3943
})
4044

4145
if (args.length) {

lib/uninstall.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ const rpj = require('read-package-json-fast')
55
const reifyFinish = require('./utils/reify-finish.js')
66
const completion = require('./utils/completion/installed-shallow.js')
77

8-
const BaseCommand = require('./base-command.js')
9-
class Uninstall extends BaseCommand {
8+
const BaseReifyCommand = require('./base-reify-command.js')
9+
class Uninstall extends BaseReifyCommand {
1010
static get description () {
1111
return 'Remove a package'
1212
}
@@ -66,7 +66,7 @@ class Uninstall extends BaseCommand {
6666
path,
6767
log: this.npm.log,
6868
rm: args,
69-
69+
workspaces: this.workspaces,
7070
}
7171
const arb = new Arborist(opts)
7272
await arb.reify(opts)

lib/update.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ const log = require('npmlog')
66
const reifyFinish = require('./utils/reify-finish.js')
77
const completion = require('./utils/completion/installed-deep.js')
88

9-
const BaseCommand = require('./base-command.js')
10-
class Update extends BaseCommand {
9+
const BaseReifyCommand = require('./base-reify-command.js')
10+
class Update extends BaseReifyCommand {
1111
/* istanbul ignore next - see test/lib/load-all-commands.js */
1212
static get description () {
1313
return 'Update packages'
@@ -53,6 +53,7 @@ class Update extends BaseCommand {
5353
...this.npm.flatOptions,
5454
log: this.npm.log,
5555
path: where,
56+
workspaces: this.workspaces,
5657
})
5758

5859
await arb.reify({ update })

test/lib/audit.js

+2
Original file line numberDiff line numberDiff line change
@@ -191,3 +191,5 @@ t.test('completion', t => {
191191

192192
t.end()
193193
})
194+
195+
t.test('workspaces')

test/lib/base-reify-command.js

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
const t = require('tap')
2+
const BaseReifyCommand = require('../../lib/base-reify-command.js')
3+
// Just a dummy thing here so eslint will stop yelling, but it'll still
4+
// log a todo.
5+
t.todo('BaseReifyCommand basic tests', { todo: true }, async t => {
6+
console.log(BaseReifyCommand)
7+
})

test/lib/ci.js

+2
Original file line numberDiff line numberDiff line change
@@ -242,3 +242,5 @@ t.test('should remove existing node_modules before installing', (t) => {
242242
throw er
243243
})
244244
})
245+
246+
t.test('workspaces')

test/lib/dedupe.js

+2
Original file line numberDiff line numberDiff line change
@@ -62,3 +62,5 @@ t.test('should remove dupes using Arborist - no arguments', (t) => {
6262
t.end()
6363
})
6464
})
65+
66+
t.test('workspaces')

test/lib/install.js

+2
Original file line numberDiff line numberDiff line change
@@ -218,3 +218,5 @@ t.test('completion', async t => {
218218
t.notOk(res)
219219
t.end()
220220
})
221+
222+
t.test('workspaces')

test/lib/prune.js

+2
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,5 @@ t.test('should prune using Arborist', (t) => {
2626
t.end()
2727
})
2828
})
29+
30+
t.test('workspaces')

test/lib/rebuild.js

+2
Original file line numberDiff line numberDiff line change
@@ -256,3 +256,5 @@ t.test('global prefix', t => {
256256
t.end()
257257
})
258258
})
259+
260+
t.test('workspaces')

test/lib/uninstall.js

+2
Original file line numberDiff line numberDiff line change
@@ -249,3 +249,5 @@ t.test('unknown error reading from localPrefix package.json', t => {
249249
t.end()
250250
})
251251
})
252+
253+
t.test('workspaces')

test/lib/update.js

+15-3
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,12 @@ t.test('no args', t => {
3737
constructor (args) {
3838
t.same(
3939
args,
40-
{ ...npm.flatOptions, path: npm.prefix, log: noop },
40+
{
41+
...npm.flatOptions,
42+
path: npm.prefix,
43+
log: noop,
44+
workspaces: null,
45+
},
4146
'should call arborist contructor with expected args'
4247
)
4348
}
@@ -71,7 +76,12 @@ t.test('with args', t => {
7176
constructor (args) {
7277
t.same(
7378
args,
74-
{ ...npm.flatOptions, path: npm.prefix, log: noop },
79+
{
80+
...npm.flatOptions,
81+
path: npm.prefix,
82+
log: noop,
83+
workspaces: null,
84+
},
7585
'should call arborist contructor with expected args'
7686
)
7787
}
@@ -139,7 +149,7 @@ t.test('update --global', t => {
139149
const { path, ...opts } = args
140150
t.same(
141151
opts,
142-
{ ...npm.flatOptions, log: noop },
152+
{ ...npm.flatOptions, log: noop, workspaces: undefined },
143153
'should call arborist contructor with expected options'
144154
)
145155

@@ -164,3 +174,5 @@ t.test('update --global', t => {
164174
throw err
165175
})
166176
})
177+
178+
t.test('workspaces')

0 commit comments

Comments
 (0)