eslint-plugin-th-rules 1.11.3 → 1.12.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/.vscode/settings.json +5 -1
- package/.xo-config.json +5 -0
- package/CHANGELOG.md +14 -0
- package/README.md +32 -0
- package/bun.lockb +0 -0
- package/package.json +3 -2
- package/src/index.js +4 -8
- package/src/rules/no-comments.js +96 -0
- package/src/tests/no-comments.js +115 -0
package/.vscode/settings.json
CHANGED
package/.xo-config.json
ADDED
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
# [1.12.0](https://github.com/tomerh2001/eslint-plugin-th-rules/compare/v1.11.4...v1.12.0) (2024-08-19)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Features
|
|
5
|
+
|
|
6
|
+
* created no-comments rule ([82dda49](https://github.com/tomerh2001/eslint-plugin-th-rules/commit/82dda49f7f4708b68b8a4bd81e5af3ca84519a43))
|
|
7
|
+
|
|
8
|
+
## [1.11.4](https://github.com/tomerh2001/eslint-plugin-th-rules/compare/v1.11.3...v1.11.4) (2024-08-19)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* Update regex pattern for disallowed comments ([11d9e1b](https://github.com/tomerh2001/eslint-plugin-th-rules/commit/11d9e1bde0382460defb252701c20769f30e67e6))
|
|
14
|
+
|
|
1
15
|
## [1.11.3](https://github.com/tomerh2001/eslint-plugin-th-rules/compare/v1.11.2...v1.11.3) (2024-08-19)
|
|
2
16
|
|
|
3
17
|
|
package/README.md
CHANGED
|
@@ -59,3 +59,35 @@ This rule targets unnamed default exports and automatically generates a named ex
|
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
61
|
```
|
|
62
|
+
### 3. No-Disallowed-Comments Rule
|
|
63
|
+
|
|
64
|
+
**Rule ID:** `th-rules/no-disallowed-comments`
|
|
65
|
+
|
|
66
|
+
#### Description
|
|
67
|
+
|
|
68
|
+
This rule disallows comments unless they match specified allowed patterns. It ensures that only relevant and permitted comments are present in the codebase, such as TODOs, warnings, JSDoc comments, ESLint directives, etc.
|
|
69
|
+
|
|
70
|
+
#### Rule Details
|
|
71
|
+
|
|
72
|
+
By default, the following comments are allowed:
|
|
73
|
+
|
|
74
|
+
- TODO, WARNING, ERROR, INFO (case-insensitive).
|
|
75
|
+
- ESLint directives like `/* eslint-disable */`.
|
|
76
|
+
- JSDoc comments (any comment starting with `/**`).
|
|
77
|
+
|
|
78
|
+
You can also configure additional patterns to allow or disallow specific types of comments.
|
|
79
|
+
|
|
80
|
+
#### Configuration
|
|
81
|
+
|
|
82
|
+
```json
|
|
83
|
+
{
|
|
84
|
+
"rules": {
|
|
85
|
+
"th-rules/no-disallowed-comments": [
|
|
86
|
+
"error",
|
|
87
|
+
{
|
|
88
|
+
"allow": ["keep", "important"],
|
|
89
|
+
"disallow": ["deprecated", "hack"]
|
|
90
|
+
}
|
|
91
|
+
]
|
|
92
|
+
}
|
|
93
|
+
}
|
package/bun.lockb
CHANGED
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-th-rules",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.12.0",
|
|
4
4
|
"description": "A List of custom ESLint rules created by Tomer Horowitz",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"eslint",
|
|
@@ -18,16 +18,17 @@
|
|
|
18
18
|
"update:eslint-docs": "eslint-doc-generator"
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
|
21
|
+
"@babel/eslint-parser": "^7.25.1",
|
|
21
22
|
"eslint-config-jsdoc": "^15.4.0",
|
|
22
23
|
"eslint-config-xo": "^0.46.0",
|
|
23
24
|
"eslint-config-xo-react": "^0.27.0",
|
|
24
25
|
"eslint-plugin-jsdoc": "^50.2.2",
|
|
25
|
-
"eslint-plugin-no-comments": "^1.1.10",
|
|
26
26
|
"eslint-plugin-react": "^7.35.0",
|
|
27
27
|
"eslint-plugin-react-hooks": "^4.6.2",
|
|
28
28
|
"eslint-plugin-react-native": "^4.1.0",
|
|
29
29
|
"eslint-plugin-security": "^3.0.1",
|
|
30
30
|
"eslint-plugin-sonarjs": "^1.0.4",
|
|
31
|
+
"eslint-plugin-th-rules": "^1.11.4",
|
|
31
32
|
"requireindex": "^1.2.0"
|
|
32
33
|
},
|
|
33
34
|
"devDependencies": {
|
package/src/index.js
CHANGED
|
@@ -18,6 +18,7 @@ configs.recommended = {
|
|
|
18
18
|
rules: {
|
|
19
19
|
'th-rules/no-destructuring': 'error',
|
|
20
20
|
'th-rules/no-default-export': 'error',
|
|
21
|
+
'th-rules/no-comments': 'error',
|
|
21
22
|
'unicorn/prefer-module': 'warn',
|
|
22
23
|
'unicorn/filename-case': 'off',
|
|
23
24
|
'unicorn/no-array-callback-reference': 'off',
|
|
@@ -26,14 +27,9 @@ configs.recommended = {
|
|
|
26
27
|
'unicorn/no-await-expression-member': 'off',
|
|
27
28
|
'new-cap': 'off',
|
|
28
29
|
'no-await-in-loop': 'off',
|
|
30
|
+
'n/file-extension-in-import': 'off',
|
|
31
|
+
'import/no-cycle': 'off',
|
|
29
32
|
camelcase: 'warn',
|
|
30
|
-
'no-comments/disallowComments': [
|
|
31
|
-
'error',
|
|
32
|
-
{
|
|
33
|
-
allow: ['^/\\*\\*(?:[\\s\\S]*?)\\*/$', 'eslint-disable', 'global', 'TODO', 'FIXME', 'NOTE', 'DEBUG'],
|
|
34
|
-
},
|
|
35
|
-
],
|
|
36
|
-
|
|
37
33
|
},
|
|
38
34
|
env: {
|
|
39
35
|
node: true,
|
|
@@ -43,7 +39,7 @@ configs.recommended = {
|
|
|
43
39
|
};
|
|
44
40
|
|
|
45
41
|
for (const configName of Object.keys(configs)) {
|
|
46
|
-
configs[configName
|
|
42
|
+
configs[`${configName}-typescript`] = {
|
|
47
43
|
...configs[configName],
|
|
48
44
|
extends: [
|
|
49
45
|
'plugin:@typescript-eslint/strict-type-checked',
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/* eslint-disable unicorn/prefer-module */
|
|
2
|
+
|
|
3
|
+
const allowedPatterns = [
|
|
4
|
+
/todo/i, // Allow TODO (case-insensitive)
|
|
5
|
+
/warning/i, // Allow WARNING (case-insensitive)
|
|
6
|
+
/error/i, // Allow ERROR (case-insensitive)
|
|
7
|
+
/info/i, // Allow INFO (case-insensitive)
|
|
8
|
+
/^\s*eslint-(disable|enable|env|globals|ignore|directive)/, // Allow ESLint directives
|
|
9
|
+
];
|
|
10
|
+
|
|
11
|
+
const meta = {
|
|
12
|
+
type: 'problem',
|
|
13
|
+
docs: {
|
|
14
|
+
description: 'Disallow comments except for specified allowed patterns.',
|
|
15
|
+
},
|
|
16
|
+
fixable: 'code',
|
|
17
|
+
schema: [
|
|
18
|
+
{
|
|
19
|
+
type: 'object',
|
|
20
|
+
properties: {
|
|
21
|
+
allow: {
|
|
22
|
+
type: 'array',
|
|
23
|
+
items: {
|
|
24
|
+
type: 'string',
|
|
25
|
+
},
|
|
26
|
+
description: 'Additional patterns to allow in comments.',
|
|
27
|
+
},
|
|
28
|
+
disallow: {
|
|
29
|
+
type: 'array',
|
|
30
|
+
items: {
|
|
31
|
+
type: 'string',
|
|
32
|
+
},
|
|
33
|
+
description: 'Additional patterns to disallow in comments.',
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
additionalProperties: false,
|
|
37
|
+
},
|
|
38
|
+
],
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
function create(context) {
|
|
42
|
+
const options = context.options[0] || {};
|
|
43
|
+
const userAllowedPatterns = (options.allow || []).map((pattern) => new RegExp(pattern));
|
|
44
|
+
const userDisallowedPatterns = (options.disallow || []).map((pattern) => new RegExp(pattern));
|
|
45
|
+
|
|
46
|
+
function isCommentAllowed(comment) {
|
|
47
|
+
const text = comment.value.trim();
|
|
48
|
+
|
|
49
|
+
// Check if the comment is a valid JSDoc comment
|
|
50
|
+
if (comment.type === 'Block' && comment.value.startsWith('*')) {
|
|
51
|
+
return true; // Allow any JSDoc-style block comment (/** ... */)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Check if the comment matches any allowed pattern
|
|
55
|
+
for (const pattern of [...allowedPatterns, ...userAllowedPatterns]) {
|
|
56
|
+
if (pattern.test(text)) {
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Check if the comment matches any disallowed pattern
|
|
62
|
+
for (const pattern of userDisallowedPatterns) {
|
|
63
|
+
if (pattern.test(text)) {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return false; // Disallow by default if no match
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return {
|
|
72
|
+
Program() {
|
|
73
|
+
const sourceCode = context.getSourceCode();
|
|
74
|
+
const comments = sourceCode.getAllComments();
|
|
75
|
+
|
|
76
|
+
comments.forEach((comment) => {
|
|
77
|
+
if (!isCommentAllowed(comment)) {
|
|
78
|
+
context.report({
|
|
79
|
+
node: comment,
|
|
80
|
+
message: 'Comment not allowed.',
|
|
81
|
+
fix(fixer) {
|
|
82
|
+
return fixer.remove(comment);
|
|
83
|
+
},
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
},
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const rule = {
|
|
92
|
+
meta,
|
|
93
|
+
create,
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
module.exports = rule;
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/* eslint-disable unicorn/prefer-module */
|
|
2
|
+
|
|
3
|
+
const { RuleTester } = require('eslint');
|
|
4
|
+
const rule = require('../rules/no-comments.js');
|
|
5
|
+
|
|
6
|
+
// Initialize RuleTester without the old parserOptions, using the new format
|
|
7
|
+
const ruleTester = new RuleTester({
|
|
8
|
+
parser: require.resolve('@babel/eslint-parser'),
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
ruleTester.run('no-comments', rule, {
|
|
12
|
+
valid: [
|
|
13
|
+
{
|
|
14
|
+
code: `
|
|
15
|
+
/**
|
|
16
|
+
* JSDoc comment
|
|
17
|
+
* @param {string} name - The name of the person.
|
|
18
|
+
*/
|
|
19
|
+
function foo(name) {}
|
|
20
|
+
`,
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
code: `
|
|
24
|
+
// TODO: this needs to be refactored
|
|
25
|
+
const x = 5;
|
|
26
|
+
`,
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
code: `
|
|
30
|
+
/* WARNING: temporary fix */
|
|
31
|
+
const y = 10;
|
|
32
|
+
`,
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
code: `
|
|
36
|
+
// eslint-disable-next-line no-console
|
|
37
|
+
console.log("hello");
|
|
38
|
+
`,
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
code: `
|
|
42
|
+
// keep this comment
|
|
43
|
+
const z = 15;
|
|
44
|
+
`,
|
|
45
|
+
options: [{ allow: ['keep'] }],
|
|
46
|
+
},
|
|
47
|
+
],
|
|
48
|
+
|
|
49
|
+
invalid: [
|
|
50
|
+
{
|
|
51
|
+
code: `
|
|
52
|
+
// Regular comment
|
|
53
|
+
const a = 5;
|
|
54
|
+
`,
|
|
55
|
+
errors: [{ message: 'Comment not allowed.' }],
|
|
56
|
+
output: `
|
|
57
|
+
const a = 5;
|
|
58
|
+
`,
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
code: `
|
|
62
|
+
// Some disallowed comment
|
|
63
|
+
const b = 10;
|
|
64
|
+
`,
|
|
65
|
+
options: [{ disallow: ['disallowed'] }],
|
|
66
|
+
errors: [{ message: 'Comment not allowed.' }],
|
|
67
|
+
output: `
|
|
68
|
+
const b = 10;
|
|
69
|
+
`,
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
code: `
|
|
73
|
+
// DEPRECATED: Remove this function in the next version
|
|
74
|
+
function deprecatedFunc() {}
|
|
75
|
+
`,
|
|
76
|
+
options: [{ disallow: ['deprecated'] }],
|
|
77
|
+
errors: [{ message: 'Comment not allowed.' }],
|
|
78
|
+
output: `
|
|
79
|
+
function deprecatedFunc() {}
|
|
80
|
+
`,
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
code: `
|
|
84
|
+
// important comment
|
|
85
|
+
const c = 20;
|
|
86
|
+
`,
|
|
87
|
+
errors: [{ message: 'Comment not allowed.' }],
|
|
88
|
+
output: `
|
|
89
|
+
const c = 20;
|
|
90
|
+
`,
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
code: `
|
|
94
|
+
// A completely random comment
|
|
95
|
+
const d = 25;
|
|
96
|
+
`,
|
|
97
|
+
options: [{ allow: ['keep'] }],
|
|
98
|
+
errors: [{ message: 'Comment not allowed.' }],
|
|
99
|
+
output: `
|
|
100
|
+
const d = 25;
|
|
101
|
+
`,
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
code: `
|
|
105
|
+
// @ts-ignore
|
|
106
|
+
const e = "typescript";
|
|
107
|
+
`,
|
|
108
|
+
options: [{ disallow: ['@ts-ignore'] }],
|
|
109
|
+
errors: [{ message: 'Comment not allowed.' }],
|
|
110
|
+
output: `
|
|
111
|
+
const e = "typescript";
|
|
112
|
+
`,
|
|
113
|
+
},
|
|
114
|
+
],
|
|
115
|
+
});
|