Skip to content

Commit 6f1f049

Browse files
author
Kelly Selden
committed
add ensure-volta-extends rule
Check that the volta/extends file exists and has a volta config.
1 parent 96d1ce1 commit 6f1f049

File tree

7 files changed

+195
-0
lines changed

7 files changed

+195
-0
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ eslint . --ext js,json
5454
| Rule ID | Description |
5555
|:--------|:------------|
5656
| [json-files/ensure-repository-directory](./docs/rules/ensure-repository-directory.md) | ensure repository/directory in package.json |
57+
| [json-files/ensure-volta-extends](./docs/rules/ensure-volta-extends.md) | ensure volta-extends in package.json |
5758
| [json-files/eol-last](./docs/rules/eol-last.md) | require or disallow newline at the end of package.json |
5859
| [json-files/no-branch-in-dependencies](./docs/rules/no-branch-in-dependencies.md) | prevent branches in package.json dependencies |
5960
| [json-files/require-engines](./docs/rules/require-engines.md) | require the engines field in package.json |

docs/rules/ensure-volta-extends.md

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# Ensure volta/extends in package.json (ensure-repository-directory)
2+
3+
Check that the volta/extends file exists and has a volta config.
4+
5+
6+
## Rule Details
7+
8+
This rule aims to ensure the volta/extends file exists and has a volta config.
9+
10+
Examples of **incorrect** code for this rule:
11+
12+
```json
13+
{
14+
"volta": {
15+
"extends": "wrong-package/bad-copy-paste"
16+
}
17+
}
18+
```
19+
20+
Examples of **correct** code for this rule:
21+
22+
```json
23+
{
24+
"volta": {
25+
"extends": "correct-path"
26+
}
27+
}
28+
```
29+
30+
```json
31+
{
32+
"volta": {}
33+
}
34+
```
35+
36+
### Options
37+
38+
39+
40+
## When Not To Use It
41+
42+
Extending is optional. If you aren't using it, you may not want this rule.
43+
44+
## Further Reading
45+
46+
https://volta.sh

lib/rules/ensure-volta-extends.js

+87
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
'use strict';
2+
3+
const path = require('path');
4+
const fs = require('fs');
5+
6+
module.exports = {
7+
meta: {
8+
docs: {
9+
description: 'ensure volta/extends in package.json'
10+
},
11+
schema: [
12+
]
13+
},
14+
15+
create(context) {
16+
let filename = context.getFilename();
17+
if (path.basename(filename) !== 'package.json') {
18+
return {};
19+
}
20+
21+
return {
22+
AssignmentExpression(node) {
23+
let json = node.right;
24+
let property = json.properties.find(p => p.key.value === 'volta');
25+
if (!property) {
26+
return;
27+
}
28+
let repository = property.value;
29+
if (repository.type !== 'ObjectExpression') {
30+
return;
31+
}
32+
property = repository.properties.find(p => p.key.value === 'extends');
33+
if (!property) {
34+
return;
35+
}
36+
let _extends = property.value;
37+
if (_extends.type !== 'Literal') {
38+
return;
39+
}
40+
let value = _extends.value;
41+
let dirname = path.dirname(filename);
42+
let filePath = path.resolve(dirname, value);
43+
44+
let text;
45+
46+
try {
47+
text = fs.readFileSync(filePath);
48+
} catch (err) {
49+
if (err.code === 'ENOENT') {
50+
context.report({
51+
node: _extends,
52+
message: `volta/extends '${value}' does not exist.`
53+
});
54+
55+
return;
56+
}
57+
58+
throw err;
59+
}
60+
61+
json;
62+
63+
try {
64+
json = JSON.parse(text);
65+
} catch (err) {
66+
if (err.message === 'Unexpected end of JSON input') {
67+
context.report({
68+
node: _extends,
69+
message: `volta/extends '${value}' is not JSON.`
70+
});
71+
72+
return;
73+
}
74+
75+
throw err;
76+
}
77+
78+
if (!('volta' in json)) {
79+
context.report({
80+
node: _extends,
81+
message: `volta/extends '${value}' does not have a volta config.`
82+
});
83+
}
84+
}
85+
};
86+
}
87+
};

tests/fixtures/volta/no-volta.json

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{}

tests/fixtures/volta/not-json.js

Whitespace-only changes.

tests/fixtures/volta/with-volta.json

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"volta": {}
3+
}
+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
'use strict';
2+
3+
const { RuleTester } = require('eslint');
4+
const rule = require('../../../lib/rules/ensure-volta-extends');
5+
const preprocess = require('../../helpers/preprocess');
6+
const path = require('path');
7+
8+
new RuleTester().run('ensure-volta-extends', rule, preprocess({
9+
valid: [
10+
{
11+
code: '{}',
12+
filename: path.join(__dirname, 'package.json')
13+
},
14+
{
15+
code: '{ "volta": "" }',
16+
filename: path.join(__dirname, 'package.json')
17+
},
18+
{
19+
code: '{ "volta": {} }',
20+
filename: path.join(__dirname, 'package.json')
21+
},
22+
{
23+
code: '{ "volta": { "extends": {} } }',
24+
filename: path.join(__dirname, 'package.json')
25+
},
26+
{
27+
code: '{ "volta": { "extends": "../../fixtures/volta/with-volta.json" } }',
28+
filename: path.join(__dirname, 'package.json')
29+
}
30+
],
31+
invalid: [
32+
{
33+
code: '{ "volta": { "extends": "wrong/dir" } }',
34+
filename: path.join(__dirname, 'package.json'),
35+
errors: [{
36+
message: 'volta/extends \'wrong/dir\' does not exist.',
37+
type: 'Literal'
38+
}]
39+
},
40+
{
41+
code: '{ "volta": { "extends": "../../fixtures/volta/not-json.js" } }',
42+
filename: path.join(__dirname, 'package.json'),
43+
errors: [{
44+
message: 'volta/extends \'../../fixtures/volta/not-json.js\' is not JSON.',
45+
type: 'Literal'
46+
}]
47+
},
48+
{
49+
code: '{ "volta": { "extends": "../../fixtures/volta/no-volta.json" } }',
50+
filename: path.join(__dirname, 'package.json'),
51+
errors: [{
52+
message: 'volta/extends \'../../fixtures/volta/no-volta.json\' does not have a volta config.',
53+
type: 'Literal'
54+
}]
55+
}
56+
]
57+
}));

0 commit comments

Comments
 (0)