@opentermsarchive/engine 0.25.1 → 0.26.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
|
@@ -226,12 +226,12 @@ Run [`ota validate`](#ota-validate) only on files that have been modified in Git
|
|
|
226
226
|
#### `ota lint`
|
|
227
227
|
|
|
228
228
|
```sh
|
|
229
|
-
npx ota lint [--services <service_id>...]
|
|
229
|
+
npx ota lint [--services <service_id>...] [--fix] [--modified]
|
|
230
230
|
```
|
|
231
231
|
|
|
232
|
-
|
|
232
|
+
Test the the format of declarations' normalisation.
|
|
233
233
|
|
|
234
|
-
|
|
234
|
+
Use `--fix` to automatically correct formatting mistakes and ensure that all declarations are standardised.
|
|
235
235
|
|
|
236
236
|
If one or several `<service_id>` are provided, check only those services.
|
|
237
237
|
|
package/bin/ota-lint.js
CHANGED
|
@@ -2,18 +2,55 @@
|
|
|
2
2
|
import './env.js';
|
|
3
3
|
|
|
4
4
|
import path from 'path';
|
|
5
|
-
import { fileURLToPath
|
|
5
|
+
import { fileURLToPath } from 'url';
|
|
6
6
|
|
|
7
7
|
import { program } from 'commander';
|
|
8
|
+
import Mocha from 'mocha';
|
|
8
9
|
|
|
9
10
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
10
11
|
|
|
12
|
+
const LINT_TEST_FILEPATH = '../scripts/declarations/lint/index.mocha.js';
|
|
13
|
+
const LINT_PATH = path.resolve(__dirname, LINT_TEST_FILEPATH);
|
|
14
|
+
|
|
15
|
+
// Mocha catches unhandled rejection from the user code and re-emits them to the process (see https://github.com/mochajs/mocha/blob/master/lib/runner.js#L198)
|
|
16
|
+
process.on('unhandledRejection', reason => {
|
|
17
|
+
// Re-throw them so that the validation command fails in these cases (for example, if there is a syntax error when parsing JSON declaration files)
|
|
18
|
+
throw reason;
|
|
19
|
+
});
|
|
20
|
+
|
|
11
21
|
program
|
|
12
22
|
.name('ota lint')
|
|
13
23
|
.description('Check format and stylistic errors in declarations and auto fix them')
|
|
14
24
|
.option('-s, --services [serviceId...]', 'service IDs of services to lint')
|
|
15
|
-
.option('-m, --modified', 'to only lint modified services already commited to git')
|
|
25
|
+
.option('-m, --modified', 'to only lint modified services already commited to git')
|
|
26
|
+
.option('-f, --fix', 'to fix the declarations');
|
|
27
|
+
|
|
28
|
+
const mocha = new Mocha({
|
|
29
|
+
delay: true, // as the validation script performs an asynchronous load before running the tests, the execution of the tests are delayed until run() is called
|
|
30
|
+
failZero: true, // consider that being called with no service to validate is a failure
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
(async () => {
|
|
34
|
+
mocha.addFile(LINT_PATH); // As `delay` has been called, this statement will not load the file directly, `loadFilesAsync` is required.
|
|
35
|
+
await mocha.loadFilesAsync() // Load files previously added to the Mocha cache with `addFile`.
|
|
36
|
+
.catch(error => {
|
|
37
|
+
console.error(error);
|
|
38
|
+
process.exit(2);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
let hasFailedTests = false;
|
|
42
|
+
|
|
43
|
+
const lintFiles = (await import(LINT_TEST_FILEPATH)).default;
|
|
44
|
+
|
|
45
|
+
lintFiles(program.parse().opts());
|
|
16
46
|
|
|
17
|
-
|
|
47
|
+
mocha.run()
|
|
48
|
+
.on('fail', () => { hasFailedTests = true; })
|
|
49
|
+
.on('end', () => {
|
|
50
|
+
if (hasFailedTests) {
|
|
51
|
+
process.exit(1);
|
|
52
|
+
}
|
|
18
53
|
|
|
19
|
-
|
|
54
|
+
process.exit(0);
|
|
55
|
+
});
|
|
56
|
+
})();
|
package/bin/ota-validate.js
CHANGED
|
@@ -9,7 +9,8 @@ import Mocha from 'mocha';
|
|
|
9
9
|
|
|
10
10
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
11
11
|
|
|
12
|
-
const
|
|
12
|
+
const VALIDATE_TEST_FILEPATH = '../scripts/declarations/validate/index.mocha.js';
|
|
13
|
+
const VALIDATE_PATH = path.resolve(__dirname, VALIDATE_TEST_FILEPATH);
|
|
13
14
|
|
|
14
15
|
// Mocha catches unhandled rejection from the user code and re-emits them to the process (see https://github.com/mochajs/mocha/blob/master/lib/runner.js#L198)
|
|
15
16
|
process.on('unhandledRejection', reason => {
|
|
@@ -40,7 +41,7 @@ const mocha = new Mocha({
|
|
|
40
41
|
|
|
41
42
|
let hasFailedTests = false;
|
|
42
43
|
|
|
43
|
-
const generateValidationTestSuite = (await import(
|
|
44
|
+
const generateValidationTestSuite = (await import(VALIDATE_TEST_FILEPATH)).default;
|
|
44
45
|
|
|
45
46
|
generateValidationTestSuite(program.parse().opts());
|
|
46
47
|
|
package/package.json
CHANGED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import fsApi from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
4
|
+
|
|
5
|
+
import { expect } from 'chai';
|
|
6
|
+
import config from 'config';
|
|
7
|
+
import { ESLint } from 'eslint';
|
|
8
|
+
|
|
9
|
+
import * as services from '../../../src/archivist/services/index.js';
|
|
10
|
+
import DeclarationUtils from '../utils/index.js';
|
|
11
|
+
|
|
12
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
13
|
+
const ROOT_PATH = path.resolve(__dirname, '../../../');
|
|
14
|
+
const ESLINT_CONFIG_PATH = path.join(ROOT_PATH, '.eslintrc.yaml');
|
|
15
|
+
|
|
16
|
+
const eslint = new ESLint({ overrideConfigFile: ESLINT_CONFIG_PATH, fix: false });
|
|
17
|
+
const eslintWithFix = new ESLint({ overrideConfigFile: ESLINT_CONFIG_PATH, fix: true });
|
|
18
|
+
|
|
19
|
+
const declarationsPath = path.resolve(process.cwd(), config.get('services.declarationsPath'));
|
|
20
|
+
const instancePath = path.resolve(declarationsPath, '../');
|
|
21
|
+
|
|
22
|
+
export default async options => {
|
|
23
|
+
let servicesToValidate = options.services || [];
|
|
24
|
+
|
|
25
|
+
const serviceDeclarations = await services.loadWithHistory(servicesToValidate);
|
|
26
|
+
|
|
27
|
+
if (!servicesToValidate.length) {
|
|
28
|
+
servicesToValidate = Object.keys(serviceDeclarations);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (options.modified) {
|
|
32
|
+
const declarationUtils = new DeclarationUtils(instancePath);
|
|
33
|
+
|
|
34
|
+
({ services: servicesToValidate } = await declarationUtils.getModifiedServiceDocumentTypes());
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const lintFile = lintAndFixFile(options.fix);
|
|
38
|
+
|
|
39
|
+
describe('Service declarations lint validation', async function () {
|
|
40
|
+
this.timeout(30000);
|
|
41
|
+
|
|
42
|
+
servicesToValidate.forEach(serviceId => {
|
|
43
|
+
const service = serviceDeclarations[serviceId];
|
|
44
|
+
const filePath = path.join(declarationsPath, `${serviceId}.json`);
|
|
45
|
+
const historyFilePath = path.join(declarationsPath, `${serviceId}.history.json`);
|
|
46
|
+
const filtersFilePath = path.join(declarationsPath, `${serviceId}.filters.js`);
|
|
47
|
+
const filtersHistoryFilePath = path.join(declarationsPath, `${serviceId}.filters.history.js`);
|
|
48
|
+
|
|
49
|
+
context(serviceId, async () => {
|
|
50
|
+
before(async function () {
|
|
51
|
+
if (!service) {
|
|
52
|
+
console.log(' (Tests skipped as declaration has been archived)');
|
|
53
|
+
this.skip();
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it('valid declaration file lint', async () => {
|
|
58
|
+
await lintFile(filePath);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
if (service && service.hasHistory()) {
|
|
62
|
+
it('valid history declaration file lint', async () => {
|
|
63
|
+
await lintFile(historyFilePath);
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (fsApi.existsSync(filtersFilePath)) {
|
|
68
|
+
it('valid filters file lint', async () => {
|
|
69
|
+
await lintFile(filtersFilePath);
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (fsApi.existsSync(filtersHistoryFilePath)) {
|
|
74
|
+
it('valid filters history file lint', async () => {
|
|
75
|
+
await lintFile(filtersHistoryFilePath);
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
run();
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
const lintAndFixFile = fix => async filePath => {
|
|
86
|
+
// Create a new instance of linter with option `fix` set to true to get a fixed output.
|
|
87
|
+
// It is not possible to use only a linter with this option enabled because when
|
|
88
|
+
// this option is set, if it can fix errors, it considers that there are no errors and returns `0` for the `errorCount`.
|
|
89
|
+
// So use two linters to have access both to `errorCount` and fix `output` variables.
|
|
90
|
+
const [lintResult] = await eslint.lintFiles(filePath);
|
|
91
|
+
|
|
92
|
+
if (!lintResult.errorCount) {
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const [lintResultFixed] = await eslintWithFix.lintFiles(filePath);
|
|
97
|
+
|
|
98
|
+
if (fix) {
|
|
99
|
+
await ESLint.outputFixes([lintResultFixed]);
|
|
100
|
+
|
|
101
|
+
return lintAndFixFile(false)(filePath);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
expect(lintResult.source).to.equal(lintResultFixed.output, `${path.basename(filePath)} is not properly formatted. Use the lint script to format it correctly.\n`);
|
|
105
|
+
};
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import fsApi from 'fs';
|
|
2
2
|
import path from 'path';
|
|
3
|
-
import { fileURLToPath } from 'url';
|
|
4
3
|
|
|
5
4
|
import Ajv from 'ajv';
|
|
6
5
|
import { expect } from 'chai';
|
|
7
6
|
import config from 'config';
|
|
8
|
-
import { ESLint } from 'eslint';
|
|
9
7
|
import jsonSourceMap from 'json-source-map';
|
|
10
8
|
|
|
11
9
|
import fetch, { launchHeadlessBrowser, stopHeadlessBrowser } from '../../../src/archivist/fetcher/index.js';
|
|
@@ -18,16 +16,9 @@ import serviceSchema from './service.schema.js';
|
|
|
18
16
|
|
|
19
17
|
const fs = fsApi.promises;
|
|
20
18
|
|
|
21
|
-
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
22
|
-
const ROOT_PATH = path.resolve(__dirname, '../../../');
|
|
23
|
-
const ESLINT_CONFIG_PATH = path.join(ROOT_PATH, '.eslintrc.yaml');
|
|
24
|
-
|
|
25
19
|
const MIN_DOC_LENGTH = 100;
|
|
26
20
|
const SLOW_DOCUMENT_THRESHOLD = 10 * 1000; // number of milliseconds after which a document fetch is considered slow
|
|
27
21
|
|
|
28
|
-
const eslint = new ESLint({ overrideConfigFile: ESLINT_CONFIG_PATH, fix: false });
|
|
29
|
-
const eslintWithFix = new ESLint({ overrideConfigFile: ESLINT_CONFIG_PATH, fix: true });
|
|
30
|
-
|
|
31
22
|
const declarationsPath = path.resolve(process.cwd(), config.get('services.declarationsPath'));
|
|
32
23
|
const instancePath = path.resolve(declarationsPath, '../');
|
|
33
24
|
|
|
@@ -76,36 +67,12 @@ export default async options => {
|
|
|
76
67
|
assertValid(serviceSchema, declaration);
|
|
77
68
|
});
|
|
78
69
|
|
|
79
|
-
it('valid declaration file format', async () => {
|
|
80
|
-
await lintFile(filePath);
|
|
81
|
-
});
|
|
82
|
-
|
|
83
70
|
if (service && service.hasHistory()) {
|
|
84
71
|
it('valid history declaration schema', async () => {
|
|
85
72
|
const declarationHistory = JSON.parse(await fs.readFile(historyFilePath));
|
|
86
73
|
|
|
87
74
|
assertValid(serviceHistorySchema, declarationHistory);
|
|
88
75
|
});
|
|
89
|
-
|
|
90
|
-
it('valid history declaration file format', async () => {
|
|
91
|
-
await lintFile(path.join(declarationsPath, `${serviceId}.history.json`));
|
|
92
|
-
});
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
const filtersFilePath = path.join(declarationsPath, `${serviceId}.filters.js`);
|
|
96
|
-
|
|
97
|
-
if (fsApi.existsSync(filtersFilePath)) {
|
|
98
|
-
it('valid filters file format', async () => {
|
|
99
|
-
await lintFile(filtersFilePath);
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
const filtersHistoryFilePath = path.join(declarationsPath, `${serviceId}.filters.history.js`);
|
|
104
|
-
|
|
105
|
-
if (fsApi.existsSync(filtersHistoryFilePath)) {
|
|
106
|
-
it('valid filters history file format', async () => {
|
|
107
|
-
await lintFile(filtersHistoryFilePath);
|
|
108
|
-
});
|
|
109
76
|
}
|
|
110
77
|
|
|
111
78
|
if (!schemaOnly && service) {
|
|
@@ -245,18 +212,3 @@ function assertValid(schema, subject) {
|
|
|
245
212
|
throw new Error(errorMessage);
|
|
246
213
|
}
|
|
247
214
|
}
|
|
248
|
-
|
|
249
|
-
async function lintFile(filePath) {
|
|
250
|
-
const [lintResult] = await eslint.lintFiles(filePath);
|
|
251
|
-
|
|
252
|
-
if (!lintResult.errorCount) {
|
|
253
|
-
return;
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
// Create a new instance of linter with option `fix` set to true to get a fixed output.
|
|
257
|
-
// It is not possible to use only a linter with this option enabled because when this option is set, if it can fix errors, it considers that there are no errors and returns `0` for the `errorCount`.
|
|
258
|
-
// So use two linters to have access both to `errorCount` and fix `output` variables.
|
|
259
|
-
const [lintResultFixed] = await eslintWithFix.lintFiles(filePath);
|
|
260
|
-
|
|
261
|
-
expect(lintResult.source).to.equal(lintResultFixed.output, `${path.basename(filePath)} is not properly formatted. Use the lint script to format it correctly.\n`);
|
|
262
|
-
}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import path from 'path';
|
|
2
|
-
import { fileURLToPath } from 'url';
|
|
3
|
-
|
|
4
|
-
import config from 'config';
|
|
5
|
-
import { ESLint } from 'eslint';
|
|
6
|
-
|
|
7
|
-
import DeclarationUtils from '../utils/index.js';
|
|
8
|
-
|
|
9
|
-
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
10
|
-
|
|
11
|
-
const declarationsPath = config.get('services.declarationsPath');
|
|
12
|
-
const instancePath = path.resolve(declarationsPath, '../');
|
|
13
|
-
const ESLINT_CONFIG_PATH = path.join(__dirname, '../../../.eslintrc.yaml');
|
|
14
|
-
|
|
15
|
-
const lintDeclarations = async ({ services, modified }) => {
|
|
16
|
-
console.log(`Linting declaration files in ${instancePath}`);
|
|
17
|
-
let servicesToValidate = services || ['*'];
|
|
18
|
-
|
|
19
|
-
if (modified) {
|
|
20
|
-
const declarationUtils = new DeclarationUtils(instancePath);
|
|
21
|
-
|
|
22
|
-
servicesToValidate = await declarationUtils.getModifiedServices();
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
for (const service of servicesToValidate) {
|
|
26
|
-
/* eslint-disable no-await-in-loop */
|
|
27
|
-
const lintResults = await new ESLint({ overrideConfigFile: ESLINT_CONFIG_PATH, fix: true })
|
|
28
|
-
.lintFiles(path.join(declarationsPath, `${service}.*`));
|
|
29
|
-
|
|
30
|
-
await ESLint.outputFixes(lintResults);
|
|
31
|
-
console.log(lintResults.map(lintResult => `${path.basename(lintResult.filePath)} linted`).join('\n'));
|
|
32
|
-
/* eslint-enable no-await-in-loop */
|
|
33
|
-
}
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
export default lintDeclarations;
|