Skip to content

Commit 78447d7

Browse files
authored
fix: prefer fs/promises over promisify (#7399)
1 parent 03958c3 commit 78447d7

File tree

19 files changed

+105
-131
lines changed

19 files changed

+105
-131
lines changed

Diff for: lib/commands/doctor.js

+1-6
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,13 @@
11
const cacache = require('cacache')
2-
const fs = require('fs')
2+
const { access, lstat, readdir, constants: { R_OK, W_OK, X_OK } } = require('fs/promises')
33
const fetch = require('make-fetch-happen')
44
const which = require('which')
55
const pacote = require('pacote')
66
const { resolve } = require('path')
77
const semver = require('semver')
8-
const { promisify } = require('util')
98
const { log, output } = require('proc-log')
109
const ping = require('../utils/ping.js')
1110
const { defaults } = require('@npmcli/config/lib/definitions')
12-
const lstat = promisify(fs.lstat)
13-
const readdir = promisify(fs.readdir)
14-
const access = promisify(fs.access)
15-
const { R_OK, W_OK, X_OK } = fs.constants
1611

1712
const maskLabel = mask => {
1813
const label = []

Diff for: lib/commands/edit.js

+8-18
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// open the package folder in the $EDITOR
33

44
const { resolve } = require('path')
5-
const fs = require('graceful-fs')
5+
const { lstat } = require('fs/promises')
66
const cp = require('child_process')
77
const completion = require('../utils/completion/installed-shallow.js')
88
const BaseCommand = require('../base-command.js')
@@ -50,25 +50,15 @@ class Edit extends BaseCommand {
5050
const path = splitPackageNames(args[0])
5151
const dir = resolve(this.npm.dir, path)
5252

53-
// graceful-fs does not promisify
53+
await lstat(dir)
5454
await new Promise((res, rej) => {
55-
fs.lstat(dir, (err) => {
56-
if (err) {
57-
return rej(err)
55+
const [bin, ...spawnArgs] = this.npm.config.get('editor').split(/\s+/)
56+
const editor = cp.spawn(bin, [...spawnArgs, dir], { stdio: 'inherit' })
57+
editor.on('exit', async (code) => {
58+
if (code) {
59+
return rej(new Error(`editor process exited with code: ${code}`))
5860
}
59-
const [bin, ...spawnArgs] = this.npm.config.get('editor').split(/\s+/)
60-
const editor = cp.spawn(bin, [...spawnArgs, dir], { stdio: 'inherit' })
61-
editor.on('exit', async (code) => {
62-
if (code) {
63-
return rej(new Error(`editor process exited with code: ${code}`))
64-
}
65-
try {
66-
await this.npm.exec('rebuild', [dir])
67-
} catch (execErr) {
68-
rej(execErr)
69-
}
70-
res()
71-
})
61+
await this.npm.exec('rebuild', [dir]).then(res).catch(rej)
7262
})
7363
})
7464
}

Diff for: lib/commands/init.js

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
const fs = require('fs')
1+
const { statSync } = require('fs')
22
const { relative, resolve } = require('path')
33
const { mkdir } = require('fs/promises')
44
const initJson = require('init-package-json')
@@ -8,11 +8,10 @@ const mapWorkspaces = require('@npmcli/map-workspaces')
88
const PackageJson = require('@npmcli/package-json')
99
const { log, output } = require('proc-log')
1010
const updateWorkspaces = require('../workspaces/update-workspaces.js')
11+
const BaseCommand = require('../base-command.js')
1112

1213
const posixPath = p => p.split('\\').join('/')
1314

14-
const BaseCommand = require('../base-command.js')
15-
1615
class Init extends BaseCommand {
1716
static description = 'Create a package.json file'
1817
static params = [
@@ -197,7 +196,7 @@ class Init extends BaseCommand {
197196
// mapWorkspaces, so we're just going to avoid touching the
198197
// top-level package.json
199198
try {
200-
fs.statSync(resolve(workspacePath, 'package.json'))
199+
statSync(resolve(workspacePath, 'package.json'))
201200
} catch (err) {
202201
return
203202
}

Diff for: lib/commands/link.js

+2-6
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,11 @@
1-
const fs = require('fs')
2-
const util = require('util')
3-
const readdir = util.promisify(fs.readdir)
1+
const { readdir } = require('fs/promises')
42
const { resolve } = require('path')
5-
63
const npa = require('npm-package-arg')
74
const pkgJson = require('@npmcli/package-json')
85
const semver = require('semver')
9-
106
const reifyFinish = require('../utils/reify-finish.js')
11-
127
const ArboristWorkspaceCmd = require('../arborist-cmd.js')
8+
139
class Link extends ArboristWorkspaceCmd {
1410
static description = 'Symlink a package folder'
1511
static name = 'link'

Diff for: lib/commands/shrinkwrap.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
const { resolve, basename } = require('path')
2-
const { unlink } = require('fs').promises
2+
const { unlink } = require('fs/promises')
33
const { log } = require('proc-log')
44
const BaseCommand = require('../base-command.js')
5+
56
class Shrinkwrap extends BaseCommand {
67
static description = 'Lock down dependency versions for publication'
78
static name = 'shrinkwrap'

Diff for: lib/commands/view.js

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
11
const columns = require('cli-columns')
2-
const fs = require('fs')
2+
const { readFile } = require('fs/promises')
33
const jsonParse = require('json-parse-even-better-errors')
44
const { log, output } = require('proc-log')
55
const npa = require('npm-package-arg')
66
const { resolve } = require('path')
77
const formatBytes = require('../utils/format-bytes.js')
88
const relativeDate = require('tiny-relative-date')
99
const semver = require('semver')
10-
const { inspect, promisify } = require('util')
10+
const { inspect } = require('util')
1111
const { packument } = require('pacote')
1212

13-
const readFile = promisify(fs.readFile)
1413
const readJson = async file => jsonParse(await readFile(file, 'utf8'))
1514

1615
const Queryable = require('../utils/queryable.js')

Diff for: lib/utils/reify-finish.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
const reifyOutput = require('./reify-output.js')
22
const ini = require('ini')
3-
const { writeFile } = require('fs').promises
3+
const { writeFile } = require('fs/promises')
44
const { resolve } = require('path')
55

66
const reifyFinish = async (npm, arb) => {

Diff for: tap-snapshots/test/lib/commands/doctor.js.test.cjs

+5-5
Original file line numberDiff line numberDiff line change
@@ -731,11 +731,11 @@ Object {
731731
"warn": Array [
732732
String(
733733
doctor getGitPath Error: test error
734-
doctor at which ({CWD}/{TESTDIR}/doctor.js:313:15)
735-
doctor at Doctor.getGitPath ({CWD}/lib/commands/doctor.js:286:18)
736-
doctor at Doctor.exec ({CWD}/lib/commands/doctor.js:125:33)
737-
doctor at processTicksAndRejections (node:internal/process/task_queues:95:5)
738-
doctor at MockNpm.exec ({CWD}/test/fixtures/mock-npm.js:80:26)
734+
doctor at which {STACK}
735+
doctor at Doctor.getGitPath {STACK}
736+
doctor at Doctor.exec {STACK}
737+
doctor at processTicksAndRejections {STACK}
738+
doctor at MockNpm.exec {STACK}
739739
),
740740
],
741741
}

Diff for: test/lib/commands/doctor.js

+14-9
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
const t = require('tap')
2-
const fs = require('fs')
2+
const fs = require('fs/promises')
33
const path = require('path')
44

55
const { load: loadMockNpm } = require('../../fixtures/mock-npm')
@@ -11,6 +11,7 @@ const cleanCacheSha = (str) =>
1111
str.replace(/content-v2\/sha512\/[^"]+/g, 'content-v2/sha512/{sha}')
1212

1313
t.cleanSnapshot = p => cleanCacheSha(cleanDate(cleanCwd(p)))
14+
.replace(/\s\((\{CWD\}|node:).*\d+:\d+\)$/gm, ' {STACK}')
1415

1516
const npmManifest = (version) => {
1617
return {
@@ -389,15 +390,15 @@ t.test('incorrect owner', async t => {
389390
const { joinedOutput, logs, npm } = await loadMockNpm(t, {
390391
mocks: {
391392
...mocks,
392-
fs: {
393+
'fs/promises': {
393394
...fs,
394-
lstat: (p, cb) => {
395-
const stat = fs.lstatSync(p)
395+
lstat: async (p) => {
396+
const stat = await fs.lstat(p)
396397
if (p.endsWith('_cacache')) {
397398
stat.uid += 1
398399
stat.gid += 1
399400
}
400-
return cb(null, stat)
401+
return stat
401402
},
402403
},
403404
},
@@ -418,9 +419,9 @@ t.test('incorrect permissions', async t => {
418419
const { joinedOutput, logs, npm } = await loadMockNpm(t, {
419420
mocks: {
420421
...mocks,
421-
fs: {
422+
'fs/promises': {
422423
...fs,
423-
access: () => {
424+
access: async () => {
424425
throw new Error('Test Error')
425426
},
426427
},
@@ -442,9 +443,13 @@ t.test('error reading directory', async t => {
442443
const { joinedOutput, logs, npm } = await loadMockNpm(t, {
443444
mocks: {
444445
...mocks,
445-
fs: {
446+
'fs/promises': {
446447
...fs,
447-
readdir: () => {
448+
readdir: async (s, ...args) => {
449+
if (s.endsWith('_logs')) {
450+
return fs.readdir(s, ...args)
451+
}
452+
// if (s.endsWith)
448453
throw new Error('Test Error')
449454
},
450455
},

Diff for: workspaces/arborist/lib/arborist/isolated-reifier.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
const _makeIdealGraph = Symbol('makeIdealGraph')
22
const _createIsolatedTree = Symbol.for('createIsolatedTree')
33
const _createBundledTree = Symbol('createBundledTree')
4-
const fs = require('fs')
4+
const { mkdirSync } = require('fs')
55
const pacote = require('pacote')
66
const { join } = require('path')
77
const { depth } = require('treeverse')
@@ -108,7 +108,7 @@ module.exports = cls => class IsolatedReifier extends cls {
108108
'.store',
109109
`${node.name}@${node.version}`
110110
)
111-
fs.mkdirSync(dir, { recursive: true })
111+
mkdirSync(dir, { recursive: true })
112112
// TODO this approach feels wrong
113113
// and shouldn't be necessary for shrinkwraps
114114
await pacote.extract(node.resolved, dir, {

Diff for: workspaces/arborist/scripts/benchmark.js

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
process.env.ARBORIST_DEBUG = '0'
2+
23
const { Suite } = require('benchmark')
34
const { relative, resolve } = require('path')
45
const { mkdir, rm } = require('fs/promises')
56
const { execSync } = require('child_process')
7+
const { linkSync, writeFileSync, readdirSync } = require('fs')
8+
const registryServer = require('../test/fixtures/server.js')
9+
610
const shaCmd = 'git show --no-patch --pretty=%H HEAD'
711
const dirty = !!String(execSync('git status -s -uno')).trim()
812
const currentSha = String(execSync(shaCmd)).trim() + (dirty ? '-dirty' : '')
913
const lastBenchmark = resolve(__dirname, 'benchmark/saved/last-benchmark.json')
10-
const { linkSync, writeFileSync, readdirSync } = require('fs')
11-
const registryServer = require('../test/fixtures/server.js')
1214

1315
const red = m => `\x1B[31m${m}\x1B[39m`
1416
const green = m => `\x1B[32m${m}\x1B[39m`

Diff for: workspaces/arborist/scripts/benchmark/load-actual.js

+2-4
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
const Arborist = require('../..')
22
const { resolve, basename } = require('path')
33
const { writeFileSync } = require('fs')
4-
const {
5-
mkdir,
6-
rm,
7-
} = require('fs/promises')
4+
const { mkdir, rm } = require('fs/promises')
5+
86
const dir = resolve(__dirname, basename(__filename, '.js'))
97

108
const suite = async (suite, { registry, cache }) => {

Diff for: workspaces/arborist/scripts/benchmark/reify.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
const Arborist = require('../..')
22
const { resolve, basename } = require('path')
3-
const { writeFileSync } = require('fs')
3+
const { writeFileSync, rmSync } = require('fs')
44
const { mkdir } = require('fs/promises')
5-
const { rmSync } = require('fs')
65
const dir = resolve(__dirname, basename(__filename, '.js'))
76

87
// these are not arbitrary, the empty/full and no-* bits matter

Diff for: workspaces/arborist/test/arborist/pruner.js

+6-7
Original file line numberDiff line numberDiff line change
@@ -80,17 +80,16 @@ t.test('prune with lockfile omit dev', async t => {
8080
})
8181

8282
t.test('prune omit dev with bins', async t => {
83-
const fs = require('fs')
84-
const { promisify } = require('util')
85-
const readdir = promisify(fs.readdir)
83+
const { readdir } = require('fs/promises')
84+
const { statSync, lstatSync } = require('fs')
8685
const path = fixture(t, 'prune-dev-bins')
8786

8887
// should have bin files
8988
const reifiedBin = resolve(path, 'node_modules/.bin/yes')
9089
if (process.platform === 'win32') {
91-
t.ok(fs.statSync(reifiedBin + '.cmd').isFile(), 'should have shim')
90+
t.ok(statSync(reifiedBin + '.cmd').isFile(), 'should have shim')
9291
} else {
93-
t.ok(fs.lstatSync(reifiedBin).isSymbolicLink(), 'should have symlink')
92+
t.ok(lstatSync(reifiedBin).isSymbolicLink(), 'should have symlink')
9493
}
9594

9695
// PRUNE things
@@ -107,9 +106,9 @@ t.test('prune omit dev with bins', async t => {
107106
// should also remove ./bin/* files
108107
const bin = resolve(path, 'node_modules/.bin/yes')
109108
if (process.platform === 'win32') {
110-
t.throws(() => fs.statSync(bin + '.cmd').isFile(), /ENOENT/, 'should not have shim')
109+
t.throws(() => statSync(bin + '.cmd').isFile(), /ENOENT/, 'should not have shim')
111110
} else {
112-
t.throws(() => fs.lstatSync(bin).isSymbolicLink(), /ENOENT/, 'should not have symlink')
111+
t.throws(() => lstatSync(bin).isSymbolicLink(), /ENOENT/, 'should not have symlink')
113112
}
114113
})
115114

Diff for: workspaces/config/lib/definitions/definitions.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ const { join } = require('node:path')
77
const isWindows = process.platform === 'win32'
88

99
// used by cafile flattening to flatOptions.ca
10-
const fs = require('fs')
10+
const { readFileSync } = require('fs')
1111
const maybeReadFile = file => {
1212
try {
13-
return fs.readFileSync(file, 'utf8')
13+
return readFileSync(file, 'utf8')
1414
} catch (er) {
1515
if (er.code !== 'ENOENT') {
1616
throw er

Diff for: workspaces/libnpmpack/lib/index.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,8 @@ const pacote = require('pacote')
44
const npa = require('npm-package-arg')
55
const runScript = require('@npmcli/run-script')
66
const path = require('path')
7-
const util = require('util')
87
const Arborist = require('@npmcli/arborist')
9-
const writeFile = util.promisify(require('fs').writeFile)
8+
const { writeFile } = require('fs/promises')
109

1110
module.exports = pack
1211
async function pack (spec = 'file:.', opts = {}) {

Diff for: workspaces/libnpmversion/lib/read-json.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
// can't use read-package-json-fast, because we want to ensure
22
// that we make as few changes as possible, even for safety issues.
3-
const { promisify } = require('util')
4-
const readFile = promisify(require('fs').readFile)
3+
const { readFile } = require('fs/promises')
54
const parse = require('json-parse-even-better-errors')
65

76
module.exports = async path => parse(await readFile(path))

Diff for: workspaces/libnpmversion/lib/write-json.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
// write the json back, preserving the line breaks and indent
2-
const { promisify } = require('util')
3-
const writeFile = promisify(require('fs').writeFile)
2+
const { writeFile } = require('fs/promises')
43
const kIndent = Symbol.for('indent')
54
const kNewline = Symbol.for('newline')
65

0 commit comments

Comments
 (0)