Skip to content

Commit 3fe6ab4

Browse files
authoredMay 8, 2022
Add cwd option (#46)
1 parent 5dbf6dc commit 3fe6ab4

File tree

5 files changed

+66
-8
lines changed

5 files changed

+66
-8
lines changed
 

‎index.d.ts

+9
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,15 @@ declare namespace cpFile {
1515
@default 0o777
1616
*/
1717
readonly directoryMode?: number;
18+
19+
/**
20+
The working directory to find source files.
21+
22+
The source and destination path are relative to this.
23+
24+
@default process.cwd()
25+
*/
26+
readonly cwd?: string;
1827
}
1928

2029
interface ProgressData {

‎index.js

+26-8
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,25 @@ const cpFileAsync = async (source, destination, options, progressEmitter) => {
5252
}
5353
};
5454

55-
const cpFile = (sourcePath, destinationPath, options) => {
55+
const resolvePath = (cwd, sourcePath, destinationPath) => {
56+
sourcePath = path.resolve(cwd, sourcePath);
57+
destinationPath = path.resolve(cwd, destinationPath);
58+
59+
return {
60+
sourcePath,
61+
destinationPath
62+
};
63+
};
64+
65+
const cpFile = (sourcePath, destinationPath, options = {}) => {
5666
if (!sourcePath || !destinationPath) {
5767
return Promise.reject(new CpFileError('`source` and `destination` required'));
5868
}
5969

70+
if (options.cwd) {
71+
({sourcePath, destinationPath} = resolvePath(options.cwd, sourcePath, destinationPath));
72+
}
73+
6074
options = {
6175
overwrite: true,
6276
...options
@@ -85,23 +99,27 @@ const checkSourceIsFile = (stat, source) => {
8599
}
86100
};
87101

88-
module.exports.sync = (source, destination, options) => {
89-
if (!source || !destination) {
102+
module.exports.sync = (sourcePath, destinationPath, options = {}) => {
103+
if (!sourcePath || !destinationPath) {
90104
throw new CpFileError('`source` and `destination` required');
91105
}
92106

107+
if (options.cwd) {
108+
({sourcePath, destinationPath} = resolvePath(options.cwd, sourcePath, destinationPath));
109+
}
110+
93111
options = {
94112
overwrite: true,
95113
...options
96114
};
97115

98-
const stat = fs.statSync(source);
99-
checkSourceIsFile(stat, source);
100-
fs.makeDirSync(path.dirname(destination), {mode: options.directoryMode});
116+
const stat = fs.statSync(sourcePath);
117+
checkSourceIsFile(stat, sourcePath);
118+
fs.makeDirSync(path.dirname(destinationPath), {mode: options.directoryMode});
101119

102120
const flags = options.overwrite ? null : fsConstants.COPYFILE_EXCL;
103121
try {
104-
fs.copyFileSync(source, destination, flags);
122+
fs.copyFileSync(sourcePath, destinationPath, flags);
105123
} catch (error) {
106124
if (!options.overwrite && error.code === 'EEXIST') {
107125
return;
@@ -110,5 +128,5 @@ module.exports.sync = (source, destination, options) => {
110128
throw error;
111129
}
112130

113-
fs.utimesSync(destination, stat.atime, stat.mtime);
131+
fs.utimesSync(destinationPath, stat.atime, stat.mtime);
114132
};

‎readme.md

+9
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,15 @@ Default: `true`
5959

6060
Overwrite existing destination file.
6161

62+
##### cwd
63+
64+
Type: `string`\
65+
Default: `process.cwd()`
66+
67+
The working directory to find source files.
68+
69+
The source and destination path are relative to this.
70+
6271
##### directoryMode
6372

6473
Type: `number`\

‎test/async.js

+9
Original file line numberDiff line numberDiff line change
@@ -269,3 +269,12 @@ test.serial('rethrow read after open errors', async t => {
269269

270270
Object.assign(fs, {createWriteStream, createReadStream});
271271
});
272+
273+
test('cwd option', async t => {
274+
const error = await t.throwsAsync(cpFile('sync.js', t.context.destination));
275+
276+
t.is(error.name, 'CpFileError');
277+
t.is(error.code, 'ENOENT');
278+
279+
await t.notThrowsAsync(cpFile('sync.js', t.context.destination, {cwd: 'test'}));
280+
});

‎test/sync.js

+13
Original file line numberDiff line numberDiff line change
@@ -218,3 +218,16 @@ test('rethrow utimes errors', t => {
218218

219219
fs.utimesSync.restore();
220220
});
221+
222+
test('cwd option', t => {
223+
const error = t.throws(() => {
224+
cpFile.sync('sync.js', t.context.destination);
225+
});
226+
227+
t.is(error.name, 'CpFileError');
228+
t.is(error.code, 'ENOENT');
229+
230+
t.notThrows(() => {
231+
cpFile.sync('sync.js', t.context.destination, {cwd: 'test'});
232+
});
233+
});

0 commit comments

Comments
 (0)
Please sign in to comment.