Staticcheck 2019.1 Release Notes

Big restructuring

At the core of the 2019.1 release lies the grand restructuring
of all of the staticcheck tools.
All of the individual checkers,
as well as megacheck,
have been merged into a single tool,
which is simply called staticcheck.
From this point forward,
staticcheck will be the static analyzer for Go code.
It will cover all of the existing categories of checks –
bugs, simplifications, performance –
as well as future categories, such as the new style checks.

This change makes a series of simplifications possible.
Per-tool command line flags in megacheck have been replaced
with unified flags
(-checks and -fail)
that operate on arbitrary subsets of checks.
Consumers of the JSON output no longer need to know about different checker names
and can instead rely solely on user-controllable severities.
And not to be neglected: gone is the silly name of megacheck.

This change will require some changes to your pipelines.
Even though the gosimple, unused, and megacheck tools still exist,
they have been deprecated
and will be removed in the next release of staticcheck.
Additionally, megacheck's -<tool>.exit-non-zero flags have been rendered inoperable.
Instead, you will have to use the -fail flag.
Furthermore,, -fail defaults to all,
meaning all checks will cause non-zero exiting.
Previous versions of megacheck had different defaults for different checkers,
trying to guess the user's intention.
Instead of guessing,
staticcheck expects you to provide the correct flags.

Since all of the tools have been merged into staticcheck,
it will no longer run just one group of checks.
This may lead to additional problems being reported.
To restore the old behavior, you can use the new -checks flag.
-checks "SA*" will run the same set of checks
that the old staticcheck tool did.
The same flag should be used in place of megacheck's –
now deprecated –
-<tool>.enabled flags.

Configuration files

Staticcheck 2019.1 adds support for per-project configuration files.
With these it will be possible to standardize and codify linter settings,
the set of enabled checks,
and more.
Please see the
documentation page on configuration
for all the details!

Build system integration

Beginning with this release,
staticcheck calls out to the tools of the underlying build system
(go for most people)
to determine the list of Go files to process.
This change should not affect most people.
It does, however, have some implications:
the system that staticcheck runs on needs access to a full Go toolchain –
just the source code of the standard library no longer suffices.
Furthermore, setting GOROOT to use a different Go installation no longer works as expected.
Instead, PATH has to be modified so that go resolves to the desired Go command.

This change has been necessary to support Go modules.
Additionally, it will allow us to support alternative build systems
such as Bazel
in the future.

Handling of broken packages

We have redesigned the way staticcheck handles broken packages.
Previously, if you ran staticcheck ...
and any package wouldn't compile,
staticcheck would refuse to check any packages whatsoever.
Now, it will skip broken packages,
as well as any of their dependents,
and check only the remaining packages.
Any build errors that are encountered will be reported as problems.

Checks

New checks

Staticcheck 2019.1 adds a new category of checks, ST1.
ST1 contains checks for common style violations –
poor variable naming,
incorrectly formatted comments
and the like.
It brings the good parts of golint to staticcheck,
and adds some checks of its own.

In addition, some other checks have been added.

S1032 recommends replacing
sort.Sort(sort.StringSlice(...))
with
sort.Strings(...);
similarly for other types that have helpers for sorting.

SA9004 flags groups of constants where only the first one is given an explicit type.

Removed checks

S1013 has been removed,
no longer suggesting replacing if err != nil { return err }; return nil with return err.
This check has been the source of contention
and more often than not,
it reduced the consistency of the surrounding code.

Deprecation notices

This release deprecates various features of staticcheck.
These features will be removed in the next release.

As already explained earlier,
the unused, gosimple, and megacheck tools
have been replaced by staticcheck.
Similarly, the flags -<tool>.enabled and -<tool>.exit-non-zero
have been replaced by -checks and -fail.
Finally, the -ignore flag has been replaced
by linter directives.

Binary releases

Beginning with this release,
we're publishing prebuilt binaries to GitHub.
These releases still require a functioning Go installation in order to operate, however.

Other changes

We've removed the -min_confidence flag.
This flag hasn't been doing anything for years.

A new formatter called Stylish
(usable with -f stylish)
provides output that is designed for easier consumption by humans.

Due to the restructuring of checkers,
the checker field in JSON output has been replaced
with the severity field.