Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: eslint-community/eslint-plugin-eslint-plugin
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v3.0.2
Choose a base ref
...
head repository: eslint-community/eslint-plugin-eslint-plugin
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v3.0.3
Choose a head ref
  • 6 commits
  • 14 files changed
  • 3 contributors

Commits on Apr 25, 2021

  1. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    98e893b View commit details

Commits on May 9, 2021

  1. Fix: Improve detection of static description strings and ignore non…

    …-static descriptions in `require-meta-docs-description` rule (#113)
    
    Two changes:
    * Drastically improves detection of the `description` string value when it can be determined statically, including handling when the description is stored in a constant or created through string concatenation
    * If we cannot determine the string value of the `description` statically, then bail out and report no violations, so that users can dynamically generate the description if they'd like to
    bmish authored May 9, 2021

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    1840a53 View commit details

Commits on May 10, 2021

  1. Docs: add npm badge to README (#114)

    Provides a more convenient way to find out what the latest version is as well as link to the package on the NPM site.
    bmish authored May 10, 2021

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    36d16df View commit details
  2. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    ccac2c2 View commit details
  3. Docs: rm global-installed usage (#116)

    it's no longer true for the latest eslint, and global-installed usage is not recommended.
    aladdin-add authored May 10, 2021

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    1f99c7c View commit details
  4. Verified

    This commit was signed with the committer’s verified signature. The key has expired.
    aladdin-add 唯然
    Copy the full SHA
    384f7ba View commit details
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# Changelog

## v3.0.3 (2021-05-10)

* Docs: rm global-installed usage ([#116](git@github.com:not-an-aardvark/eslint-plugin-eslint-plugin/issues/116)) ([1f99c7c](git@github.com:not-an-aardvark/eslint-plugin-eslint-plugin/commit/1f99c7ce827f576ffba8a76fc8d2bee534648f8a))
* Docs: update CI badge for github actions in README ([#115](git@github.com:not-an-aardvark/eslint-plugin-eslint-plugin/issues/115)) ([ccac2c2](git@github.com:not-an-aardvark/eslint-plugin-eslint-plugin/commit/ccac2c2e8b21b18f46f2f409ce9c66f302bbee19))
* Docs: add npm badge to README ([#114](git@github.com:not-an-aardvark/eslint-plugin-eslint-plugin/issues/114)) ([36d16df](git@github.com:not-an-aardvark/eslint-plugin-eslint-plugin/commit/36d16dfc1d408dfcb3ddd0dfbf02007d1c1fb98c))
* Fix: Improve detection of static `description` strings and ignore non-static descriptions in `require-meta-docs-description` rule ([#113](git@github.com:not-an-aardvark/eslint-plugin-eslint-plugin/issues/113)) ([1840a53](git@github.com:not-an-aardvark/eslint-plugin-eslint-plugin/commit/1840a53d98fd602feae20219d37510ecbe30fd74))
* Chore: refactor `utils.getRuleInfo` ([#112](git@github.com:not-an-aardvark/eslint-plugin-eslint-plugin/issues/112)) ([98e893b](git@github.com:not-an-aardvark/eslint-plugin-eslint-plugin/commit/98e893b941ab1e41931a17d141723547a0cad659))

## v3.0.2 (2021-04-16)

* Fix: `require-meta-schema`: Fix false positive ([#111](git@github.com:not-an-aardvark/eslint-plugin-eslint-plugin/issues/111)) ([9f4f461](git@github.com:not-an-aardvark/eslint-plugin-eslint-plugin/commit/9f4f461969b0f89d40219198423b39eea7b63d1e))
4 changes: 1 addition & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# eslint-plugin-eslint-plugin [![Build Status](https://travis-ci.org/not-an-aardvark/eslint-plugin-eslint-plugin.svg?branch=master)](https://travis-ci.org/not-an-aardvark/eslint-plugin-eslint-plugin)
# eslint-plugin-eslint-plugin ![CI](https://github.com/not-an-aardvark/eslint-plugin-eslint-plugin/workflows/CI/badge.svg) [![NPM version](https://img.shields.io/npm/v/eslint-plugin-eslint-plugin.svg?style=flat)](https://npmjs.org/package/eslint-plugin-eslint-plugin)

An ESLint plugin for linting ESLint plugins

@@ -16,8 +16,6 @@ Next, install `eslint-plugin-eslint-plugin`:
$ npm install eslint-plugin-eslint-plugin --save-dev
```

**Note:** If you installed ESLint globally (using the `-g` flag) then you must also install `eslint-plugin-eslint-plugin` globally.

## Usage

Add `eslint-plugin` to the plugins section of your `.eslintrc` configuration file. You can omit the `eslint-plugin-` prefix:
2 changes: 1 addition & 1 deletion lib/rules/meta-property-ordering.js
Original file line number Diff line number Diff line change
@@ -27,7 +27,7 @@ module.exports = {

create (context) {
const sourceCode = context.getSourceCode();
const info = getRuleInfo(sourceCode.ast);
const info = getRuleInfo(sourceCode);

const message = 'The meta properties should be placed in a consistent order: [{{order}}].';
const order = context.options[0] || ['type', 'docs', 'fixable', 'schema', 'messages'];
2 changes: 1 addition & 1 deletion lib/rules/prefer-object-rule.js
Original file line number Diff line number Diff line change
@@ -31,7 +31,7 @@ module.exports = {
// ----------------------------------------------------------------------

const sourceCode = context.getSourceCode();
const ruleInfo = utils.getRuleInfo(sourceCode.ast);
const ruleInfo = utils.getRuleInfo(sourceCode);

return {
Program () {
2 changes: 1 addition & 1 deletion lib/rules/report-message-format.js
Original file line number Diff line number Diff line change
@@ -54,7 +54,7 @@ module.exports = {
return {
Program (node) {
contextIdentifiers = utils.getContextIdentifiers(context, node);
const ruleInfo = utils.getRuleInfo(context.getSourceCode().ast);
const ruleInfo = utils.getRuleInfo(context.getSourceCode());
const messagesObject = ruleInfo &&
ruleInfo.meta &&
ruleInfo.meta.type === 'ObjectExpression' &&
28 changes: 14 additions & 14 deletions lib/rules/require-meta-docs-description.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
'use strict';

const { getStaticValue } = require('eslint-utils');
const utils = require('../utils');

// ------------------------------------------------------------------------------
@@ -8,16 +9,6 @@ const utils = require('../utils');

const DEFAULT_PATTERN = new RegExp('^(enforce|require|disallow)');

/**
* Whether or not the node is a string literal
*
* @param {object} node
* @returns {boolean} whether or not the node is a string literal
*/
function isStringLiteral (node) {
return node.type === 'Literal' && typeof node.value === 'string';
}

module.exports = {
meta: {
docs: {
@@ -47,7 +38,7 @@ module.exports = {

create (context) {
const sourceCode = context.getSourceCode();
const info = utils.getRuleInfo(sourceCode.ast, sourceCode.scopeManager);
const info = utils.getRuleInfo(sourceCode);

return {
Program () {
@@ -70,11 +61,20 @@ module.exports = {

if (!descriptionNode) {
context.report({ node: docsNode ? docsNode : metaNode, messageId: 'missing' });
} else if (!isStringLiteral(descriptionNode.value) || descriptionNode.value.value === '') {
return;
}

const staticValue = getStaticValue(descriptionNode.value, context.getScope());
if (!staticValue) {
// Ignore non-static values since we can't determine what they look like.
return;
}

if (typeof staticValue.value !== 'string' || staticValue.value === '') {
context.report({ node: descriptionNode.value, messageId: 'wrongType' });
} else if (descriptionNode.value.value !== descriptionNode.value.value.trim()) {
} else if (staticValue.value !== staticValue.value.trim()) {
context.report({ node: descriptionNode.value, messageId: 'extraWhitespace' });
} else if (!pattern.test(descriptionNode.value.value)) {
} else if (!pattern.test(staticValue.value)) {
context.report({
node: descriptionNode.value,
message: '`meta.docs.description` must match the regexp {{pattern}}.',
2 changes: 1 addition & 1 deletion lib/rules/require-meta-docs-url.js
Original file line number Diff line number Diff line change
@@ -66,7 +66,7 @@ module.exports = {

return {
Program (node) {
const info = util.getRuleInfo(node);
const info = util.getRuleInfo(sourceCode);
if (info === null) {
return;
}
2 changes: 1 addition & 1 deletion lib/rules/require-meta-fixable.js
Original file line number Diff line number Diff line change
@@ -24,7 +24,7 @@ module.exports = {

create (context) {
const sourceCode = context.getSourceCode();
const ruleInfo = utils.getRuleInfo(sourceCode.ast);
const ruleInfo = utils.getRuleInfo(sourceCode);
let contextIdentifiers;
let usesFixFunctions;

4 changes: 2 additions & 2 deletions lib/rules/require-meta-schema.js
Original file line number Diff line number Diff line change
@@ -35,8 +35,8 @@ module.exports = {

create (context) {
const sourceCode = context.getSourceCode();
const { ast, scopeManager } = sourceCode;
const info = utils.getRuleInfo(ast, scopeManager);
const { scopeManager } = sourceCode;
const info = utils.getRuleInfo(sourceCode);

return {
Program () {
2 changes: 1 addition & 1 deletion lib/rules/require-meta-type.js
Original file line number Diff line number Diff line change
@@ -30,7 +30,7 @@ module.exports = {

create (context) {
const sourceCode = context.getSourceCode();
const info = utils.getRuleInfo(sourceCode.ast, sourceCode.scopeManager);
const info = utils.getRuleInfo(sourceCode);

// ----------------------------------------------------------------------
// Helpers
6 changes: 3 additions & 3 deletions lib/utils.js
Original file line number Diff line number Diff line change
@@ -85,13 +85,13 @@ module.exports = {

/**
* Performs static analysis on an AST to try to determine the final value of `module.exports`.
* @param {ASTNode} ast The `Program` AST node
* @param {{ast: ASTNode, scopeManager?: ScopeManager}} sourceCode The object contains `Program` AST node, and optional `scopeManager`
* @returns {Object} An object with keys `meta`, `create`, and `isNewStyle`. `meta` and `create` correspond to the AST nodes
for the final values of `module.exports.meta` and `module.exports.create`. `isNewStyle` will be `true` if `module.exports`
is an object, and `false` if module.exports is just the `create` function. If no valid ESLint rule info can be extracted
from the file, the return value will be `null`.
*/
getRuleInfo (ast, scopeManager) {
getRuleInfo ({ ast, scopeManager }) {
const INTERESTING_KEYS = new Set(['create', 'meta']);
let exportsVarOverridden = false;
let exportsIsFunction = false;
@@ -171,7 +171,7 @@ module.exports = {
* @returns {Set<ASTNode>} A Set of all `Identifier` nodes that are references to the `context` value for the file
*/
getContextIdentifiers (context, ast) {
const ruleInfo = module.exports.getRuleInfo(ast);
const ruleInfo = module.exports.getRuleInfo({ ast });

if (!ruleInfo || !ruleInfo.create.params.length || ruleInfo.create.params[0].type !== 'Identifier') {
return new Set();
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "eslint-plugin-eslint-plugin",
"version": "3.0.2",
"version": "3.0.3",
"description": "An ESLint plugin for linting ESLint plugins",
"author": "Teddy Katz",
"main": "lib/index.js",
60 changes: 55 additions & 5 deletions tests/lib/rules/require-meta-docs-description.js
Original file line number Diff line number Diff line change
@@ -32,6 +32,44 @@ ruleTester.run('require-meta-docs-description', rule, {
create(context) {}
};
`,
`
module.exports = {
meta: { docs: { description: generateRestOfDescription() } },
create(context) {}
};
`,
`
module.exports = {
meta: { docs: { description: \`enforce with template literal\` } },
create(context) {}
};
`,
`
module.exports = {
meta: { docs: { description: "enforce" + " " + "something" } },
create(context) {}
};
`,
`
module.exports = {
meta: { docs: { description: "enforce " + generateSomething() } },
create(context) {}
};
`,
`
const DESCRIPTION = 'require foo';
module.exports = {
meta: { docs: { description: DESCRIPTION } },
create(context) {}
};
`,
`
const DESCRIPTION = generateDescription();
module.exports = {
meta: { docs: { description: DESCRIPTION } },
create(context) {}
};
`,
{
code:
`
@@ -88,17 +126,18 @@ ruleTester.run('require-meta-docs-description', rule, {
{
code: `
module.exports = {
meta: { docs: { description: \`enforce with template literal\` } },
meta: { docs: { description: '' } },
create(context) {}
};
`,
output: null,
errors: [{ messageId: 'wrongType', type: 'TemplateLiteral' }],
errors: [{ messageId: 'wrongType', type: 'Literal' }],
},
{
code: `
const DESCRIPTION = true;
module.exports = {
meta: { docs: { description: SOME_DESCRIPTION } },
meta: { docs: { description: DESCRIPTION } },
create(context) {}
};
`,
@@ -107,13 +146,14 @@ ruleTester.run('require-meta-docs-description', rule, {
},
{
code: `
const DESCRIPTION = 123;
module.exports = {
meta: { docs: { description: '' } },
meta: { docs: { description: DESCRIPTION } },
create(context) {}
};
`,
output: null,
errors: [{ messageId: 'wrongType', type: 'Literal' }],
errors: [{ messageId: 'wrongType', type: 'Identifier' }],
},
{
code: `
@@ -135,6 +175,16 @@ ruleTester.run('require-meta-docs-description', rule, {
output: null,
errors: [{ message: '`meta.docs.description` must match the regexp /^(enforce|require|disallow)/.', type: 'Literal' }],
},
{
code: `
module.exports = {
meta: { docs: { description: 'foo' + ' ' + 'bar' } },
create(context) {}
};
`,
output: null,
errors: [{ message: '`meta.docs.description` must match the regexp /^(enforce|require|disallow)/.', type: 'BinaryExpression' }],
},
{
code: `
module.exports = {
8 changes: 4 additions & 4 deletions tests/lib/utils.js
Original file line number Diff line number Diff line change
@@ -28,7 +28,7 @@ describe('utils', () => {
].forEach(noRuleCase => {
it(`returns null for ${noRuleCase}`, () => {
const ast = espree.parse(noRuleCase, { ecmaVersion: 8, range: true });
assert.isNull(utils.getRuleInfo(ast), 'Expected no rule to be found');
assert.isNull(utils.getRuleInfo({ ast }), 'Expected no rule to be found');
});
});
});
@@ -115,7 +115,7 @@ describe('utils', () => {
Object.keys(CASES).forEach(ruleSource => {
it(ruleSource, () => {
const ast = espree.parse(ruleSource, { ecmaVersion: 6, range: true });
const ruleInfo = utils.getRuleInfo(ast);
const ruleInfo = utils.getRuleInfo({ ast });
assert(
lodash.isMatch(ruleInfo, CASES[ruleSource]),
`Expected \n${util.inspect(ruleInfo)}\nto match\n${util.inspect(CASES[ruleSource])}`
@@ -139,8 +139,8 @@ describe('utils', () => {
isNewStyle: true,
};
it(`ScopeOptions: ${JSON.stringify(scopeOptions)}`, () => {
const scope = eslintScope.analyze(ast, scopeOptions);
const ruleInfo = utils.getRuleInfo(ast, scope);
const scopeManager = eslintScope.analyze(ast, scopeOptions);
const ruleInfo = utils.getRuleInfo({ ast, scopeManager });
assert(
lodash.isMatch(ruleInfo, expected),
`Expected \n${util.inspect(ruleInfo)}\nto match\n${util.inspect(expected)}`