Skip to content

Commit e4b7aa1

Browse files
committed
Apply code review suggestions from @RyanZim
1 parent d9f8ef9 commit e4b7aa1

File tree

1 file changed

+35
-47
lines changed

1 file changed

+35
-47
lines changed

lib/copy/copy.js

+35-47
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,14 @@ const { pathExists } = require('../path-exists')
77
const { utimesMillisAsync } = require('../util/utimes')
88
const stat = require('../util/stat')
99

10-
async function copy (src, dest, opts) {
10+
async function copy(src, dest, opts = {}) {
1111
if (typeof opts === 'function') {
1212
opts = { filter: opts }
1313
}
1414

15-
opts = opts || {}
15+
opts = typeof opts === 'function'
16+
? { filter: opts }
17+
: opts
1618

1719
opts.clobber = 'clobber' in opts ? !!opts.clobber : true // default to true for now
1820
opts.overwrite = 'overwrite' in opts ? !!opts.overwrite : opts.clobber // overwrite falls back to clobber
@@ -37,27 +39,24 @@ async function copy (src, dest, opts) {
3739
return checkParentDir(destStat, src, dest, opts)
3840
}
3941

40-
async function checkParentDir (destStat, src, dest, opts) {
42+
async function checkParentDir(destStat, src, dest, opts) {
4143
const destParent = path.dirname(dest)
4244

4345
const dirExists = await pathExists(destParent)
4446

45-
if (dirExists) return getStats(destStat, src, dest, opts)
46-
47-
const parentDirExists = await pathExists(destParent)
48-
if (parentDirExists) return getStats(destStat, src, dest, opts)
49-
50-
await mkdirs(destParent)
47+
if (!dirExists) {
48+
await mkdirs(destParent)
49+
}
5150

5251
return getStats(destStat, src, dest, opts)
5352
}
5453

55-
async function runFilter (src, dest, opts) {
54+
async function runFilter(src, dest, opts) {
5655
if (!opts.filter) return true
5756
return opts.filter(src, dest)
5857
}
5958

60-
async function getStats (destStat, src, dest, opts) {
59+
async function getStats(destStat, src, dest, opts) {
6160
const statFn = opts.dereference ? fs.stat : fs.lstat
6261
const srcStat = await statFn(src)
6362

@@ -75,12 +74,9 @@ async function getStats (destStat, src, dest, opts) {
7574
throw new Error(`Unknown file: ${src}`)
7675
}
7776

78-
function onFile (srcStat, destStat, src, dest, opts) {
77+
async function onFile(srcStat, destStat, src, dest, opts) {
7978
if (!destStat) return copyFile(srcStat, src, dest, opts)
80-
return mayCopyFile(srcStat, src, dest, opts)
81-
}
8279

83-
async function mayCopyFile (srcStat, src, dest, opts) {
8480
if (opts.overwrite) {
8581
await fs.unlink(dest)
8682
return copyFile(srcStat, src, dest, opts)
@@ -90,75 +86,68 @@ async function mayCopyFile (srcStat, src, dest, opts) {
9086
}
9187
}
9288

93-
async function copyFile (srcStat, src, dest, opts) {
89+
async function copyFile(srcStat, src, dest, opts) {
9490
await fs.copyFile(src, dest)
9591
if (opts.preserveTimestamps) {
9692
return handleTimestampsAndMode(srcStat.mode, src, dest)
9793
}
9894
return setDestMode(dest, srcStat.mode)
9995
}
10096

101-
async function handleTimestampsAndMode (srcMode, src, dest) {
97+
async function handleTimestampsAndMode(srcMode, src, dest) {
10298
// Make sure the file is writable before setting the timestamp
10399
// otherwise open fails with EPERM when invoked with 'r+'
104100
// (through utimes call)
105101
if (fileIsNotWritable(srcMode)) {
106102
await makeFileWritable(dest, srcMode)
107-
return setDestTimestampsAndMode(srcMode, src, dest)
108103
}
109104
return setDestTimestampsAndMode(srcMode, src, dest)
110105
}
111106

112-
function fileIsNotWritable (srcMode) {
107+
function fileIsNotWritable(srcMode) {
113108
return (srcMode & 0o200) === 0
114109
}
115110

116-
function makeFileWritable (dest, srcMode) {
111+
function makeFileWritable(dest, srcMode) {
117112
return setDestMode(dest, srcMode | 0o200)
118113
}
119114

120-
async function setDestTimestampsAndMode (srcMode, src, dest) {
121-
await setDestTimestamps(src, dest)
122-
return setDestMode(dest, srcMode)
123-
}
124-
125-
function setDestMode (dest, srcMode) {
126-
return fs.chmod(dest, srcMode)
127-
}
128-
129-
async function setDestTimestamps (src, dest) {
115+
async function setDestTimestampsAndMode(srcMode, src, dest) {
130116
// The initial srcStat.atime cannot be trusted
131117
// because it is modified by the read(2) system call
132-
// (See https://nodejs.org/api/fs.html#fs$stat_time_values)
118+
// (See https://nodejs.org/api/fs.html#fs_stat_time_values)
133119
const updatedSrcStat = await fs.stat(src)
120+
await utimesMillisAsync(dest, updatedSrcStat.atime, updatedSrcStat.mtime)
134121

135-
return utimesMillisAsync(dest, updatedSrcStat.atime, updatedSrcStat.mtime)
122+
return setDestMode(dest, srcMode)
136123
}
137124

138-
function onDir (srcStat, destStat, src, dest, opts) {
139-
if (!destStat) return mkDirAndCopy(srcStat.mode, src, dest, opts)
140-
return copyDir(src, dest, opts)
125+
function setDestMode(dest, srcMode) {
126+
return fs.chmod(dest, srcMode)
141127
}
142128

143-
async function mkDirAndCopy (srcMode, src, dest, opts) {
144-
await fs.mkdir(dest)
129+
async function onDir(srcStat, destStat, src, dest, opts) {
130+
if (!destStat) {
131+
await fs.mkdir(dest)
132+
}
145133
await copyDir(src, dest, opts)
146-
147-
return setDestMode(dest, srcMode)
134+
if (!destStat) {
135+
await setDestMode(dest, srcMode)
136+
}
148137
}
149138

150-
async function copyDir (src, dest, opts) {
139+
async function copyDir(src, dest, opts) {
151140
const items = await fs.readdir(src)
152141
return copyDirItems(items, src, dest, opts)
153142
}
154143

155-
function copyDirItems (items, src, dest, opts) {
144+
function copyDirItems(items, src, dest, opts) {
156145
const item = items.pop()
157146
if (!item) return
158147
return copyDirItem(items, item, src, dest, opts)
159148
}
160149

161-
async function copyDirItem (items, item, src, dest, opts) {
150+
async function copyDirItem(items, item, src, dest, opts) {
162151
const srcItem = path.join(src, item)
163152
const destItem = path.join(dest, item)
164153

@@ -172,7 +161,7 @@ async function copyDirItem (items, item, src, dest, opts) {
172161
return copyDirItems(items, src, dest, opts)
173162
}
174163

175-
async function onLink (destStat, src, dest, opts) {
164+
async function onLink(destStat, src, dest, opts) {
176165
let resolvedSrc = await fs.readlink(src)
177166
if (opts.dereference) {
178167
resolvedSrc = path.resolve(process.cwd(), resolvedSrc)
@@ -185,6 +174,9 @@ async function onLink (destStat, src, dest, opts) {
185174
try {
186175
resolvedDest = await fs.readlink(dest)
187176
} catch (e) {
177+
// dest exists and is a regular file or directory,
178+
// Windows may throw UNKNOWN error. If dest already exists,
179+
// fs throws error anyway, so no need to guard against it here.
188180
if (e.code === 'EINVAL' || e.code === 'UNKNOWN') return fs.symlink(resolvedSrc, dest)
189181
throw e
190182
}
@@ -202,10 +194,6 @@ async function onLink (destStat, src, dest, opts) {
202194
throw new Error(`Cannot overwrite '${resolvedDest}' with '${resolvedSrc}'.`)
203195
}
204196

205-
return copyLink(resolvedSrc, dest)
206-
}
207-
208-
async function copyLink (resolvedSrc, dest) {
209197
await fs.unlink(dest)
210198
return fs.symlink(resolvedSrc, dest)
211199
}

0 commit comments

Comments
 (0)