
Revive – Fast, configurable, extensible linter for Go - angelinaii
https://github.com/mgechev/revive
======
atombender
Have you looked at golangci-linter [1] at all? It's a competing project that
also implement a bunch of linter rules, and was created because gometalinter
is too slow.

One reason golangci-linter is faster is that it shares the same in-memory
representation of the linted packages between all the linters. From what I can
tell, Revive requires that each rule parse the file itself, which is the same
design gometalinter use, and it will absolutely kill performance for anything
that needs to operate on the full AST.

Also, the Go community does not need a bunch of competing linter tools. For
one, at means that tools like Visual Studio Code's Go plugin [2] will have to
build special support for each linter tool. Gometalinter was nice because it
built lots of rules (including golint) into a single tool, so you just needed
that one tool.

I agree with the others about configuration. I think a lint tool should have a
configuration work out of the box that reflects Go standards that _everyone_ ,
without doubt, uses. More controversial conventions such as requiring all
exported functions to have comments don't need to be included.

[1] [https://github.com/golangci/golangci-
lint](https://github.com/golangci/golangci-lint)

[2] [https://github.com/Microsoft/vscode-
go](https://github.com/Microsoft/vscode-go)

~~~
mgechev
Thanks for the comment! Yes, I saw golangci-linter. As the readme of the tool
states, it's a linter aggregator, similar to gometalinter, with better
performance characteristics. Both golangci-linter and gometalinter incorporate
existing tools for static analysis and provide a facade on top.

Revive is a project, which I started about 9 months ago but recently found
time to put some finishing touches and open source it. It's not a linter
aggregator; it's a framework which provides tools for reducing the friction
for development of custom rules for static analysis of your applications.

And no, the individual rules in revive do not parse the files. There's an
abstraction on a higher level which parses the files ones. Each rule may
request type information for the package which is then cached and reused
across the invocations as well. That's how revive manages to improve the
performance of golint to this extent.

~~~
lobster_johnson
Thanks for the clarification. I saw the readme, and I assumed (wrongly) that
each rule just receive a file name.

I wonder where you draw the line between a "linter aggregator" and a "linter".
golangci-lint incorporates all the rules themselves, though it imports the
linter logic as libraries, so I'm not sure that it's fair to call it an
aggregator. Gometalinter runs linters as child processes and I don't think it
contains any linter code, so it's a pure aggregator.

My point is that while your project is admirable, the Go world isn't large
enough for so many linter projects. Personally, I just want _one_ good linter
that is maintained and that incorporates all the rules I want.

------
thanatos_dem
This really irks me for some reason. One of the goals of the Go tooling in
general is to cut down on the number of config files and differing choices
that need to be made everywhere.

Gofmt is the canonical example (there is no configuration. It formats things
like how Go code is formatted), but almost all of the go tooling sticks to
similar principles and its fantastic IMO. No more pointless arguments about
style because your config file doesn't match your coworkers, but you both have
_great_ reasons for why _your_ configuration is the right one.

I guess it's less a problem with linting, so long as your local configuration
is more strict than any run during CI, or other validation steps, but still,
in this case I'd prefer to have less control to match the rest of the
ecosystem.

~~~
staticassertion
This boogeyman of "pointless arguments" is so strange.

Other than on the internet, I've never experienced pointless bikeshed
arguments. So long as _within an organization_ you keep the same standards,
what difference does it make? Everywhere I've worked does this and it's _fine_
\- and allows us to be break from patterns handed down to us from people doing
a different job.

~~~
shabbyrobe
That's your anecdata though, mine's very very different indeed. Many of the
places I've worked have either actively fought attempts to get some
consistency in place, or have lapsed into total anarchy, even in some cases
with edit wars showing up in the Git history. It's horrible, and I'm glad
you've been able to avoid it. Go's way is better - those things just can't
happen.

There's a network effect too. Sooner or later you'll start to notice that not
only does all your organisation's code look consistent, dependencies you pull
in look extremely consistent too, as if other organisations were following the
same interpretation of the Golden Rule yours is following.

This has enormous benefits when you're assessing the quality of a dependency
because once again, you get to walk straight past the same thousand pointless
and distracting arguments you got to walk past internally (well, not you of
course, but those of us who have been stuck having them!) and get right to the
meat of the quality of the code you're assessing for inclusion. "Are the
idioms sensible? Are the errors being propagated correctly? Is the public API
neat and tidy?" That stuff, the real stuff, is all visible much more quickly
when you're not rage-twitching because some other developer from some other
team on the other side of the world likes to put the curly brace on a new line
at the same indent level as the function body.

I had never experienced this unique benefit with any language ecosystem I
worked with before Go and I'm loath to leave it behind. I'm incredibly
heartened to see tools like Prettier and Black making strides in the
Javascript and Python communities respectively.

------
twblalock
I understand the use of linters in interpreted languages. But I'd rather see
this kind of stuff done as compiler warnings in compiled languages.

Ideally, one could configure the compiler to treat specified warnings as
errors and fail the build if they are fired.

~~~
_ph_
No, please not! It is a feature of the Go compiler, that it does not produce
warnings.

------
devdrew
We already have go fmt, vet, and integrated vet in go test. thumbs down

