@@ -7,12 +7,14 @@ const { pathExists } = require('../path-exists')
7
7
const { utimesMillisAsync } = require ( '../util/utimes' )
8
8
const stat = require ( '../util/stat' )
9
9
10
- async function copy ( src , dest , opts ) {
10
+ async function copy ( src , dest , opts = { } ) {
11
11
if ( typeof opts === 'function' ) {
12
12
opts = { filter : opts }
13
13
}
14
14
15
- opts = opts || { }
15
+ opts = typeof opts === 'function'
16
+ ? { filter : opts }
17
+ : opts
16
18
17
19
opts . clobber = 'clobber' in opts ? ! ! opts . clobber : true // default to true for now
18
20
opts . overwrite = 'overwrite' in opts ? ! ! opts . overwrite : opts . clobber // overwrite falls back to clobber
@@ -42,12 +44,9 @@ async function checkParentDir (destStat, src, dest, opts) {
42
44
43
45
const dirExists = await pathExists ( destParent )
44
46
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
+ }
51
50
52
51
return getStats ( destStat , src , dest , opts )
53
52
}
@@ -75,12 +74,9 @@ async function getStats (destStat, src, dest, opts) {
75
74
throw new Error ( `Unknown file: ${ src } ` )
76
75
}
77
76
78
- function onFile ( srcStat , destStat , src , dest , opts ) {
77
+ async function onFile ( srcStat , destStat , src , dest , opts ) {
79
78
if ( ! destStat ) return copyFile ( srcStat , src , dest , opts )
80
- return mayCopyFile ( srcStat , src , dest , opts )
81
- }
82
79
83
- async function mayCopyFile ( srcStat , src , dest , opts ) {
84
80
if ( opts . overwrite ) {
85
81
await fs . unlink ( dest )
86
82
return copyFile ( srcStat , src , dest , opts )
@@ -104,7 +100,6 @@ async function handleTimestampsAndMode (srcMode, src, dest) {
104
100
// (through utimes call)
105
101
if ( fileIsNotWritable ( srcMode ) ) {
106
102
await makeFileWritable ( dest , srcMode )
107
- return setDestTimestampsAndMode ( srcMode , src , dest )
108
103
}
109
104
return setDestTimestampsAndMode ( srcMode , src , dest )
110
105
}
@@ -118,33 +113,27 @@ function makeFileWritable (dest, srcMode) {
118
113
}
119
114
120
115
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 ) {
130
116
// The initial srcStat.atime cannot be trusted
131
117
// 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 )
133
119
const updatedSrcStat = await fs . stat ( src )
120
+ await utimesMillisAsync ( dest , updatedSrcStat . atime , updatedSrcStat . mtime )
134
121
135
- return utimesMillisAsync ( dest , updatedSrcStat . atime , updatedSrcStat . mtime )
122
+ return setDestMode ( dest , srcMode )
136
123
}
137
124
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 )
141
127
}
142
128
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
+ }
145
133
await copyDir ( src , dest , opts )
146
-
147
- return setDestMode ( dest , srcMode )
134
+ if ( ! destStat ) {
135
+ await setDestMode ( dest , srcStat . mode )
136
+ }
148
137
}
149
138
150
139
async function copyDir ( src , dest , opts ) {
@@ -185,6 +174,9 @@ async function onLink (destStat, src, dest, opts) {
185
174
try {
186
175
resolvedDest = await fs . readlink ( dest )
187
176
} 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.
188
180
if ( e . code === 'EINVAL' || e . code === 'UNKNOWN' ) return fs . symlink ( resolvedSrc , dest )
189
181
throw e
190
182
}
@@ -202,10 +194,6 @@ async function onLink (destStat, src, dest, opts) {
202
194
throw new Error ( `Cannot overwrite '${ resolvedDest } ' with '${ resolvedSrc } '.` )
203
195
}
204
196
205
- return copyLink ( resolvedSrc , dest )
206
- }
207
-
208
- async function copyLink ( resolvedSrc , dest ) {
209
197
await fs . unlink ( dest )
210
198
return fs . symlink ( resolvedSrc , dest )
211
199
}
0 commit comments