-
-
Notifications
You must be signed in to change notification settings - Fork 26
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add require-meta-docs-recommended rule (#447)
* feat: add require-meta-docs-recommended rule * Apply suggestions from code review Co-authored-by: Bryan Mishkin <[email protected]> * Apply rename * Fix lint complaints * Added allowNonBoolean opt-in option * Unit test for unknown value --------- Co-authored-by: Bryan Mishkin <[email protected]>
- Loading branch information
1 parent
95b1980
commit 2370b46
Showing
9 changed files
with
397 additions
and
44 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
# Require rules to implement a `meta.docs.recommended` property (`eslint-plugin/require-meta-docs-recommended`) | ||
|
||
<!-- end auto-generated rule header --> | ||
|
||
Utilizing `meta.docs.recommended` makes it clear from each rule implementation whether a rule is part of the `recommended` config. Some plugins also have scripting for conveniently generating their config based on this flag. | ||
|
||
However, this flag may not be appropriate for all plugins: | ||
|
||
- Extra scripting/tooling is needed to keep the flags in sync with the config | ||
- The flag may not scale to plugins that have multiple/many configs or don't have a recommended config | ||
- Or some may simply prefer to keep the source of truth solely in the config rather than duplicating config membership data in the rules | ||
|
||
By default, this rule enforces a `recommended` property be set to a `boolean` value. | ||
|
||
## Rule Details | ||
|
||
This rule requires ESLint rules to have a valid `meta.docs.recommended` property. | ||
|
||
Examples of **incorrect** code for this rule: | ||
|
||
```js | ||
/* eslint eslint-plugin/require-meta-docs-recommended: error */ | ||
|
||
module.exports = { | ||
meta: {}, | ||
create(context) { | ||
/* ... */ | ||
}, | ||
}; | ||
``` | ||
|
||
Examples of **correct** code for this rule: | ||
|
||
```js | ||
/* eslint eslint-plugin/require-meta-docs-recommended: error */ | ||
|
||
module.exports = { | ||
meta: { recommended: true }, | ||
create(context) { | ||
/* ... */ | ||
}, | ||
}; | ||
``` | ||
|
||
## Options | ||
|
||
<!-- begin auto-generated rule options list --> | ||
|
||
| Name | Description | Type | Default | | ||
| :---------------- | :--------------------------------------------------- | :------ | :------ | | ||
| `allowNonBoolean` | Whether to allow values of types other than boolean. | Boolean | `false` | | ||
|
||
<!-- end auto-generated rule options list --> | ||
|
||
### `allowNonBoolean` | ||
|
||
Some plugins require `meta.docs.recommended` values but allow value types other than `boolean`. | ||
This option changes the rule to only enforce that the values exist. | ||
|
||
Example of **correct** code for this rule with `allowNonBoolean`: | ||
|
||
```js | ||
/* eslint eslint-plugin/require-meta-docs-recommended: ["error", { "allowNonBoolean": true }] */ | ||
|
||
module.exports = { | ||
meta: { recommended: 'strict' }, | ||
create(context) { | ||
/* ... */ | ||
}, | ||
}; | ||
``` | ||
|
||
## Further Reading | ||
|
||
- [Rule Structure](https://eslint.org/docs/latest/extend/custom-rules#rule-structure) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
'use strict'; | ||
|
||
const { getStaticValue } = require('eslint-utils'); | ||
const utils = require('../utils'); | ||
|
||
/** @type {import('eslint').Rule.RuleModule} */ | ||
module.exports = { | ||
meta: { | ||
type: 'suggestion', | ||
docs: { | ||
description: | ||
'require rules to implement a `meta.docs.recommended` property', | ||
category: 'Rules', | ||
recommended: false, | ||
url: 'https://github.com/eslint-community/eslint-plugin-eslint-plugin/tree/HEAD/docs/rules/require-meta-docs-recommended.md', | ||
}, | ||
fixable: null, | ||
schema: [ | ||
{ | ||
type: 'object', | ||
properties: { | ||
allowNonBoolean: { | ||
default: false, | ||
description: 'Whether to allow values of types other than boolean.', | ||
type: 'boolean', | ||
}, | ||
}, | ||
additionalProperties: false, | ||
}, | ||
], | ||
messages: { | ||
incorrect: '`meta.docs.recommended` is required to be a boolean.', | ||
missing: '`meta.docs.recommended` is required.', | ||
}, | ||
}, | ||
|
||
create(context) { | ||
const sourceCode = context.sourceCode || context.getSourceCode(); // TODO: just use context.sourceCode when dropping eslint < v9 | ||
const ruleInfo = utils.getRuleInfo(sourceCode); | ||
if (!ruleInfo) { | ||
return {}; | ||
} | ||
|
||
const { scopeManager } = sourceCode; | ||
const { | ||
docsNode, | ||
metaNode, | ||
metaPropertyNode: descriptionNode, | ||
} = utils.getMetaDocsProperty('recommended', ruleInfo, scopeManager); | ||
|
||
if (!descriptionNode) { | ||
context.report({ | ||
node: docsNode || metaNode || ruleInfo.create, | ||
messageId: 'missing', | ||
}); | ||
return {}; | ||
} | ||
|
||
if (context.options[0]?.allowNonBoolean) { | ||
return {}; | ||
} | ||
|
||
const staticValue = utils.isUndefinedIdentifier(descriptionNode.value) | ||
? { value: undefined } | ||
: getStaticValue(descriptionNode.value); | ||
|
||
if (staticValue && typeof staticValue.value !== 'boolean') { | ||
context.report({ | ||
node: descriptionNode.value, | ||
messageId: 'incorrect', | ||
}); | ||
return {}; | ||
} | ||
|
||
return {}; | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.