Skip to content

Commit 075c2d1

Browse files
authored
Refactor internal stat utils (#764)
* Refactor internal getStats() util Fixes #762 * Proper promise tests for copy() Our hacky tests don't play well with multiple layers of callback/promise switching * Simplify internal checkParentPaths() * Port improvments to sync methods
1 parent ce41762 commit 075c2d1

File tree

3 files changed

+40
-64
lines changed

3 files changed

+40
-64
lines changed

lib/__tests__/promise.test.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ const fs = require('fs')
77
const fse = require('..')
88

99
const methods = [
10-
'copy',
1110
'emptyDir',
1211
'ensureFile',
1312
'ensureDir',

lib/copy/__tests__/copy.test.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,19 @@ describe('fs-extra', () => {
7272
})
7373
})
7474

75+
it('should work with promises', () => {
76+
const fileSrc = path.join(TEST_DIR, 'TEST_fs-extra_src')
77+
const fileDest = path.join(TEST_DIR, 'TEST_fs-extra_copy')
78+
fs.writeFileSync(fileSrc, crypto.randomBytes(SIZE))
79+
const srcMd5 = crypto.createHash('md5').update(fs.readFileSync(fileSrc)).digest('hex')
80+
let destMd5 = ''
81+
82+
return fse.copy(fileSrc, fileDest).then(() => {
83+
destMd5 = crypto.createHash('md5').update(fs.readFileSync(fileDest)).digest('hex')
84+
assert.strictEqual(srcMd5, destMd5)
85+
})
86+
})
87+
7588
it('should return an error if src file does not exist', done => {
7689
const fileSrc = 'we-simply-assume-this-file-does-not-exist.bin'
7790
const fileDest = path.join(TEST_DIR, 'TEST_fs-extra_copy')

lib/util/stat.js

Lines changed: 27 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,29 @@
11
'use strict'
22

3-
const fs = require('graceful-fs')
3+
const fs = require('../fs')
44
const path = require('path')
5+
const util = require('util')
56
const atLeastNode = require('at-least-node')
67

78
const nodeSupportsBigInt = atLeastNode('10.5.0')
9+
const stat = (file) => nodeSupportsBigInt ? fs.stat(file, { bigint: true }) : fs.stat(file)
10+
const statSync = (file) => nodeSupportsBigInt ? fs.statSync(file, { bigint: true }) : fs.statSync(file)
811

9-
function getStats (src, dest, cb) {
10-
if (nodeSupportsBigInt) {
11-
fs.stat(src, { bigint: true }, (err, srcStat) => {
12-
if (err) return cb(err)
13-
fs.stat(dest, { bigint: true }, (err, destStat) => {
14-
if (err) {
15-
if (err.code === 'ENOENT') return cb(null, { srcStat, destStat: null })
16-
return cb(err)
17-
}
18-
return cb(null, { srcStat, destStat })
19-
})
12+
function getStats (src, dest) {
13+
return Promise.all([
14+
stat(src),
15+
stat(dest).catch(err => {
16+
if (err.code === 'ENOENT') return null
17+
throw err
2018
})
21-
} else {
22-
fs.stat(src, (err, srcStat) => {
23-
if (err) return cb(err)
24-
fs.stat(dest, (err, destStat) => {
25-
if (err) {
26-
if (err.code === 'ENOENT') return cb(null, { srcStat, destStat: null })
27-
return cb(err)
28-
}
29-
return cb(null, { srcStat, destStat })
30-
})
31-
})
32-
}
19+
]).then(([srcStat, destStat]) => ({ srcStat, destStat }))
3320
}
3421

3522
function getStatsSync (src, dest) {
36-
let srcStat, destStat
37-
if (nodeSupportsBigInt) {
38-
srcStat = fs.statSync(src, { bigint: true })
39-
} else {
40-
srcStat = fs.statSync(src)
41-
}
23+
let destStat
24+
const srcStat = statSync(src)
4225
try {
43-
if (nodeSupportsBigInt) {
44-
destStat = fs.statSync(dest, { bigint: true })
45-
} else {
46-
destStat = fs.statSync(dest)
47-
}
26+
destStat = statSync(dest)
4827
} catch (err) {
4928
if (err.code === 'ENOENT') return { srcStat, destStat: null }
5029
throw err
@@ -53,7 +32,7 @@ function getStatsSync (src, dest) {
5332
}
5433

5534
function checkPaths (src, dest, funcName, cb) {
56-
getStats(src, dest, (err, stats) => {
35+
util.callbackify(getStats)(src, dest, (err, stats) => {
5736
if (err) return cb(err)
5837
const { srcStat, destStat } = stats
5938
if (destStat && areIdentical(srcStat, destStat)) {
@@ -85,29 +64,18 @@ function checkParentPaths (src, srcStat, dest, funcName, cb) {
8564
const srcParent = path.resolve(path.dirname(src))
8665
const destParent = path.resolve(path.dirname(dest))
8766
if (destParent === srcParent || destParent === path.parse(destParent).root) return cb()
88-
if (nodeSupportsBigInt) {
89-
fs.stat(destParent, { bigint: true }, (err, destStat) => {
90-
if (err) {
91-
if (err.code === 'ENOENT') return cb()
92-
return cb(err)
93-
}
94-
if (areIdentical(srcStat, destStat)) {
95-
return cb(new Error(errMsg(src, dest, funcName)))
96-
}
97-
return checkParentPaths(src, srcStat, destParent, funcName, cb)
98-
})
99-
} else {
100-
fs.stat(destParent, (err, destStat) => {
101-
if (err) {
102-
if (err.code === 'ENOENT') return cb()
103-
return cb(err)
104-
}
105-
if (areIdentical(srcStat, destStat)) {
106-
return cb(new Error(errMsg(src, dest, funcName)))
107-
}
108-
return checkParentPaths(src, srcStat, destParent, funcName, cb)
109-
})
67+
const callback = (err, destStat) => {
68+
if (err) {
69+
if (err.code === 'ENOENT') return cb()
70+
return cb(err)
71+
}
72+
if (areIdentical(srcStat, destStat)) {
73+
return cb(new Error(errMsg(src, dest, funcName)))
74+
}
75+
return checkParentPaths(src, srcStat, destParent, funcName, cb)
11076
}
77+
if (nodeSupportsBigInt) fs.stat(destParent, { bigint: true }, callback)
78+
else fs.stat(destParent, callback)
11179
}
11280

11381
function checkParentPathsSync (src, srcStat, dest, funcName) {
@@ -116,11 +84,7 @@ function checkParentPathsSync (src, srcStat, dest, funcName) {
11684
if (destParent === srcParent || destParent === path.parse(destParent).root) return
11785
let destStat
11886
try {
119-
if (nodeSupportsBigInt) {
120-
destStat = fs.statSync(destParent, { bigint: true })
121-
} else {
122-
destStat = fs.statSync(destParent)
123-
}
87+
destStat = statSync(destParent)
12488
} catch (err) {
12589
if (err.code === 'ENOENT') return
12690
throw err

0 commit comments

Comments
 (0)