Skip to content

Improve experience of running linters with auto-fix capabilities on save events in editor #4639

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

Closed
HartBlanc opened this issue Apr 13, 2024 · 9 comments · Fixed by #4653
Closed
Assignees
Labels
enhancement New feature or improvement

Comments

@HartBlanc
Copy link

Your feature request related to a problem? Please describe

A repo I work in uses golangci-lint with the gci linter (among other linters).

golangci-lint is run automatically before raising each PR, and the auto-fixes from gci are applied at this point.

As a developer in this repo, I find that these changes introduce a little friction as I need to amend the suggested changes to my latest commit before raising my PR. The change which introduces the import and the change which sorts the imports may then be in different commits which introduces a little unnecessary noise in my changes (or additional effort to reorganise the commits).

I would prefer to have the autofix applied automatically by my editor (neovim) after each save to ensure that imports are sorted as early as possible.

I can configure my editor to run gci when saving a file relatively easily. However, I would like to ensure that when gci runs on save in my editor it uses the same config that golangci-lint will use without needing to manually ensure that the two stay in sync.

I have attempted the following approaches:

  1. Introduce logic in my editor configuration / an external script to parse the .golangci-lint.yml configuration and convert it into the relevant gci CLI arguments.

Limitations:

  • This is quite a lot of effort for integration. For every individual linter every user will need to implement this conversion logic. This would likely be better solved once by a linter aggregator.
  1. Configure my editor to run golangci-lint on save (goclangci-lint run --fix --fast --enable-only=gci $FILENAME flags).

Limitations:

  • golangci-lint reports type check errors even in cases where gci would be able to format the file without any issues (e.g. a syntax error in another file in the package, a reference to an undefined type etc.)
  • The user needs to explicitly enumerate all of the linters with autofix capabilities

Describe the solution you'd like

  1. Resolve failure modes for golangci-lint where prerequisite checks (i.e. typecheck) fail despite these presenting no issues for the enabled linters.
  2. Consider adding support for only running the linters with autofix capabilities (e.g. run --autofix-linters flag or something similar)

Describe alternatives you've considered

  • Adding support for querying config for a specific linter (this would make the integration for users a little easier, but still non-trivial.
  • Making do with running gci directly and parsing gci config manually (this does seem to have the advantage of being a bit faster)
  • Simply not running the autoformatter when there are typecheck errors (loses some of the incrementality benefits of running on save.)

Additional context

I'm happy to contribute a PR if any of the proposed solutions are acceptable

@HartBlanc HartBlanc added the enhancement New feature or improvement label Apr 13, 2024
Copy link

boring-cyborg bot commented Apr 13, 2024

Hey, thank you for opening your first Issue ! 🙂 If you would like to contribute we have a guide for contributors.

@ldez ldez changed the title Improve expereince of running linters with auto-fix capabilities on save events in editor. Improve experience of running linters with auto-fix capabilities on save events in editor. Apr 13, 2024
@ldez ldez self-assigned this Apr 13, 2024
@ldez
Copy link
Member

ldez commented Apr 13, 2024

Hello,

in v1.57.0, we introduced the flag --enable-only.
This option overrides enable/disable/preset/fast section from the file configuration but uses the linters-settings from the file configuration.

Then you can use golangci-lint run --enable-only=gci --fix.

The --fast flag is ignored when using --enable-only.

When typecheck errors occur, most linters (107 linters on 117) cannot perform the analysis because they need type information.
I will force this behavior on all linters.

Another element, golangci-lint is made to handle packages, I recommend avoiding the usage on file because side effects can appear (e.g. typecheck)

@HartBlanc
Copy link
Author

Hello,

If there is no interest in file-level formatting or modifying/disabling the typechecking process then I think the applicability of golangci-lint for this use case will always be a little lacking.

In my particular case, using gci directly is probably the best solution.

Thanks for considering the issue! (and the advice on the flags)

@ldez
Copy link
Member

ldez commented Apr 13, 2024

Just a precision, typecheck is not a linter or specific golangci-lint process: https://golangci-lint.run/welcome/faq/#why-do-you-have-typecheck-errors

So it's not really because "no interest modifying/disabling the typechecking process" but because typecheck is used to display those blocking errors in the "issue style".
The loading of the code is performed in a way that we can't skip.

I highly recommend using golangci-lint on a package instead of a file.

@ldez
Copy link
Member

ldez commented Apr 13, 2024

Do you have a minimal reproducible example?

Because gci, as a standalone app, has the same "problem" as golangci-lint with typecheck errors:

$ gci print main.go                          
Error: main.go:15:9: expected 'IDENT', found '{' (and 1 more errors)

@ldez ldez added the feedback required Requires additional feedback label Apr 13, 2024
@HartBlanc
Copy link
Author

For example, with the following file:

# gciexample.go
package gciexample

var a = b

Running gci directly:

$ gci print gciexample.go

package gciexample

var a = b

Running gci via golangci-lint:

$ golangci-lint run --fix --enable-only=gci a.go
a.go:3:9: undefined: b (typecheck)
var a = b
        ^

@ldez
Copy link
Member

ldez commented Apr 13, 2024

thank you

if you use this sample:

package gciexample

func () {

}

The behavior will be different: an error will be reported by gci.

gci detects syntax errors only, and golangci-lint detects syntax errors and type checking error.

Related to #2914

Side note: I know that the name typecheck is not really accurate, I plan to change that at some point.

@ldez
Copy link
Member

ldez commented Apr 17, 2024

@HartBlanc with PR #4653, if you run only a "fast" linter like gci only the syntax errors will be checked.
Bonus: the performance will be better.

@alexandear alexandear changed the title Improve experience of running linters with auto-fix capabilities on save events in editor. Improve experience of running linters with auto-fix capabilities on save events in editor Apr 17, 2024
@HartBlanc
Copy link
Author

This sounds like a significant improvement! Thanks @ldez!

@ldez ldez removed the feedback required Requires additional feedback label Apr 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or improvement
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants