Skip to content
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

New: Fixable Disable Directives #78

Merged
merged 6 commits into from May 20, 2021
Merged

New: Fixable Disable Directives #78

merged 6 commits into from May 20, 2021

Conversation

JoshuaKGoldberg
Copy link
Contributor

@JoshuaKGoldberg JoshuaKGoldberg commented Apr 12, 2021

Summary

Inline disable directives such as /* eslint-disable */ that do not suppress any violations may be detected with the --report-unused-disable-directives CLI option, but there is no way to automatically remove those comments.
This RFC proposes adding removal of those directives to the --fix CLI option as a new --fix-type: directive.

Related Issues

@ljharb
Copy link
Sponsor

ljharb commented Apr 12, 2021

If this won’t be autofixed by default (it should be) I would like a way to configure it in eslintrc (and a shared config) so that it is.

@nzakas
Copy link
Member

nzakas commented Apr 13, 2021

@ljharb fixing can’t be toggled in a config file. It’s a separate mode that ESLint runs in and you don’t want someone else’s config that you extend determining whether or not fixes are applied.

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.

Thanks for putting this together. As mentioned elsewhere, I think there is some additional complexity around expectations with certain CLI flag usage that we need to dig deeper into.

designs/2021-fixable-disable-directives/design.md Outdated Show resolved Hide resolved

> Will these be autofixed by default?

Yes: problems reported by directive usage checking are joined with remaining rule violation problems in a single array.
Copy link
Member

Choose a reason for hiding this comment

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

I’m not sure having this fixable just when using —fix is the right approach. Right now we don’t fix rules that wouldn’t otherwise output warnings. Since unused directives are not warned by default, I don’t think they should be auto fixed by default. Maybe if both —fix and —report-unused-disable-directives are used, then it would make sense to remove them, or else a separate flag might be a better way to go.

Copy link
Sponsor

Choose a reason for hiding this comment

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

wait, are these not reported by default? i don’t think I’ve ever provided the flag, but I’m pretty sure I’ve seen the output by default

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I phrased this poorly, and this part of the RFC is inaccurate. This was intended to convey that the fixers for unused directives will be added to reported problems "by default" -- as in, if --report-unused-disable-directives is true, there's nothing else you need to do to have the fixers be created. They still won't be applied if --fix is not true.

I.e. you must provide both --fix and --report-unused-disable-directives for them to be fixed.

I'll clarify this wording.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh, and no, --report-unused-disable-directives is IME off by default.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added FAQs in c87e3b9.

Copy link
Sponsor

Choose a reason for hiding this comment

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

is it that the flag is required to make them errors, but they're warnings by default?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's off by default on the CLI.

Interestingly, CLI-related places in code allow it to be boolean | undefined although others allow it to be "error" | "warn" | "off" | null.

I set up a quick little playground for it: https://github.com/JoshuaKGoldberg/eslint-disable-directives-testing

Copy link
Member

Choose a reason for hiding this comment

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

There is also reportUnusedDisableDirectives configuration option.

reportUnusedDisableDirectives: true config option produces warnings, --report-unused-disable-directives CLI option produces errors.

Copy link
Sponsor

Choose a reason for hiding this comment

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

aha! i'm surely using reportUnusedDisableDirectives: true in my shared config, and that resolves my confusion :-)

in that case, when that is true in my shared config, they should automatically be autofixed, yes?

@nzakas nzakas added Initial Commenting This RFC is in the initial feedback stage breaking change This RFC contains breaking changes and removed triage labels Apr 13, 2021
@ljharb
Copy link
Sponsor

ljharb commented Apr 13, 2021

@nzakas i don’t want someone else to control whether any fixes are applied or not, indeed - but which fixed are applied when any are being applied? That’s already what shared rule config dictates, and i definitely would want to be able to have that delegated to a shared config.

@mdjermanovic
Copy link
Member

but which fixed are applied when any are being applied? That’s already what shared rule config dictates, and i definitely would want to be able to have that delegated to a shared config.

I don't think we already have a config option to specify which fixes should be applied. There is only a CLI option --fix-type.

@ljharb
Copy link
Sponsor

ljharb commented Apr 13, 2021

@mdjermanovic what i mean is, "enabling a rule" and "disabling a rule" and "configuring a rule" is already exerting control over what fixes are applied.

@nzakas
Copy link
Member

nzakas commented Apr 21, 2021

@ljharb i think we are getting a bit too esoteric on this topic. Feel free to open a discussion if you want to talk more, but let’s keep the discussion here focused on the RFC itself.

@nzakas
Copy link
Member

nzakas commented Apr 28, 2021

@eslint/eslint-tsc can we get some more eyes on this?

Co-authored-by: 薛定谔的猫 <weiran.zsd@outlook.com>
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 the behavior as described now makes sense. This would end up being a breaking change, but I think it nicely balances what users might expect with the additional functionality.

Copy link
Member

@btmills btmills left a comment

Choose a reason for hiding this comment

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

LGTM. I think including this as a new --fix-type makes a lot of sense from a user's perspective. Thanks for putting this together and being ready to implement it!


This RFC's implementation would lock in the name for a new `--fix-type` even though we only have one concrete use case for it.

## Backwards Compatibility Analysis
Copy link
Member

Choose a reason for hiding this comment

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

Right now all messages with fixes have a non-null rule ID. I could imagine e.g. an IDE integration assuming the rule ID is always a string when displaying or applying fixes. Our LintMessage docs never promise that typeof message.fix !== "undefined" implies typeof message.ruleId === "string", so this change is compatible with our stated API. While that means it's not a breaking change to the Node.js API, I wouldn't be surprised if it requires fixes in some integrations.


## Open Questions

- Is `"directive"` a good name for the fix type?
Copy link
Member

Choose a reason for hiding this comment

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

The only other name I'm thinking of is "eslint-disable", which is even more specific to this particular use if that's desirable.

@nzakas nzakas added Final Commenting This RFC is in the final week of commenting and removed Initial Commenting This RFC is in the initial feedback stage labels May 3, 2021
@nzakas
Copy link
Member

nzakas commented May 3, 2021

Because we have two approvals and it's been 22 days, I'm moving this to the Final Commenting phase.

@nzakas
Copy link
Member

nzakas commented May 20, 2021

With apologies for the delay, this RFC has been approved.

@nzakas nzakas merged commit 101d00f into eslint:main May 20, 2021
@JoshuaKGoldberg JoshuaKGoldberg deleted the fixable-disable-directives branch May 20, 2021 21:39
@JoshuaKGoldberg
Copy link
Contributor Author

Awesome, thanks so much for the RFC review @nzakas & co.! I'll endeavor to send a PR as soon as I can - likely within a week.


Like any new feature, this flag will slightly increase the complexity and maintenance costs of ESLint core.

This RFC's implementation would lock in the name for a new `--fix-type` even though we only have one concrete use case for it.
Copy link
Sponsor Member

Choose a reason for hiding this comment

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

What if there other potential problems regarding directives we want to detect/fix in the future? --fix-type: directive doesn't indicate the specific directive problem, so would it be intended to encompass a variety of potential directive problems (perhaps incorporating new ones on major version bumps?)? Unused disable directives is just one potential problem, eslint-plugin-eslint-comments enumerates a host of other potential directive problems.


Otherwise, this change is additive in behavior.

## Alternatives
Copy link
Sponsor Member

Choose a reason for hiding this comment

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

It would be good to include other potential API designs in this section, even if we don't choose to use them:

  • Using a more specific fix-type of unused-disable-directives
  • Providing a new option --fix-unused-disable-directives
  • Using a new ESLint core rule no-unused-disable-directives for detecting and fixing this problem, similar to the rule eslint-comments/no-unused-disable


## Frequently Asked Questions

> Will these be autofixed by default?
Copy link
Sponsor Member

Choose a reason for hiding this comment

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

What's the behavior when using both --fix and --fix-type directive but not --report-unused-disable-directives?

Copy link
Member

Choose a reason for hiding this comment

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

then no unused-disable-directives problems will be reported (and no fixed). :)
it's as the same as --fix-type=layout(or else) - if no layout rules enabled, no layout errors reported.

aladdin-add added a commit to aladdin-add/rfcs that referenced this pull request Jul 12, 2022
* New: Fixable Disable Directives

* First two FAQs: autofix by default, opt out

* Clarified default CLI behavior

* Elaborated on fixes to account for remaining used rules

* Remaining -->

* Update designs/2021-fixable-disable-directives/design.md

Co-authored-by: 薛定谔的猫 <weiran.zsd@outlook.com>

Co-authored-by: Nicholas C. Zakas <nicholas@humanwhocodes.com>
Co-authored-by: 薛定谔的猫 <weiran.zsd@outlook.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
breaking change This RFC contains breaking changes Final Commenting This RFC is in the final week of commenting
Projects
None yet
7 participants