Skip to content

Commit edcc055

Browse files
committedJun 11, 2019
Meta tweaks
1 parent d3ed7b9 commit edcc055

File tree

7 files changed

+125
-122
lines changed

7 files changed

+125
-122
lines changed
 

‎index.d.ts

+11-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
declare namespace cpFile {
22
interface Options {
33
/**
4-
Overwrite existing file.
4+
Overwrite existing destination file.
55
66
@default true
77
*/
@@ -37,7 +37,7 @@ declare namespace cpFile {
3737

3838
interface ProgressEmitter {
3939
/**
40-
For empty files, the `progress` event is emitted only once.
40+
Note: For empty files, the `progress` event is emitted only once.
4141
*/
4242
on(event: 'progress', handler: (data: ProgressData) => void): Promise<void>;
4343
}
@@ -47,7 +47,7 @@ declare const cpFile: {
4747
/**
4848
Copy a file.
4949
50-
@param source - File you want to copy.
50+
@param source - The file you want to copy.
5151
@param destination - Where you want the file copied.
5252
@returns A `Promise` that resolves when the file is copied.
5353
@@ -66,8 +66,15 @@ declare const cpFile: {
6666
/**
6767
Copy a file synchronously.
6868
69-
@param source - File you want to copy.
69+
@param source - The file you want to copy.
7070
@param destination - Where you want the file copied.
71+
72+
@example
73+
```
74+
import cpFile = require('cp-file');
75+
76+
cpFile.sync('source/unicorn.png', 'destination/unicorn.png');
77+
```
7178
*/
7279
sync(source: string, destination: string, options?: cpFile.Options): void;
7380
};

‎package.json

+5-12
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,6 @@
99
"email": "sindresorhus@gmail.com",
1010
"url": "sindresorhus.com"
1111
},
12-
"maintainers": [
13-
{
14-
"name": "Michael Mayer",
15-
"email": "michael@schnittstabil.de",
16-
"url": "schnittstabil.de"
17-
}
18-
],
1912
"engines": {
2013
"node": ">=8"
2114
},
@@ -51,14 +44,14 @@
5144
"p-event": "^4.1.0"
5245
},
5346
"devDependencies": {
54-
"ava": "^1.4.1",
47+
"ava": "^2.1.0",
5548
"clear-module": "^3.1.0",
56-
"coveralls": "^3.0.3",
57-
"del": "^4.1.0",
49+
"coveralls": "^3.0.4",
50+
"del": "^4.1.1",
5851
"import-fresh": "^3.0.0",
59-
"nyc": "^13.3.0",
52+
"nyc": "^14.1.1",
6053
"sinon": "^7.3.1",
61-
"tsd": "^0.7.2",
54+
"tsd": "^0.7.3",
6255
"uuid": "^3.3.2",
6356
"xo": "^0.24.0"
6457
}

‎readme.md

+7-10
Original file line numberDiff line numberDiff line change
@@ -33,17 +33,17 @@ const cpFile = require('cp-file');
3333

3434
## API
3535

36-
### cpFile(source, destination, [options])
36+
### cpFile(source, destination, options?)
3737

3838
Returns a `Promise` that resolves when the file is copied.
3939

40-
### cpFile.sync(source, destination, [options])
40+
### cpFile.sync(source, destination, options?)
4141

4242
#### source
4343

4444
Type: `string`
4545

46-
File you want to copy.
46+
The file you want to copy.
4747

4848
#### destination
4949

@@ -53,14 +53,14 @@ Where you want the file copied.
5353

5454
#### options
5555

56-
Type: `Object`
56+
Type: `object`
5757

5858
##### overwrite
5959

6060
Type: `boolean`<br>
6161
Default: `true`
6262

63-
Overwrite existing file.
63+
Overwrite existing destination file.
6464

6565
### cpFile.on('progress', handler)
6666

@@ -93,6 +93,8 @@ Type: `Function`
9393
you add a `handler` before `.then()`:
9494

9595
```js
96+
const cpFile = require('cp-file');
97+
9698
(async () => {
9799
await cpFile(source, destination).on('progress', data => {
98100
//
@@ -107,8 +109,3 @@ you add a `handler` before `.then()`:
107109
- [cpy-cli](https://github.com/sindresorhus/cpy-cli) - Copy files on the command-line
108110
- [move-file](https://github.com/sindresorhus/move-file) - Move a file
109111
- [make-dir](https://github.com/sindresorhus/make-dir) - Make a directory and its parents if needed
110-
111-
112-
## License
113-
114-
MIT © [Sindre Sorhus](https://sindresorhus.com)

‎test/async.js

+55-53
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ import test from 'ava';
88
import uuid from 'uuid';
99
import sinon from 'sinon';
1010
import cpFile from '..';
11-
import assertDateEqual from './helpers/assert';
12-
import {buildEACCES, buildEIO, buildENOSPC, buildENOENT, buildEPERM} from './helpers/fs-errors';
11+
import assertDateEqual from './helpers/_assert';
12+
import {buildEACCES, buildEIO, buildENOSPC, buildENOENT, buildEPERM} from './helpers/_fs-errors';
1313

1414
const THREE_HUNDRED_KILO = (100 * 3 * 1024) + 1;
1515

@@ -24,7 +24,9 @@ test.beforeEach(t => {
2424
});
2525

2626
test.afterEach.always(t => {
27-
t.context.creates.forEach(path => del.sync(path));
27+
for (const path_ of t.context.creates) {
28+
del.sync(path_);
29+
}
2830
});
2931

3032
test('reject an Error on missing `source`', async t => {
@@ -47,10 +49,10 @@ test('copy an empty file', async t => {
4749
});
4850

4951
test('copy big files', async t => {
50-
const buf = crypto.randomBytes(THREE_HUNDRED_KILO);
51-
fs.writeFileSync(t.context.source, buf);
52+
const buffer = crypto.randomBytes(THREE_HUNDRED_KILO);
53+
fs.writeFileSync(t.context.source, buffer);
5254
await cpFile(t.context.source, t.context.destination);
53-
t.true(buf.equals(fs.readFileSync(t.context.destination)));
55+
t.true(buffer.equals(fs.readFileSync(t.context.destination)));
5456
});
5557

5658
test('do not alter overwrite option', async t => {
@@ -78,18 +80,18 @@ test('do not overwrite when disabled', async t => {
7880
});
7981

8082
test('do not create `destination` on unreadable `source`', async t => {
81-
const error = await t.throwsAsync(() => cpFile('node_modules', t.context.destination));
82-
t.is(error.name, 'CpFileError', error);
83-
t.is(error.code, 'EISDIR', error);
83+
const error = await t.throwsAsync(cpFile('node_modules', t.context.destination));
84+
t.is(error.name, 'CpFileError', error.message);
85+
t.is(error.code, 'EISDIR', error.message);
8486
t.throws(() => {
8587
fs.statSync(t.context.destination);
8688
}, /ENOENT/);
8789
});
8890

8991
test('do not create `destination` directory on unreadable `source`', async t => {
90-
const error = await t.throwsAsync(() => cpFile('node_modules', 'subdir/' + uuid.v4()));
91-
t.is(error.name, 'CpFileError', error);
92-
t.is(error.code, 'EISDIR', error);
92+
const error = await t.throwsAsync(cpFile('node_modules', path.join('subdir', uuid.v4())));
93+
t.is(error.name, 'CpFileError', error.message);
94+
t.is(error.code, 'EISDIR', error.message);
9395
t.throws(() => {
9496
fs.statSync('subdir');
9597
}, /ENOENT/);
@@ -98,47 +100,47 @@ test('do not create `destination` directory on unreadable `source`', async t =>
98100
test('preserve timestamps', async t => {
99101
await cpFile('license', t.context.destination);
100102
const licenseStats = fs.lstatSync('license');
101-
const tmpStats = fs.lstatSync(t.context.destination);
102-
assertDateEqual(t, licenseStats.atime, tmpStats.atime);
103-
assertDateEqual(t, licenseStats.mtime, tmpStats.mtime);
103+
const tempStats = fs.lstatSync(t.context.destination);
104+
assertDateEqual(t, licenseStats.atime, tempStats.atime);
105+
assertDateEqual(t, licenseStats.mtime, tempStats.mtime);
104106
});
105107

106108
test('preserve mode', async t => {
107109
await cpFile('license', t.context.destination);
108110
const licenseStats = fs.lstatSync('license');
109-
const tmpStats = fs.lstatSync(t.context.destination);
110-
t.is(licenseStats.mode, tmpStats.mode);
111+
const tempStats = fs.lstatSync(t.context.destination);
112+
t.is(licenseStats.mode, tempStats.mode);
111113
});
112114

113115
test('preserve ownership', async t => {
114116
await cpFile('license', t.context.destination);
115117
const licenseStats = fs.lstatSync('license');
116-
const tmpStats = fs.lstatSync(t.context.destination);
117-
t.is(licenseStats.gid, tmpStats.gid);
118-
t.is(licenseStats.uid, tmpStats.uid);
118+
const tempStats = fs.lstatSync(t.context.destination);
119+
t.is(licenseStats.gid, tempStats.gid);
120+
t.is(licenseStats.uid, tempStats.uid);
119121
});
120122

121123
test('throw an Error if `source` does not exists', async t => {
122124
const error = await t.throwsAsync(cpFile('NO_ENTRY', t.context.destination));
123-
t.is(error.name, 'CpFileError', error);
124-
t.is(error.code, 'ENOENT', error);
125-
t.regex(error.message, /`NO_ENTRY`/, error);
126-
t.regex(error.stack, /`NO_ENTRY`/, error);
125+
t.is(error.name, 'CpFileError', error.message);
126+
t.is(error.code, 'ENOENT', error.message);
127+
t.regex(error.message, /`NO_ENTRY`/, error.message);
128+
t.regex(error.stack, /`NO_ENTRY`/, error.message);
127129
});
128130

129131
test.serial('rethrow mkdir EACCES errors', async t => {
130-
const dirPath = '/root/NO_ACCESS_' + uuid.v4();
131-
const dest = dirPath + '/' + uuid.v4();
132-
const mkdirError = buildEACCES(dirPath);
132+
const directoryPath = `/root/NO_ACCESS_${uuid.v4()}`;
133+
const destination = path.join(directoryPath, uuid.v4());
134+
const mkdirError = buildEACCES(directoryPath);
133135

134136
fs.stat = sinon.stub(fs, 'stat').throws(mkdirError);
135137
fs.mkdir = sinon.stub(fs, 'mkdir').throws(mkdirError);
136138

137-
const error = await t.throwsAsync(cpFile('license', dest));
138-
t.is(error.name, 'CpFileError', error);
139-
t.is(error.errno, mkdirError.errno, error);
140-
t.is(error.code, mkdirError.code, error);
141-
t.is(error.path, mkdirError.path, error);
139+
const error = await t.throwsAsync(cpFile('license', destination));
140+
t.is(error.name, 'CpFileError', error.message);
141+
t.is(error.errno, mkdirError.errno, error.message);
142+
t.is(error.code, mkdirError.code, error.message);
143+
t.is(error.path, mkdirError.path, error.message);
142144
t.true(fs.mkdir.called || fs.stat.called);
143145

144146
fs.mkdir.restore();
@@ -148,14 +150,14 @@ test.serial('rethrow mkdir EACCES errors', async t => {
148150
test.serial('rethrow ENOSPC errors', async t => {
149151
const {createWriteStream} = fs;
150152
const noSpaceError = buildENOSPC();
151-
let called = false;
153+
let isCalled = false;
152154

153155
fs.createWriteStream = (path, options) => {
154156
const stream = createWriteStream(path, options);
155157
if (path === t.context.destination) {
156158
stream.on('pipe', () => {
157-
if (!called) {
158-
called = true;
159+
if (!isCalled) {
160+
isCalled = true;
159161
stream.emit('error', noSpaceError);
160162
}
161163
});
@@ -167,10 +169,10 @@ test.serial('rethrow ENOSPC errors', async t => {
167169
clearModule('../fs');
168170
const uncached = importFresh('..');
169171
const error = await t.throwsAsync(uncached('license', t.context.destination));
170-
t.is(error.name, 'CpFileError', error);
171-
t.is(error.errno, noSpaceError.errno, error);
172-
t.is(error.code, noSpaceError.code, error);
173-
t.true(called);
172+
t.is(error.name, 'CpFileError', error.message);
173+
t.is(error.errno, noSpaceError.errno, error.message);
174+
t.is(error.code, noSpaceError.code, error.message);
175+
t.true(isCalled);
174176

175177
fs.createWriteStream = createWriteStream;
176178
});
@@ -184,9 +186,9 @@ test.serial('rethrow stat errors', async t => {
184186
clearModule('../fs');
185187
const uncached = importFresh('..');
186188
const error = await t.throwsAsync(uncached(t.context.source, t.context.destination));
187-
t.is(error.name, 'CpFileError', error);
188-
t.is(error.errno, fstatError.errno, error);
189-
t.is(error.code, fstatError.code, error);
189+
t.is(error.name, 'CpFileError', error.message);
190+
t.is(error.errno, fstatError.errno, error.message);
191+
t.is(error.code, fstatError.code, error.message);
190192
t.true(fs.lstat.called);
191193

192194
fs.lstat.restore();
@@ -200,8 +202,8 @@ test.serial('rethrow utimes errors', async t => {
200202
clearModule('../fs');
201203
const uncached = importFresh('..');
202204
const error = await t.throwsAsync(uncached('license', t.context.destination));
203-
t.is(error.name, 'CpFileError', error);
204-
t.is(error.code, 'ENOENT', error);
205+
t.is(error.name, 'CpFileError', error.message);
206+
t.is(error.code, 'ENOENT', error.message);
205207
t.true(fs.utimes.called);
206208

207209
fs.utimes.restore();
@@ -215,9 +217,9 @@ test.serial('rethrow chmod errors', async t => {
215217
clearModule('../fs');
216218
const uncached = importFresh('..');
217219
const error = await t.throwsAsync(uncached('license', t.context.destination));
218-
t.is(error.name, 'CpFileError', error);
219-
t.is(error.code, chmodError.code, error);
220-
t.is(error.path, chmodError.path, error);
220+
t.is(error.name, 'CpFileError', error.message);
221+
t.is(error.code, chmodError.code, error.message);
222+
t.is(error.path, chmodError.path, error.message);
221223
t.true(fs.chmod.called);
222224

223225
fs.chmod.restore();
@@ -231,9 +233,9 @@ test.serial('rethrow chown errors', async t => {
231233
clearModule('../fs');
232234
const uncached = importFresh('..');
233235
const error = await t.throwsAsync(uncached('license', t.context.destination));
234-
t.is(error.name, 'CpFileError', error);
235-
t.is(error.code, chownError.code, error);
236-
t.is(error.path, chownError.path, error);
236+
t.is(error.name, 'CpFileError', error.message);
237+
t.is(error.code, chownError.code, error.message);
238+
t.is(error.path, chownError.path, error.message);
237239
t.true(fs.chown.called);
238240

239241
fs.chown.restore();
@@ -272,9 +274,9 @@ test.serial('rethrow read after open errors', async t => {
272274
clearModule('../fs');
273275
const uncached = importFresh('..');
274276
const error = await t.throwsAsync(uncached('license', t.context.destination));
275-
t.is(error.name, 'CpFileError', error);
276-
t.is(error.errno, readError.errno, error);
277-
t.is(error.code, readError.code, error);
277+
t.is(error.name, 'CpFileError', error.message);
278+
t.is(error.errno, readError.errno, error.message);
279+
t.is(error.code, readError.code, error.message);
278280
t.is(calledWriteEnd, 1);
279281

280282
Object.assign(fs, {createWriteStream, createReadStream});
File renamed without changes.
File renamed without changes.

‎test/sync.js

+47-43
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ import test from 'ava';
66
import uuid from 'uuid';
77
import sinon from 'sinon';
88
import cpFile from '..';
9-
import assertDateEqual from './helpers/assert';
10-
import {buildEACCES, buildENOSPC, buildEBADF, buildEPERM} from './helpers/fs-errors';
9+
import assertDateEqual from './helpers/_assert';
10+
import {buildEACCES, buildENOSPC, buildEBADF, buildEPERM} from './helpers/_fs-errors';
1111

1212
const THREE_HUNDRED_KILO = (100 * 3 * 1024) + 1;
1313

@@ -22,7 +22,9 @@ test.beforeEach(t => {
2222
});
2323

2424
test.afterEach.always(t => {
25-
t.context.creates.forEach(path => del.sync(path));
25+
for (const path_ of t.context.creates) {
26+
del.sync(path_);
27+
}
2628
});
2729

2830
test('throw an Error on missing `source`', t => {
@@ -49,10 +51,10 @@ test('copy an empty file', t => {
4951
});
5052

5153
test('copy big files', t => {
52-
const buf = crypto.randomBytes(THREE_HUNDRED_KILO);
53-
fs.writeFileSync(t.context.source, buf);
54+
const buffer = crypto.randomBytes(THREE_HUNDRED_KILO);
55+
fs.writeFileSync(t.context.source, buffer);
5456
cpFile.sync(t.context.source, t.context.destination);
55-
t.true(buf.equals(fs.readFileSync(t.context.destination)));
57+
t.true(buffer.equals(fs.readFileSync(t.context.destination)));
5658
});
5759

5860
test('do not alter overwrite option', t => {
@@ -114,48 +116,50 @@ test('do not create `destination` directory on unreadable `source`', t => {
114116
test('preserve timestamps', t => {
115117
cpFile.sync('license', t.context.destination);
116118
const licenseStats = fs.lstatSync('license');
117-
const tmpStats = fs.lstatSync(t.context.destination);
118-
assertDateEqual(t, licenseStats.atime, tmpStats.atime);
119-
assertDateEqual(t, licenseStats.mtime, tmpStats.mtime);
119+
const tempStats = fs.lstatSync(t.context.destination);
120+
assertDateEqual(t, licenseStats.atime, tempStats.atime);
121+
assertDateEqual(t, licenseStats.mtime, tempStats.mtime);
120122
});
121123

122124
test('preserve mode', t => {
123125
cpFile.sync('license', t.context.destination);
124126
const licenseStats = fs.lstatSync('license');
125-
const tmpStats = fs.lstatSync(t.context.destination);
126-
t.is(licenseStats.mode, tmpStats.mode);
127+
const tempStats = fs.lstatSync(t.context.destination);
128+
t.is(licenseStats.mode, tempStats.mode);
127129
});
128130

129131
test('preserve ownership', t => {
130132
cpFile.sync('license', t.context.destination);
131133
const licenseStats = fs.lstatSync('license');
132-
const tmpStats = fs.lstatSync(t.context.destination);
133-
t.is(licenseStats.gid, tmpStats.gid);
134-
t.is(licenseStats.uid, tmpStats.uid);
134+
const tempStats = fs.lstatSync(t.context.destination);
135+
t.is(licenseStats.gid, tempStats.gid);
136+
t.is(licenseStats.uid, tempStats.uid);
135137
});
136138

137139
test('throw an Error if `source` does not exists', t => {
138-
const error = t.throws(() => cpFile.sync('NO_ENTRY', t.context.destination));
139-
t.is(error.name, 'CpFileError', error);
140-
t.is(error.code, 'ENOENT', error);
141-
t.regex(error.message, /`NO_ENTRY`/, error);
142-
t.regex(error.stack, /`NO_ENTRY`/, error);
140+
const error = t.throws(() => {
141+
cpFile.sync('NO_ENTRY', t.context.destination);
142+
});
143+
t.is(error.name, 'CpFileError', error.message);
144+
t.is(error.code, 'ENOENT', error.message);
145+
t.regex(error.message, /`NO_ENTRY`/, error.message);
146+
t.regex(error.stack, /`NO_ENTRY`/, error.message);
143147
});
144148

145149
test('rethrow mkdir EACCES errors', t => {
146-
const dirPath = '/root/NO_ACCESS_' + uuid.v4();
147-
const dest = dirPath + '/' + uuid.v4();
148-
const mkdirError = buildEACCES(dirPath);
150+
const directoryPath = `/root/NO_ACCESS_${uuid.v4()}`;
151+
const destination = path.join(directoryPath, uuid.v4());
152+
const mkdirError = buildEACCES(directoryPath);
149153

150154
fs.mkdirSync = sinon.stub(fs, 'mkdirSync').throws(mkdirError);
151155

152156
const error = t.throws(() => {
153-
cpFile.sync('license', dest);
157+
cpFile.sync('license', destination);
154158
});
155-
t.is(error.name, 'CpFileError', error);
156-
t.is(error.errno, mkdirError.errno, error);
157-
t.is(error.code, mkdirError.code, error);
158-
t.is(error.path, mkdirError.path, error);
159+
t.is(error.name, 'CpFileError', error.message);
160+
t.is(error.errno, mkdirError.errno, error.message);
161+
t.is(error.code, mkdirError.code, error.message);
162+
t.is(error.path, mkdirError.path, error.message);
159163
t.true(fs.mkdirSync.called);
160164

161165
fs.mkdirSync.restore();
@@ -170,10 +174,10 @@ test('rethrow ENOSPC errors', t => {
170174
const error = t.throws(() => {
171175
cpFile.sync('license', t.context.destination);
172176
});
173-
t.is(error.name, 'CpFileError', error);
174-
t.is(error.errno, noSpaceError.errno, error);
175-
t.is(error.code, noSpaceError.code, error);
176-
t.true(fs.copyFileSync.called, 1);
177+
t.is(error.name, 'CpFileError', error.message);
178+
t.is(error.errno, noSpaceError.errno, error.message);
179+
t.is(error.code, noSpaceError.code, error.message);
180+
t.true(fs.copyFileSync.called);
177181

178182
fs.copyFileSync.restore();
179183
});
@@ -188,9 +192,9 @@ test('rethrow stat errors', t => {
188192
const error = t.throws(() => {
189193
cpFile.sync(t.context.source, t.context.destination);
190194
});
191-
t.is(error.name, 'CpFileError', error);
192-
t.is(error.errno, statError.errno, error);
193-
t.is(error.code, statError.code, error);
195+
t.is(error.name, 'CpFileError', error.message);
196+
t.is(error.errno, statError.errno, error.message);
197+
t.is(error.code, statError.code, error.message);
194198
t.true(fs.statSync.called);
195199

196200
fs.statSync.restore();
@@ -204,9 +208,9 @@ test('rethrow utimes errors', t => {
204208
const error = t.throws(() => {
205209
cpFile.sync('license', t.context.destination);
206210
});
207-
t.is(error.name, 'CpFileError', error);
208-
t.is(error.errno, futimesError.errno, error);
209-
t.is(error.code, futimesError.code, error);
211+
t.is(error.name, 'CpFileError', error.message);
212+
t.is(error.errno, futimesError.errno, error.message);
213+
t.is(error.code, futimesError.code, error.message);
210214
t.true(fs.utimesSync.called);
211215

212216
fs.utimesSync.restore();
@@ -220,9 +224,9 @@ test('rethrow chmod errors', t => {
220224
const error = t.throws(() => {
221225
cpFile.sync('license', t.context.destination);
222226
});
223-
t.is(error.name, 'CpFileError', error);
224-
t.is(error.errno, chmodError.errno, error);
225-
t.is(error.code, chmodError.code, error);
227+
t.is(error.name, 'CpFileError', error.message);
228+
t.is(error.errno, chmodError.errno, error.message);
229+
t.is(error.code, chmodError.code, error.message);
226230
t.true(fs.chmodSync.called);
227231

228232
fs.chmodSync.restore();
@@ -236,9 +240,9 @@ test('rethrow chown errors', t => {
236240
const error = t.throws(() => {
237241
cpFile.sync('license', t.context.destination);
238242
});
239-
t.is(error.name, 'CpFileError', error);
240-
t.is(error.errno, chownError.errno, error);
241-
t.is(error.code, chownError.code, error);
243+
t.is(error.name, 'CpFileError', error.message);
244+
t.is(error.errno, chownError.errno, error.message);
245+
t.is(error.code, chownError.code, error.message);
242246
t.true(fs.chownSync.called);
243247

244248
fs.chownSync.restore();

0 commit comments

Comments
 (0)
Please sign in to comment.