Skip to content

Commit a8e229f

Browse files
committed
Utilize fs.copyFileSync if available.
* Currently would only be utilized on windows * available in node 8.5.x * prefer Copy-On-Write if available * good benchmarks yarnpkg/yarn#3290 Although node-copy-file-sync module exists, it uses more modern JS features. Which this library cannot yet support (without major version bump)
1 parent be01247 commit a8e229f

File tree

2 files changed

+64
-1
lines changed

2 files changed

+64
-1
lines changed

index.js

+12-1
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,13 @@ function symlink(_srcPath, _destPath) {
123123
// Fix for https://github.com/broccolijs/broccoli-merge-trees/issues/42
124124
var WINDOWS_PREFIX = "\\\\?\\";
125125

126+
function copyFileSync(srcPath, destPath, stat) {
127+
options.fs.writeFileSync(destPath, options.fs.readFileSync(srcPath), {
128+
flag: 'wx',
129+
mode: stat.mode
130+
});
131+
}
132+
126133
function symlinkWindows(srcPath, destPath) {
127134
var stat = options.fs.lstatSync(srcPath);
128135
var isDir = stat.isDirectory();
@@ -143,7 +150,11 @@ function symlinkWindows(srcPath, destPath) {
143150
if (isDir) {
144151
options.fs.symlinkSync(srcPath, destPath, 'junction');
145152
} else {
146-
options.fs.writeFileSync(destPath, options.fs.readFileSync(srcPath), { flag: 'wx', mode: stat.mode });
153+
if (options.fs.copyFileSync) {
154+
options.fs.copyFileSync(srcPath, destPath);
155+
} else {
156+
copyFileSync(srcPath, destPath, stat);
157+
}
147158
options.fs.utimesSync(destPath, stat.atime, stat.mtime);
148159
}
149160
}

tests/index.js

+52
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,58 @@ describe('symlink-or-copy', function() {
122122
assert.equal(utimesSyncCount, 1);
123123
});
124124

125+
it('windows falls back to copyFileSync if available for file', function() {
126+
var count = 0
127+
var lstatSyncCount = 0
128+
var isDirectoryCount = 0
129+
var readFileSyncCount = 0
130+
var writeFileSyncCount = 0
131+
var utimesSyncCount = 0
132+
var copyFileSync = 0
133+
symLinkOrCopy.setOptions({
134+
isWindows: true,
135+
canSymLink: false,
136+
fs: {
137+
lstatSync: function() {
138+
lstatSyncCount++;
139+
return {
140+
isSymbolicLink: function() {
141+
return true;
142+
},
143+
isDirectory: function() {
144+
isDirectoryCount++;
145+
return false;
146+
}
147+
};
148+
},
149+
readFileSync: function() {
150+
readFileSyncCount++;
151+
return 'foo';
152+
},
153+
writeFileSync: function() {
154+
writeFileSyncCount++;
155+
return 'foo';
156+
},
157+
copyFileSync: function() {
158+
copyFileSync++;
159+
return 'foo';
160+
},
161+
realpathSync: function() {count++;},
162+
symlinkSync: function() {count++;},
163+
utimesSync: function() {utimesSyncCount++;}
164+
}
165+
});
166+
167+
symLinkOrCopy.sync('foo', 'bar');
168+
assert.equal(count, 1);
169+
assert.equal(lstatSyncCount, 2);
170+
assert.equal(isDirectoryCount, 2);
171+
assert.equal(writeFileSyncCount, 0);
172+
assert.equal(copyFileSync, 1);
173+
assert.equal(readFileSyncCount, 0);
174+
assert.equal(utimesSyncCount, 1);
175+
});
176+
125177
it('windows symlinks when has permission', function() {
126178
var count = 0;
127179
symLinkOrCopy.setOptions({

0 commit comments

Comments
 (0)