Skip to content

feat: Consider bulk suppressions when running Lint via the Node.js API #133

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: main
Choose a base branch
from

Conversation

sushichan044
Copy link

@sushichan044 sushichan044 commented May 5, 2025

Summary

This RFC proposes integrating bulk suppressions support into the Node.js API via the ESLint and LegacyESLint classes, specifically focusing on considering existing bulk suppressions when linting files or text through the API. This change ensures that suppression files (eslint-suppressions.json) created via CLI commands are automatically respected when using the programmatic API, maintaining consistency between CLI and API behavior.

The scope is limited to applying existing suppressions during linting and does not include suppression file manipulation features (such as --suppress-all, --suppress-rule, or --prune-suppressions), which remain CLI-exclusive functionalities.

Related Issues

Copy link

linux-foundation-easycla bot commented May 5, 2025

CLA Signed

The committers listed above are authorized under a signed CLA.

@sushichan044
Copy link
Author

Specific code examples for LegacyESLint are WIP, but will be added soon.

@mdjermanovic mdjermanovic added the Initial Commenting This RFC is in the initial feedback stage label May 6, 2025
Copy link
Member

@mdjermanovic mdjermanovic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the RFC! I left some initial questions about the design.

used. Be sure to define any new terms in this section.
-->

This proposal integrates the existing bulk suppression functionality into the `ESLint` and `LegacyESLint` Node.js API classes by leveraging the internal `SuppressionsService`. A new `suppressionsLocation` option is introduced in the constructors.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since ESLint CLI uses ESLint API, and part of the bulk suppressions functionality will now be implemented directly in the API, will there be any changes to the ESLint CLI code (https://github.com/eslint/eslint/blob/main/lib/cli.js)? For example, perhaps removing some code that is now implemented in the API.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the CLI uses the API, so on the CLI side need to remove the calls of SuppressionsService.
I forgot to write it.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed: c5b4134

Comment on lines +19 to +22
Currently, the bulk suppression feature introduced in ESLint 9.24.0 is only available via the CLI.
This leads to inconsistencies when ESLint is used programmatically via its Node.js API, such as in IDE integrations.

This leads to inconsistencies when ESLint is used programmatically. Violations suppressed using `eslint-suppressions.json` (especially when using a custom location via the CLI) might not be recognized when using the Node.js API, leading to incorrect error reporting in environments like IDEs.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suppose someone has a task to fix previously suppressed violations. How will they do this, since the violations no longer appear in their IDE?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The motivation for using bulk suppression may be “I want to ignore existing errors and give priority to activating new errors”.
With that assumption, existing errors that should be ignored should not be shown in the IDE either.

To work on reducing the number of ignored errors, we can start by check the suppressed errors in eslint-suppressions.json.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mdjermanovic I think this is the same use case as when running on the CLI. Because the CLI automatically picks up the eslint-suppressions.json file, it's necessary to edit, move, or delete the file if your task is to clean up suppressed violations.

@nzakas
Copy link
Member

nzakas commented May 7, 2025

@sushichan044 please take a moment to sign the CLA (see first comment).

nzakas
nzakas previously approved these changes May 7, 2025
Copy link
Member

@nzakas nzakas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall this looks like a good plan to me. Nice work.

Comment on lines +19 to +22
Currently, the bulk suppression feature introduced in ESLint 9.24.0 is only available via the CLI.
This leads to inconsistencies when ESLint is used programmatically via its Node.js API, such as in IDE integrations.

This leads to inconsistencies when ESLint is used programmatically. Violations suppressed using `eslint-suppressions.json` (especially when using a custom location via the CLI) might not be recognized when using the Node.js API, leading to incorrect error reporting in environments like IDEs.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mdjermanovic I think this is the same use case as when running on the CLI. Because the CLI automatically picks up the eslint-suppressions.json file, it's necessary to edit, move, or delete the file if your task is to clean up suppressed violations.

-->

- Specific implementation examples for the `LegacyESLint` class.
- Should functionality equivalent to CLI flags like `--suppress-all` or `--suppress-rule` be supported via separate API methods in the future?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think so. I think the main use case is people will create and manage a suppressions file using the CLI. The IDE use case is more an extension of that rather than a replacement.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nzakas
I was relieved because I had the same opinion.
It was an open question to confirm if our understanding was aligned.

Given this direction, I believe it would be better to slightly modify the RFC's title and content to focus on the scope of considering bulk suppressions when running Lint via the Node.js API.
The reason is that with the current content, it might take time for future discussions referencing this RFC to understand that handling the suppression content itself is out of scope.

How do you think?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good to me. Looks like this was already done?

Copy link
Author

@sushichan044 sushichan044 May 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you! I haven't made any changes regarding the scope of the RFC yet, but I will add them in short.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed: 00ba3e9

Co-authored-by: Nicholas C. Zakas <nicholas@humanwhocodes.com>
- The constructor will resolve the final absolute path to the suppression file (using `suppressionsLocation` or the default) and pass it to the `SuppressionsService` constructor.

3. Applying Suppressions
- Within the `lintFiles()` and `lintText()` methods of both classes, *after* the initial linting results are obtained, the `applySuppressions` method of the instantiated `SuppressionsService` will be called.
Copy link
Contributor

@softius softius May 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we will need to maintain the existing order of processing. In this case, applySuppressions will be invoked before the call to outputFixes, suppress and prune. This will lead to different behavior from the existing implementation. For example, if the CLI is invoked with --prune-suppressions you will still get errors about unmatched suppressions, since the pruning will happen after.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am currently organizing the issues related to the order of processing. Please give me a little time.

Copy link
Author

@sushichan044 sushichan044 May 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@softius cc @nzakas
That's a fair point. However, if we were to make the API's processing order match the CLI's, it would likely require breaking changes to the API.
Therefore, I think it's more realistic to adjust the CLI's processing order to align with the API implementation in this RFC.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sushichan044 I don't think changing the CLI is the right choice if it leads to a broken experience as @softius described.


1. New Constructor Option (`suppressionsLocation`)
- Both `ESLintOptions` and `LegacyESLintOptions` will accept a new optional property: `suppressionsLocation`.
- `suppressionsLocation: string | undefined`: Specifies the path to the suppressions file (`eslint-suppressions.json`). This path can be absolute or relative to the `cwd`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it would be better to pass the whole suppressions config and move the whole logic into the classes, similar to the cache? 🤔

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you expand on that suggestion? I'm not clear on what it is you're imagining.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a suggestion in regards to my concern described here at #133 (comment)

Since we are discussing to move the suppression check from CLI to ESLint classes, we would need to bring over the entire code block to maintain the correct order of execution. In that case we would need to pass over all the suppressions args and let the ESLint classes handle the logic including updating the files (similar to cache).

Having said that, I realised that even with this approach we will be doing the suppressions logic before the automated fixes, which means that once again we are changing the execution order.

@sushichan044 sushichan044 changed the title feat: Add bulk suppressions feature for Node.js API feat: Consider bulk suppressions when running Lint via the Node.js API May 28, 2025
Copy link
Member

@nzakas nzakas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we need to take another look to see if we can effectively keep the current behavior while allowing API consumers to filter the results through suppressions.

To that end, it seems like the only reasonable approach would be to add an option to the ESLint constructor to indicate whether it should or shouldn't apply suppressions to results when lintText() or lintFiles() is called? That way, the CLI can tell ESLint not to apply suppressions and maintain its current behavior, and any API consumers who want to apply suppressions can do so. (Question remains: what is the default? Should ESLint apply suppressions automatically or not?)

@sushichan044
Copy link
Author

@nzakas
Thank you!
I am very busy right now, so my reply will be delayed until around next Monday.

@nzakas
Copy link
Member

nzakas commented Jun 13, 2025

@sushichan044 no problem, thanks for letting us know.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature Initial Commenting This RFC is in the initial feedback stage
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants