Skip to content

Commit c766606

Browse files
committed
chore: Update eslint dependencies and add new rule for disallowed comments
1 parent 1a81cf5 commit c766606

File tree

5 files changed

+239
-18
lines changed

5 files changed

+239
-18
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,11 @@
1818
"update:eslint-docs": "eslint-doc-generator"
1919
},
2020
"dependencies": {
21+
"@babel/eslint-parser": "^7.25.1",
2122
"eslint-config-jsdoc": "^15.4.0",
2223
"eslint-config-xo": "^0.46.0",
2324
"eslint-config-xo-react": "^0.27.0",
2425
"eslint-plugin-jsdoc": "^50.2.2",
25-
"eslint-plugin-no-comments": "^1.1.10",
2626
"eslint-plugin-react": "^7.35.0",
2727
"eslint-plugin-react-hooks": "^4.6.2",
2828
"eslint-plugin-react-native": "^4.1.0",

src/index.js

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ configs.recommended = {
1818
rules: {
1919
'th-rules/no-destructuring': 'error',
2020
'th-rules/no-default-export': 'error',
21+
'th-rules/no-comments': 'error',
2122
'unicorn/prefer-module': 'warn',
2223
'unicorn/filename-case': 'off',
2324
'unicorn/no-array-callback-reference': 'off',
@@ -27,13 +28,6 @@ configs.recommended = {
2728
'new-cap': 'off',
2829
'no-await-in-loop': 'off',
2930
camelcase: 'warn',
30-
'no-comments/disallowComments': [
31-
'error',
32-
{
33-
allow: ['^\\*\\*', 'eslint-disable', 'global', 'TODO', 'FIXME', 'NOTE', 'DEBUG'],
34-
},
35-
],
36-
3731
},
3832
env: {
3933
node: true,

src/rules/no-comments.js

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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;

src/tests/no-comments.js

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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-disallowed-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+
});

yarn.lock

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,20 @@ __metadata:
2222
languageName: node
2323
linkType: hard
2424

25+
"@babel/eslint-parser@npm:^7.25.1":
26+
version: 7.25.1
27+
resolution: "@babel/eslint-parser@npm:7.25.1"
28+
dependencies:
29+
"@nicolo-ribaudo/eslint-scope-5-internals": "npm:5.1.1-v1"
30+
eslint-visitor-keys: "npm:^2.1.0"
31+
semver: "npm:^6.3.1"
32+
peerDependencies:
33+
"@babel/core": ^7.11.0
34+
eslint: ^7.5.0 || ^8.0.0 || ^9.0.0
35+
checksum: 10c0/9f98351b32edfced9e6308a80ad69af1210d9c9780f19339cb286d0c9be0a9afac80d1df3b3793112e720675ce5b927920b19454d0f48ddf8370d08ab62d0dc2
36+
languageName: node
37+
linkType: hard
38+
2539
"@babel/helper-validator-identifier@npm:^7.22.20":
2640
version: 7.22.20
2741
resolution: "@babel/helper-validator-identifier@npm:7.22.20"
@@ -238,6 +252,15 @@ __metadata:
238252
languageName: node
239253
linkType: hard
240254

255+
"@nicolo-ribaudo/eslint-scope-5-internals@npm:5.1.1-v1":
256+
version: 5.1.1-v1
257+
resolution: "@nicolo-ribaudo/eslint-scope-5-internals@npm:5.1.1-v1"
258+
dependencies:
259+
eslint-scope: "npm:5.1.1"
260+
checksum: 10c0/75dda3e623b8ad7369ca22552d6beee337a814b2d0e8a32d23edd13fcb65c8082b32c5d86e436f3860dd7ade30d91d5db55d4ef9a08fb5a976c718ecc0d88a74
261+
languageName: node
262+
linkType: hard
263+
241264
"@nodelib/fs.scandir@npm:2.1.5":
242265
version: 2.1.5
243266
resolution: "@nodelib/fs.scandir@npm:2.1.5"
@@ -3148,13 +3171,6 @@ __metadata:
31483171
languageName: node
31493172
linkType: hard
31503173

3151-
"eslint-plugin-no-comments@npm:^1.1.10":
3152-
version: 1.1.10
3153-
resolution: "eslint-plugin-no-comments@npm:1.1.10"
3154-
checksum: 10c0/75549d56ccc73b7a1ead94efbca80610b6c74a417dc2a3436b87ea938d50eb208977d0ed4a43674f2794cee1d1e8446d07ccdffb76468d05bed8213a0ad61de4
3155-
languageName: node
3156-
linkType: hard
3157-
31583174
"eslint-plugin-no-use-extend-native@npm:^0.5.0":
31593175
version: 0.5.0
31603176
resolution: "eslint-plugin-no-use-extend-native@npm:0.5.0"
@@ -3289,6 +3305,7 @@ __metadata:
32893305
version: 0.0.0-use.local
32903306
resolution: "eslint-plugin-th-rules@workspace:."
32913307
dependencies:
3308+
"@babel/eslint-parser": "npm:^7.25.1"
32923309
"@codedependant/semantic-release-docker": "npm:^5.0.3"
32933310
"@eslint/js": "npm:^9.9.0"
32943311
"@semantic-release/changelog": "npm:^6.0.3"
@@ -3309,7 +3326,6 @@ __metadata:
33093326
eslint-doc-generator: "npm:^1.7.1"
33103327
eslint-plugin-eslint-plugin: "npm:^6.2.0"
33113328
eslint-plugin-jsdoc: "npm:^50.2.2"
3312-
eslint-plugin-no-comments: "npm:^1.1.10"
33133329
eslint-plugin-node: "npm:^11.1.0"
33143330
eslint-plugin-react: "npm:^7.35.0"
33153331
eslint-plugin-react-hooks: "npm:^4.6.2"
@@ -3388,7 +3404,7 @@ __metadata:
33883404
languageName: node
33893405
linkType: hard
33903406

3391-
"eslint-scope@npm:^5.1.1":
3407+
"eslint-scope@npm:5.1.1, eslint-scope@npm:^5.1.1":
33923408
version: 5.1.1
33933409
resolution: "eslint-scope@npm:5.1.1"
33943410
dependencies:
@@ -3445,7 +3461,7 @@ __metadata:
34453461
languageName: node
34463462
linkType: hard
34473463

3448-
"eslint-visitor-keys@npm:^2.0.0":
3464+
"eslint-visitor-keys@npm:^2.0.0, eslint-visitor-keys@npm:^2.1.0":
34493465
version: 2.1.0
34503466
resolution: "eslint-visitor-keys@npm:2.1.0"
34513467
checksum: 10c0/9f0e3a2db751d84067d15977ac4b4472efd6b303e369e6ff241a99feac04da758f46d5add022c33d06b53596038dbae4b4aceb27c7e68b8dfc1055b35e495787

0 commit comments

Comments
 (0)