Skip to content

Commit b175b46

Browse files
bmishnot-an-aardvark
authored andcommitted
Update: Add new rule require-meta-docs-description (#89)
* feat: add new rule `require-meta-docs-description` The eslint core plugin has an internal lint rule to enforce this same thing: https://github.com/eslint/eslint/blob/master/tools/internal-rules/consistent-docs-description.js * docs: update rule descriptions to begin with consistent prefixes
1 parent 8c74f24 commit b175b46

15 files changed

+307
-22
lines changed

README.md

+12-11
Original file line numberDiff line numberDiff line change
@@ -49,25 +49,26 @@ Then configure the rules you want to use under the rules section.
4949
<!-- __BEGIN AUTOGENERATED TABLE__ -->
5050
Name | ✔️ | 🛠 | Description
5151
----- | ----- | ----- | -----
52-
[consistent-output](https://github.com/not-an-aardvark/eslint-plugin-eslint-plugin/blob/master/docs/rules/consistent-output.md) | | | Enforce consistent use of output assertions in rule tests
53-
[fixer-return](https://github.com/not-an-aardvark/eslint-plugin-eslint-plugin/blob/master/docs/rules/fixer-return.md) | ✔️ | | Expected fixer function to always return a value.
54-
[meta-property-ordering](https://github.com/not-an-aardvark/eslint-plugin-eslint-plugin/blob/master/docs/rules/meta-property-ordering.md) | | 🛠 | Enforces the order of meta properties
55-
[no-deprecated-context-methods](https://github.com/not-an-aardvark/eslint-plugin-eslint-plugin/blob/master/docs/rules/no-deprecated-context-methods.md) | | 🛠 | Disallows usage of deprecated methods on rule context objects
52+
[consistent-output](https://github.com/not-an-aardvark/eslint-plugin-eslint-plugin/blob/master/docs/rules/consistent-output.md) | | | enforce consistent use of output assertions in rule tests
53+
[fixer-return](https://github.com/not-an-aardvark/eslint-plugin-eslint-plugin/blob/master/docs/rules/fixer-return.md) | ✔️ | | require fixer function to always return a value.
54+
[meta-property-ordering](https://github.com/not-an-aardvark/eslint-plugin-eslint-plugin/blob/master/docs/rules/meta-property-ordering.md) | | 🛠 | enforce the order of meta properties
55+
[no-deprecated-context-methods](https://github.com/not-an-aardvark/eslint-plugin-eslint-plugin/blob/master/docs/rules/no-deprecated-context-methods.md) | | 🛠 | disallow usage of deprecated methods on rule context objects
5656
[no-deprecated-report-api](https://github.com/not-an-aardvark/eslint-plugin-eslint-plugin/blob/master/docs/rules/no-deprecated-report-api.md) | ✔️ | 🛠 | disallow use of the deprecated context.report() API
5757
[no-identical-tests](https://github.com/not-an-aardvark/eslint-plugin-eslint-plugin/blob/master/docs/rules/no-identical-tests.md) | ✔️ | 🛠 | disallow identical tests
58-
[no-missing-placeholders](https://github.com/not-an-aardvark/eslint-plugin-eslint-plugin/blob/master/docs/rules/no-missing-placeholders.md) | ✔️ | | Disallow missing placeholders in rule report messages
59-
[no-unused-placeholders](https://github.com/not-an-aardvark/eslint-plugin-eslint-plugin/blob/master/docs/rules/no-unused-placeholders.md) | ✔️ | | Disallow unused placeholders in rule report messages
60-
[no-useless-token-range](https://github.com/not-an-aardvark/eslint-plugin-eslint-plugin/blob/master/docs/rules/no-useless-token-range.md) | ✔️ | 🛠 | Disallow unnecessary calls to sourceCode.getFirstToken and sourceCode.getLastToken
61-
[prefer-output-null](https://github.com/not-an-aardvark/eslint-plugin-eslint-plugin/blob/master/docs/rules/prefer-output-null.md) | | 🛠 | disallows invalid RuleTester test cases with the output the same as the code.
58+
[no-missing-placeholders](https://github.com/not-an-aardvark/eslint-plugin-eslint-plugin/blob/master/docs/rules/no-missing-placeholders.md) | ✔️ | | disallow missing placeholders in rule report messages
59+
[no-unused-placeholders](https://github.com/not-an-aardvark/eslint-plugin-eslint-plugin/blob/master/docs/rules/no-unused-placeholders.md) | ✔️ | | disallow unused placeholders in rule report messages
60+
[no-useless-token-range](https://github.com/not-an-aardvark/eslint-plugin-eslint-plugin/blob/master/docs/rules/no-useless-token-range.md) | ✔️ | 🛠 | disallow unnecessary calls to sourceCode.getFirstToken and sourceCode.getLastToken
61+
[prefer-output-null](https://github.com/not-an-aardvark/eslint-plugin-eslint-plugin/blob/master/docs/rules/prefer-output-null.md) | | 🛠 | disallow invalid RuleTester test cases with the output the same as the code.
6262
[prefer-placeholders](https://github.com/not-an-aardvark/eslint-plugin-eslint-plugin/blob/master/docs/rules/prefer-placeholders.md) | | | disallow template literals as report messages
63-
[prefer-replace-text](https://github.com/not-an-aardvark/eslint-plugin-eslint-plugin/blob/master/docs/rules/prefer-replace-text.md) | | | prefer using replaceText instead of replaceTextRange.
63+
[prefer-replace-text](https://github.com/not-an-aardvark/eslint-plugin-eslint-plugin/blob/master/docs/rules/prefer-replace-text.md) | | | require using replaceText instead of replaceTextRange.
6464
[report-message-format](https://github.com/not-an-aardvark/eslint-plugin-eslint-plugin/blob/master/docs/rules/report-message-format.md) | | | enforce a consistent format for rule report messages
65+
[require-meta-docs-description](https://github.com/not-an-aardvark/eslint-plugin-eslint-plugin/blob/master/docs/rules/require-meta-docs-description.md) | | | require rules to implement a meta.docs.description property with the correct format
6566
[require-meta-docs-url](https://github.com/not-an-aardvark/eslint-plugin-eslint-plugin/blob/master/docs/rules/require-meta-docs-url.md) | | 🛠 | require rules to implement a meta.docs.url property
6667
[require-meta-fixable](https://github.com/not-an-aardvark/eslint-plugin-eslint-plugin/blob/master/docs/rules/require-meta-fixable.md) | ✔️ | | require rules to implement a meta.fixable property
6768
[require-meta-schema](https://github.com/not-an-aardvark/eslint-plugin-eslint-plugin/blob/master/docs/rules/require-meta-schema.md) | | 🛠 | require rules to implement a meta.schema property
6869
[require-meta-type](https://github.com/not-an-aardvark/eslint-plugin-eslint-plugin/blob/master/docs/rules/require-meta-type.md) | | | require rules to implement a meta.type property
69-
[test-case-property-ordering](https://github.com/not-an-aardvark/eslint-plugin-eslint-plugin/blob/master/docs/rules/test-case-property-ordering.md) | | 🛠 | Requires the properties of a test case to be placed in a consistent order
70-
[test-case-shorthand-strings](https://github.com/not-an-aardvark/eslint-plugin-eslint-plugin/blob/master/docs/rules/test-case-shorthand-strings.md) | | 🛠 | Enforce consistent usage of shorthand strings for test cases with no options
70+
[test-case-property-ordering](https://github.com/not-an-aardvark/eslint-plugin-eslint-plugin/blob/master/docs/rules/test-case-property-ordering.md) | | 🛠 | require the properties of a test case to be placed in a consistent order
71+
[test-case-shorthand-strings](https://github.com/not-an-aardvark/eslint-plugin-eslint-plugin/blob/master/docs/rules/test-case-shorthand-strings.md) | | 🛠 | enforce consistent usage of shorthand strings for test cases with no options
7172
<!-- __END AUTOGENERATED TABLE__ -->
7273

7374
## Supported Presets
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# require rules to implement a meta.docs.description property (require-meta-docs-description)
2+
3+
Defining a clear and consistent description for each rule helps developers understand what they're used for.
4+
5+
In particular, each rule description should begin with an allowed prefix:
6+
* `enforce`
7+
* `require`
8+
* `disallow`
9+
10+
## Rule Details
11+
12+
This rule requires ESLint rules to have a valid `meta.docs.description` property.
13+
14+
Examples of **incorrect** code for this rule:
15+
16+
```js
17+
/* eslint eslint-plugin/require-meta-docs-description: error */
18+
module.exports = {
19+
meta: {},
20+
create: function(context) { /* ... */}
21+
};
22+
23+
module.exports = {
24+
meta: { description: 'this rule does ...' }, // missing allowed prefix
25+
create: function(context) { /* ... */}
26+
};
27+
```
28+
29+
Examples of **correct** code for this rule:
30+
31+
```js
32+
/* eslint eslint-plugin/require-meta-docs-description: error */
33+
module.exports = {
34+
meta: { description: 'disallow unused variables' },
35+
create: function(context) { /* ... */}
36+
};
37+
```
38+
39+
## Options
40+
41+
This rule takes an optional object containing:
42+
43+
- `String``pattern` — A regular expression that the description must match. Use `'.+'` to allow anything. Defaults to `^(enforce|require|disallow)`.
44+
45+
## Further Reading
46+
47+
* [working-with-rules#options-schemas](https://eslint.org/docs/developer-guide/working-with-rules#options-schemas)

lib/rules/consistent-output.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ const utils = require('../utils');
1414
module.exports = {
1515
meta: {
1616
docs: {
17-
description: 'Enforce consistent use of output assertions in rule tests',
17+
description: 'enforce consistent use of output assertions in rule tests',
1818
category: 'Tests',
1919
recommended: false,
2020
},

lib/rules/fixer-return.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ const utils = require('../utils');
1818
module.exports = {
1919
meta: {
2020
docs: {
21-
description: 'Expected fixer function to always return a value.',
21+
description: 'require fixer function to always return a value.',
2222
category: 'Possible Errors',
2323
recommended: true,
2424
},

lib/rules/meta-property-ordering.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ const { getKeyName, getRuleInfo } = require('../utils');
1313
module.exports = {
1414
meta: {
1515
docs: {
16-
description: 'Enforces the order of meta properties',
16+
description: 'enforce the order of meta properties',
1717
category: 'Rules',
1818
recommended: false,
1919
},

lib/rules/no-deprecated-context-methods.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ const DEPRECATED_PASSTHROUGHS = {
3737
module.exports = {
3838
meta: {
3939
docs: {
40-
description: 'Disallows usage of deprecated methods on rule context objects',
40+
description: 'disallow usage of deprecated methods on rule context objects',
4141
category: 'Rules',
4242
recommended: false,
4343
},

lib/rules/no-missing-placeholders.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ const utils = require('../utils');
1414
module.exports = {
1515
meta: {
1616
docs: {
17-
description: 'Disallow missing placeholders in rule report messages',
17+
description: 'disallow missing placeholders in rule report messages',
1818
category: 'Rules',
1919
recommended: true,
2020
},

lib/rules/no-unused-placeholders.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ const utils = require('../utils');
1414
module.exports = {
1515
meta: {
1616
docs: {
17-
description: 'Disallow unused placeholders in rule report messages',
17+
description: 'disallow unused placeholders in rule report messages',
1818
category: 'Rules',
1919
recommended: true,
2020
},

lib/rules/no-useless-token-range.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ const utils = require('../utils');
1414
module.exports = {
1515
meta: {
1616
docs: {
17-
description: 'Disallow unnecessary calls to sourceCode.getFirstToken and sourceCode.getLastToken',
17+
description: 'disallow unnecessary calls to sourceCode.getFirstToken and sourceCode.getLastToken',
1818
category: 'Rules',
1919
recommended: true,
2020
},

lib/rules/prefer-output-null.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ const utils = require('../utils');
1414
module.exports = {
1515
meta: {
1616
docs: {
17-
description: 'disallows invalid RuleTester test cases with the output the same as the code.',
17+
description: 'disallow invalid RuleTester test cases with the output the same as the code.',
1818
category: 'Tests',
1919
recommended: false,
2020
},

lib/rules/prefer-replace-text.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ const utils = require('../utils');
1414
module.exports = {
1515
meta: {
1616
docs: {
17-
description: 'prefer using replaceText instead of replaceTextRange.',
17+
description: 'require using replaceText instead of replaceTextRange.',
1818
category: 'Rules',
1919
recommended: false,
2020
},
+87
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
'use strict';
2+
3+
const utils = require('../utils');
4+
5+
// ------------------------------------------------------------------------------
6+
// Rule Definition
7+
// ------------------------------------------------------------------------------
8+
9+
const DEFAULT_PATTERN = new RegExp('^(enforce|require|disallow)');
10+
11+
/**
12+
* Whether or not the node is a string literal
13+
*
14+
* @param {object} node
15+
* @returns {boolean} whether or not the node is a string literal
16+
*/
17+
function isStringLiteral (node) {
18+
return node.type === 'Literal' && typeof node.value === 'string';
19+
}
20+
21+
module.exports = {
22+
meta: {
23+
docs: {
24+
description: 'require rules to implement a meta.docs.description property with the correct format',
25+
category: 'Rules',
26+
recommended: false, // TODO: enable it in a major release.
27+
},
28+
type: 'suggestion',
29+
fixable: null,
30+
schema: [
31+
{
32+
type: 'object',
33+
properties: {
34+
pattern: {
35+
type: 'string',
36+
},
37+
},
38+
additionalProperties: false,
39+
},
40+
],
41+
messages: {
42+
missing: '`meta.docs.description` is required.',
43+
wrongType: '`meta.docs.description` must be a non-empty string.',
44+
extraWhitespace: '`meta.docs.description` must not have leading nor trailing whitespace.',
45+
},
46+
},
47+
48+
create (context) {
49+
const sourceCode = context.getSourceCode();
50+
const info = utils.getRuleInfo(sourceCode.ast, sourceCode.scopeManager);
51+
52+
return {
53+
Program () {
54+
if (info === null || info.meta === null) {
55+
return;
56+
}
57+
58+
const pattern = context.options[0] && context.options[0].pattern ? new RegExp(context.options[0].pattern) : DEFAULT_PATTERN;
59+
60+
const metaNode = info.meta;
61+
const docsNode =
62+
metaNode &&
63+
metaNode.properties &&
64+
metaNode.properties.find(p => p.type === 'Property' && utils.getKeyName(p) === 'docs');
65+
66+
const descriptionNode =
67+
docsNode &&
68+
docsNode.value.properties &&
69+
docsNode.value.properties.find(p => p.type === 'Property' && utils.getKeyName(p) === 'description');
70+
71+
if (!descriptionNode) {
72+
context.report({ node: docsNode ? docsNode : metaNode, messageId: 'missing' });
73+
} else if (!isStringLiteral(descriptionNode.value) || descriptionNode.value.value === '') {
74+
context.report({ node: descriptionNode.value, messageId: 'wrongType' });
75+
} else if (descriptionNode.value.value !== descriptionNode.value.value.trim()) {
76+
context.report({ node: descriptionNode.value, messageId: 'extraWhitespace' });
77+
} else if (!pattern.test(descriptionNode.value.value)) {
78+
context.report({
79+
node: descriptionNode.value,
80+
message: '`meta.docs.description` must match the regexp {{pattern}}.',
81+
data: { pattern },
82+
});
83+
}
84+
},
85+
};
86+
},
87+
};

lib/rules/test-case-property-ordering.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ const utils = require('../utils');
1414
module.exports = {
1515
meta: {
1616
docs: {
17-
description: 'Requires the properties of a test case to be placed in a consistent order',
17+
description: 'require the properties of a test case to be placed in a consistent order',
1818
category: 'Tests',
1919
recommended: false,
2020
},

lib/rules/test-case-shorthand-strings.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ const utils = require('../utils');
1414
module.exports = {
1515
meta: {
1616
docs: {
17-
description: 'Enforce consistent usage of shorthand strings for test cases with no options',
17+
description: 'enforce consistent usage of shorthand strings for test cases with no options',
1818
category: 'Tests',
1919
recommended: false,
2020
},

0 commit comments

Comments
 (0)