Skip to content

Commit f15a279

Browse files
committedMay 7, 2020
chore: Use spire
1 parent b7016e6 commit f15a279

16 files changed

+6184
-2080
lines changed
 

‎.eslintignore

-1
This file was deleted.

‎.eslintrc

-11
This file was deleted.

‎.eslintrc.js

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
// This file was created by spire-plugin-eslint for editor support
2+
module.exports = require('@researchgate/spire-config/eslint/node');

‎.travis.yml

+9-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,14 @@ node_js:
44
- "10"
55
- "8"
66
script:
7-
- yarn lint
8-
- yarn test:coverage
7+
- yarn test --coverage
98
after_success:
109
- bash <(curl -s https://codecov.io/bash) -f coverage/coverage-final.json
10+
jobs:
11+
include:
12+
- stage: test
13+
node_js: lts/*
14+
name: "Codestyle"
15+
script:
16+
- yarn lint
17+
after_success: skip

‎CHANGELOG.md

+21-20
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,53 @@
11
# Change Log
22

3-
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
3+
All notable changes to this project will be documented in this file. See
4+
[standard-version](https://github.com/conventional-changelog/standard-version)
5+
for commit guidelines.
46

57
<a name="2.0.0"></a>
6-
# [2.0.0](https://github.com/researchgate/node-file-processor/compare/v1.2.0...v2.0.0) (2018-03-21)
78

9+
# [2.0.0](https://github.com/researchgate/node-file-processor/compare/v1.2.0...v2.0.0) (2018-03-21)
810

911
### Features
1012

11-
* Add keepAlive option ([f9fb05a](https://github.com/researchgate/node-file-processor/commit/f9fb05a))
12-
13+
- Add keepAlive option
14+
([f9fb05a](https://github.com/researchgate/node-file-processor/commit/f9fb05a))
1315

1416
### BREAKING CHANGES
1517

16-
* worker-farm options are moved to `options.worker` key.
17-
* abort method renamed to destroy.
18-
19-
18+
- worker-farm options are moved to `options.worker` key.
19+
- abort method renamed to destroy.
2020

2121
<a name="1.2.0"></a>
22-
# [1.2.0](https://github.com/researchgate/node-file-processor/compare/v1.1.0...v1.2.0) (2018-01-05)
2322

23+
# [1.2.0](https://github.com/researchgate/node-file-processor/compare/v1.1.0...v1.2.0) (2018-01-05)
2424

2525
### Bug Fixes
2626

27-
* Exit immediately if an error happened ([#7](https://github.com/researchgate/node-file-processor/issues/7)) ([b41e656](https://github.com/researchgate/node-file-processor/commit/b41e656))
28-
27+
- Exit immediately if an error happened
28+
([#7](https://github.com/researchgate/node-file-processor/issues/7))
29+
([b41e656](https://github.com/researchgate/node-file-processor/commit/b41e656))
2930

3031
### Features
3132

32-
* **worker-farm:** Allow to pass-through options to worker-farm ([#6](https://github.com/researchgate/node-file-processor/issues/6)) ([64fb20d](https://github.com/researchgate/node-file-processor/commit/64fb20d))
33-
34-
33+
- **worker-farm:** Allow to pass-through options to worker-farm
34+
([#6](https://github.com/researchgate/node-file-processor/issues/6))
35+
([64fb20d](https://github.com/researchgate/node-file-processor/commit/64fb20d))
3536

3637
<a name="1.1.0"></a>
37-
# [1.1.0](https://github.com/researchgate/node-file-processor/compare/v1.0.0...v1.1.0) (2017-08-11)
3838

39+
# [1.1.0](https://github.com/researchgate/node-file-processor/compare/v1.0.0...v1.1.0) (2017-08-11)
3940

4041
### Features
4142

42-
* Support multiple paths ([3bc826e](https://github.com/researchgate/node-file-processor/commit/3bc826e))
43-
44-
43+
- Support multiple paths
44+
([3bc826e](https://github.com/researchgate/node-file-processor/commit/3bc826e))
4545

4646
<a name="1.0.0"></a>
47-
# 1.0.0 (2017-08-09)
4847

48+
# 1.0.0 (2017-08-09)
4949

5050
### Features
5151

52-
* Implement library ([815824e](https://github.com/researchgate/node-file-processor/commit/815824e))
52+
- Implement library
53+
([815824e](https://github.com/researchgate/node-file-processor/commit/815824e))

‎README.md

+16-21
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,11 @@ Must export single function, accepting `fileName` and `callback`. This function
1616
must process the file and call the `callback` when it is done. Function can be
1717
asynchronous.
1818

19-
2019
```js
2120
module.exports = function (fileName, callback) {
22-
const result = doExpensiveProcessing(fileName);
23-
callback(null, result);
24-
}
21+
const result = doExpensiveProcessing(fileName);
22+
callback(null, result);
23+
};
2524
```
2625

2726
### Main module
@@ -33,47 +32,43 @@ worker module.
3332
```js
3433
const FileProcessor = require('@researchgate/file-processor');
3534
const processor = new FileProcessor(
36-
[
37-
'path/to/some/files/*.txt',
38-
'some/other/path/*.js',
39-
],
40-
require.resolve('./worker')
35+
['path/to/some/files/*.txt', 'some/other/path/*.js'],
36+
require.resolve('./worker')
4137
);
4238

4339
processor.on('processed', (fileName, result) => {
44-
console.log(`result for ${fileName}: ${result}`);
40+
console.log(`result for ${fileName}: ${result}`);
4541
});
4642
```
4743

4844
`FileProcessor` instace emits following events:
4945

50-
* `queued` - file is queued for processing.
51-
52-
Arguments:
46+
- `queued` - file is queued for processing.
5347

54-
* `fileName`
48+
Arguments:
5549

50+
- `fileName`
5651

5752
* `processed` - file is successfully processed by worker.
5853

5954
Arguments:
6055

61-
* `fileName`
62-
* `result` - the result, returned by worker module
56+
- `fileName`
57+
- `result` - the result, returned by worker module
6358

6459
* `error` - worker failed to process the file
6560

6661
Arguments:
6762

68-
* `error`
63+
- `error`
6964

7065
* `allQueued` - all files, matching the pattern are queued for processing.
7166

7267
Arguments:
7368

74-
* `stats` - object with the following field
75-
76-
* `queuedCount` - total number of queued files
77-
* `processedCount` - total number of files which are already processed
69+
- `stats` - object with the following field
70+
71+
- `queuedCount` - total number of queued files
72+
- `processedCount` - total number of files which are already processed
7873

7974
* `end` - all files are processed.

‎index.js

+53-51
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,61 @@
1+
'use strict';
2+
13
const { EventEmitter } = require('events');
24
const globStream = require('glob-stream');
35
const workerFarm = require('worker-farm');
46

57
class FileProcessor extends EventEmitter {
6-
constructor(globPattern, worker, options) {
7-
super();
8-
options = options || {};
9-
const glob = (this.glob = globStream(globPattern));
10-
const workers = (this.workers = workerFarm(options.worker || {}, worker));
11-
12-
let allQueued = false;
13-
let errorHappened = false;
14-
let queuedCount = 0;
15-
let processedCount = 0;
16-
17-
const checkForEnd = () => {
18-
if (errorHappened || (allQueued && queuedCount === processedCount)) {
19-
if (!options.keepAlive) {
20-
workerFarm.end(workers);
21-
}
22-
if (!errorHappened) this.emit('end');
23-
}
24-
};
25-
26-
glob.on('data', ({ path }) => {
27-
queuedCount++;
28-
this.emit('queued', path);
29-
this.process(path, (err, result) => {
30-
processedCount++;
31-
if (err) {
32-
errorHappened = true;
33-
this.emit('error', err);
34-
} else {
35-
this.emit('processed', path, result);
36-
}
37-
38-
checkForEnd();
39-
});
40-
});
41-
42-
glob.on('end', () => {
43-
allQueued = true;
44-
this.emit('allQueued', { queuedCount, processedCount });
45-
checkForEnd();
46-
});
47-
}
48-
49-
process(path, callback) {
50-
this.workers(path, callback);
51-
}
52-
53-
destroy(callback) {
54-
this.glob.destroy();
55-
workerFarm.end(this.workers, callback);
56-
}
8+
constructor(globPattern, worker, options) {
9+
super();
10+
options = options || {};
11+
const glob = (this.glob = globStream(globPattern));
12+
const workers = (this.workers = workerFarm(options.worker || {}, worker));
13+
14+
let allQueued = false;
15+
let errorHappened = false;
16+
let queuedCount = 0;
17+
let processedCount = 0;
18+
19+
const checkForEnd = () => {
20+
if (errorHappened || (allQueued && queuedCount === processedCount)) {
21+
if (!options.keepAlive) {
22+
workerFarm.end(workers);
23+
}
24+
if (!errorHappened) this.emit('end');
25+
}
26+
};
27+
28+
glob.on('data', ({ path }) => {
29+
queuedCount++;
30+
this.emit('queued', path);
31+
this.process(path, (err, result) => {
32+
processedCount++;
33+
if (err) {
34+
errorHappened = true;
35+
this.emit('error', err);
36+
} else {
37+
this.emit('processed', path, result);
38+
}
39+
40+
checkForEnd();
41+
});
42+
});
43+
44+
glob.on('end', () => {
45+
allQueued = true;
46+
this.emit('allQueued', { queuedCount, processedCount });
47+
checkForEnd();
48+
});
49+
}
50+
51+
process(path, callback) {
52+
this.workers(path, callback);
53+
}
54+
55+
destroy(callback) {
56+
this.glob.destroy();
57+
workerFarm.end(this.workers, callback);
58+
}
5759
}
5860

5961
module.exports = FileProcessor;

‎package.json

+27-33
Original file line numberDiff line numberDiff line change
@@ -3,49 +3,43 @@
33
"version": "2.0.0",
44
"description": "Run parallel tasks on a multiple files",
55
"main": "index.js",
6+
"author": "Sergey Tatarintsev <sergey.tatarintsev@researchgate.net> (https://github.com/SevInf)",
7+
"license": "MIT",
8+
"repository": "researchgate/node-file-processor",
69
"scripts": {
7-
"test": "jest",
8-
"test:coverage": "jest --coverage",
9-
"lint": "eslint .",
10-
"precommit": "yarn lint && lint-staged",
11-
"release": "standard-version"
10+
"test": "spire test",
11+
"lint": "spire lint",
12+
"release": "spire release"
1213
},
1314
"files": [
1415
"index.js"
1516
],
16-
"lint-staged": {
17-
"*.js": [
18-
"prettier --single-quote --write --tab-width 4 --trailing-comma es5 --print-width 120",
19-
"git add"
20-
]
21-
},
22-
"jest":{
23-
"testEnvironment": "node",
24-
"testRegex": "/test/[^/]+\\.js$"
25-
},
26-
"author": "Sergey Tatarintsev <sergey.tatarintsev@researchgate.net> (https://github.com/SevInf)",
27-
"license": "MIT",
2817
"dependencies": {
2918
"glob-stream": "^6.1.0",
3019
"worker-farm": "^1.4.1"
3120
},
3221
"devDependencies": {
33-
"eslint": "6.8.0",
34-
"husky": "3.1.0",
35-
"jest": "24.9.0",
36-
"lint-staged": "9.5.0",
37-
"prettier": "1.19.1",
38-
"standard-version": "7.0.0"
39-
},
40-
"directories": {
41-
"test": "test"
42-
},
43-
"repository": {
44-
"type": "git",
45-
"url": "git+https://github.com/researchgate/node-file-processor.git"
22+
"@researchgate/spire-config": "4.0.2",
23+
"spire": "2.1.4",
24+
"spire-plugin-semantic-release": "2.0.2"
25+
},
26+
"spire": {
27+
"extends": [
28+
[
29+
"@researchgate/spire-config",
30+
{
31+
"eslint": "node",
32+
"jest": "base"
33+
}
34+
]
35+
],
36+
"plugins": [
37+
"spire-plugin-semantic-release"
38+
]
4639
},
47-
"bugs": {
48-
"url": "https://github.com/researchgate/node-file-processor/issues"
40+
"jest": {
41+
"preset": "@researchgate/jest-preset-base",
42+
"testEnvironment": "node"
4943
},
50-
"homepage": "https://github.com/researchgate/node-file-processor#readme"
44+
"prettier": "@researchgate/prettier-config"
5145
}

‎renovate.json

+1-7
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,5 @@
22
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
33
"extends": ["@researchgate:lib"],
44
"automergeType": "branch",
5-
"labels": ["dependencies"],
6-
"lockFileMaintenance": {
7-
"enabled": true,
8-
"automerge":true,
9-
"automergeType":"branch",
10-
"extends": "schedule:weekly"
11-
}
5+
"labels": ["dependencies"]
126
}

‎test/error-test.js

-23
This file was deleted.

‎test/error.spec.js

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
'use strict';
2+
3+
const path = require('path');
4+
const workerPath = require.resolve('./workers/error-worker');
5+
const FileProcessor = require('..');
6+
7+
const examplePath = (fileName) => path.join(__dirname, 'example', fileName);
8+
const pattern = examplePath('*.txt');
9+
10+
describe('fails', () => {
11+
let fileProcessor = null;
12+
beforeEach(() => {
13+
fileProcessor = new FileProcessor(pattern, workerPath);
14+
});
15+
16+
test('reports error in worker', () => {
17+
expect.assertions(1);
18+
return new Promise((resolve) => {
19+
fileProcessor.on('error', (err) => {
20+
expect(err).toEqual(new Error('Not today'));
21+
resolve();
22+
});
23+
});
24+
});
25+
});

‎test/index.spec.js

+114
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
'use strict';
2+
3+
const path = require('path');
4+
const workerPath = require.resolve('./workers/worker');
5+
const FileProcessor = require('..');
6+
7+
const examplePath = (fileName) => path.join(__dirname, 'example', fileName);
8+
const pattern = examplePath('*.txt');
9+
10+
describe('success', () => {
11+
let fileProcessor = null;
12+
beforeEach(() => {
13+
fileProcessor = new FileProcessor(pattern, workerPath);
14+
});
15+
16+
test('queued', () => {
17+
expect.assertions(3);
18+
const handler = jest.fn();
19+
fileProcessor.on('queued', handler);
20+
return new Promise((resolve) => {
21+
fileProcessor.on('end', () => {
22+
expect(handler).toHaveBeenCalledWith(examplePath('1.txt'));
23+
expect(handler).toHaveBeenCalledWith(examplePath('2.txt'));
24+
expect(handler).toHaveBeenCalledWith(examplePath('3.txt'));
25+
resolve();
26+
});
27+
});
28+
});
29+
30+
test('processed', () => {
31+
expect.assertions(3);
32+
const handler = jest.fn();
33+
fileProcessor.on('processed', handler);
34+
return new Promise((resolve) => {
35+
fileProcessor.on('end', () => {
36+
expect(handler).toHaveBeenCalledWith(examplePath('1.txt'), 'a');
37+
expect(handler).toHaveBeenCalledWith(examplePath('2.txt'), 'b');
38+
expect(handler).toHaveBeenCalledWith(examplePath('3.txt'), 'c');
39+
resolve();
40+
});
41+
});
42+
});
43+
44+
test('allQueued', () => {
45+
expect.assertions(1);
46+
const handler = jest.fn();
47+
fileProcessor.on('allQueued', handler);
48+
return new Promise((resolve) => {
49+
fileProcessor.on('end', () => {
50+
expect(handler).toHaveBeenCalledWith(
51+
expect.objectContaining({
52+
queuedCount: 3,
53+
processedCount: expect.any(Number),
54+
})
55+
);
56+
resolve();
57+
});
58+
});
59+
});
60+
61+
test('destroy', () => {
62+
return new Promise((resolve) => {
63+
fileProcessor.destroy(resolve);
64+
});
65+
});
66+
67+
test('multiple paths', () => {
68+
fileProcessor = new FileProcessor(
69+
[examplePath('1.txt'), examplePath('3.txt')],
70+
workerPath
71+
);
72+
73+
expect.assertions(3);
74+
const handler = jest.fn();
75+
fileProcessor.on('queued', handler);
76+
return new Promise((resolve) => {
77+
fileProcessor.on('end', () => {
78+
expect(handler).toHaveBeenCalledWith(examplePath('1.txt'));
79+
expect(handler).not.toHaveBeenCalledWith(examplePath('2.txt'));
80+
expect(handler).toHaveBeenCalledWith(examplePath('3.txt'));
81+
resolve();
82+
});
83+
});
84+
});
85+
86+
describe('keepAlive', () => {
87+
let processor;
88+
89+
beforeEach(() => {
90+
processor = new FileProcessor(examplePath('1.txt'), workerPath, {
91+
keepAlive: true,
92+
});
93+
});
94+
95+
test('allows to process more files after initial pass', () => {
96+
expect.assertions(2);
97+
return new Promise((resolve) => {
98+
processor.on('end', () => {
99+
processor.process(examplePath('2.txt'), (error, result) => {
100+
expect(error).toBe(null);
101+
expect(result).toEqual('b');
102+
resolve();
103+
});
104+
});
105+
});
106+
});
107+
108+
afterEach(() => {
109+
return new Promise((resolve) => {
110+
processor.destroy(resolve);
111+
});
112+
});
113+
});
114+
});

‎test/test.js

-107
This file was deleted.

‎test/workers/error-worker.js

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1-
module.exports = function(fileName, callback) {
2-
callback(new Error('Not today'));
1+
'use strict';
2+
3+
module.exports = function (fileName, callback) {
4+
callback(new Error('Not today'));
35
};

‎test/workers/worker.js

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
'use strict';
2+
13
const fs = require('fs');
24

3-
module.exports = function(fileName, callback) {
4-
fs.readFile(fileName, 'utf8', callback);
5+
module.exports = function (fileName, callback) {
6+
fs.readFile(fileName, 'utf8', callback);
57
};

‎yarn.lock

+5,908-1,800
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)
Please sign in to comment.