ignore-lint-errors 0.4.2 → 0.6.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/README.md CHANGED
@@ -15,14 +15,29 @@ In large production projects, ignoring lint errors for existing code is the most
15
15
 
16
16
  For the sake of reducing noise, some prefer disabling linting for the entire file. They do so by adding a global directive (e.g. `eslint-disable`) or creating a special file to "suppress" files with many errors.
17
17
 
18
- Instead, `ignore-lint-errors` takes the honest approach: It adds a local directive (e.g. `eslint-disable-next-line`) for every line that has an error. This way, we can easily see and show others (including non-engineers),
18
+ Instead, `ignore-lint-errors` takes the honest approach: It adds a local directive (e.g. `eslint-disable-next-line`) for every line that has an error. This way, we can easily see and show others (including non-engineers and AIs),
19
19
 
20
- - How bad our code is in order to create the urgency to fix issues. The number of local ignores (1 per line) always estimates the actual number of errors better than the number of global ignores (1 per file).
21
- - Which parts of our code are good and should be replicated, and which parts are bad and to be avoided. When there is a global ignore, a linter doesn't check the file for the given rule(s).
20
+ - How bad our code is to increase the urgency to fix issues. The number of local ignores (1 per line) will always estimate the actual number of errors better than the number of global ignores (1 per file).
21
+ - Which parts of our code are good and should be replicated, and which parts are bad and to be avoided. When there is a global ignore, a linter won't check the file for the given rule(s).
22
22
 
23
23
 
24
24
  ## Usage
25
25
 
26
+ Step 1. Run codemod.
27
+
28
+ ```sh
29
+ cd <path/to/your/project>
30
+ pnpx ignore-lint-errors <arguments>
31
+ ```
32
+
33
+ Step 2. Fix formatting.
34
+
35
+ ```sh
36
+ # Run prettier
37
+ pnpm prettier . --write
38
+ ```
39
+
40
+
26
41
  ### Arguments
27
42
 
28
43
  You must pass `--linter` to indicate which linter to run.
@@ -1,9 +1,45 @@
1
1
  import { EOL } from 'node:os';
2
+ import { AST } from '@codemod-utils/ast-javascript';
3
+ function getIgnoredRules(lineOfCode) {
4
+ const traverse = AST.traverse(true);
5
+ let ignoredRules = [];
6
+ try {
7
+ traverse(lineOfCode, {
8
+ visitComment(node) {
9
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
10
+ const comment = node.value.value.trim();
11
+ if (comment.startsWith('eslint-disable-next-line')) {
12
+ ignoredRules = comment
13
+ .replace(/^eslint-disable-next-line\s+/, '')
14
+ .split(',')
15
+ .map((token) => token.trim());
16
+ }
17
+ return false;
18
+ },
19
+ });
20
+ }
21
+ catch {
22
+ // Do nothing
23
+ }
24
+ return ignoredRules;
25
+ }
2
26
  export function ignoreErrors(file, lintErrors) {
3
27
  const lines = file.split(EOL);
4
28
  lintErrors.forEach(({ line, message }) => {
5
- const ignoreDirective = `// eslint-disable-next-line ${message}`;
6
- lines.splice(line - 1, 0, ignoreDirective);
29
+ const currentIndex = line - 1;
30
+ const previousIndex = Math.max(currentIndex - 1, 0);
31
+ const ignoredRules = getIgnoredRules(lines[previousIndex]);
32
+ if (ignoredRules.length === 0) {
33
+ const ignoreDirective = `// eslint-disable-next-line ${message}`;
34
+ lines.splice(currentIndex, 0, ignoreDirective);
35
+ }
36
+ else {
37
+ const newMessage = [...ignoredRules, ...message.split(', ')]
38
+ .sort()
39
+ .join(', ');
40
+ const ignoreDirective = `// eslint-disable-next-line ${newMessage}`;
41
+ lines.splice(previousIndex, 1, ignoreDirective);
42
+ }
7
43
  });
8
44
  return lines.join(EOL);
9
45
  }
@@ -1,9 +1,45 @@
1
1
  import { EOL } from 'node:os';
2
+ import { AST } from '@codemod-utils/ast-javascript';
3
+ function getIgnoredRules(lineOfCode) {
4
+ const traverse = AST.traverse(true);
5
+ let ignoredRules = [];
6
+ try {
7
+ traverse(lineOfCode, {
8
+ visitComment(node) {
9
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
10
+ const comment = node.value.value.trim();
11
+ if (comment.startsWith('stylelint-disable-next-line')) {
12
+ ignoredRules = comment
13
+ .replace(/^stylelint-disable-next-line\s+/, '')
14
+ .split(',')
15
+ .map((token) => token.trim());
16
+ }
17
+ return false;
18
+ },
19
+ });
20
+ }
21
+ catch {
22
+ // Do nothing
23
+ }
24
+ return ignoredRules;
25
+ }
2
26
  export function ignoreErrors(file, lintErrors) {
3
27
  const lines = file.split(EOL);
4
28
  lintErrors.forEach(({ line, message }) => {
5
- const ignoreDirective = `/* stylelint-disable-next-line ${message} */`;
6
- lines.splice(line - 1, 0, ignoreDirective);
29
+ const currentIndex = line - 1;
30
+ const previousIndex = Math.max(currentIndex - 1, 0);
31
+ const ignoredRules = getIgnoredRules(lines[previousIndex]);
32
+ if (ignoredRules.length === 0) {
33
+ const ignoreDirective = `/* stylelint-disable-next-line ${message} */`;
34
+ lines.splice(currentIndex, 0, ignoreDirective);
35
+ }
36
+ else {
37
+ const newMessage = [...ignoredRules, ...message.split(', ')]
38
+ .sort()
39
+ .join(', ');
40
+ const ignoreDirective = `/* stylelint-disable-next-line ${newMessage} */`;
41
+ lines.splice(previousIndex, 1, ignoreDirective);
42
+ }
7
43
  });
8
44
  return lines.join(EOL);
9
45
  }
@@ -58,17 +58,14 @@ export function ignoreErrorsFallback(file, lintErrors) {
58
58
  export function isParseable(file) {
59
59
  const traverse = AST.traverse();
60
60
  let isParseable = true;
61
- function parseTemplate(template) {
62
- try {
63
- traverse(template);
64
- }
65
- catch {
66
- isParseable = false;
67
- }
61
+ try {
62
+ const templateTags = findTemplateTags(file);
63
+ templateTags.forEach((templateTag) => {
64
+ traverse(templateTag.contents);
65
+ });
66
+ }
67
+ catch {
68
+ isParseable = false;
68
69
  }
69
- const templateTags = findTemplateTags(file);
70
- templateTags.forEach((templateTag) => {
71
- parseTemplate(templateTag.contents);
72
- });
73
70
  return isParseable;
74
71
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ignore-lint-errors",
3
- "version": "0.4.2",
3
+ "version": "0.6.0",
4
4
  "description": "Codemod to ignore lint errors per line",
5
5
  "keywords": [
6
6
  "codemod",
@@ -17,6 +17,7 @@
17
17
  "dist"
18
18
  ],
19
19
  "dependencies": {
20
+ "@codemod-utils/ast-javascript": "^3.0.1",
20
21
  "@codemod-utils/ast-template": "^3.0.1",
21
22
  "@codemod-utils/ast-template-tag": "^2.1.0",
22
23
  "@codemod-utils/files": "^4.0.1",