This is mingo, a library and command-line tool for analyzing Go code to determine the minimum version of Go necessary to compile it.
For the command-line tool:
go install github.com/bobg/mingo/cmd/mingo@latest
For the library:
go get github.com/bobg/mingo@latest
For library usage please see the package doc.
Command-line usage:
mingo [-v] [-deps (all|direct|none)] [-tests] [-check] [-api API] [DIR]
This command runs mingo on the Go module in the given directory DIR (the current directory by default).
The flags and their meanings are:
flag | meaning |
---|---|
-v | Run verbosely |
-deps | Dependencies to include - all (the default), direct only, or none |
-tests | Include tests |
-check | Check that go.mod declares the right version of Go or higher |
-strict | Check that go.mod declares exactly the right version of Go |
-api API | Find the Go API files in the directory API instead of the default $GOROOT/api |
Normal output is the lowest minor version of Go
(the x in Go 1.x)
that is safe to declare in the go
directive of the module’s go.mod
file.
Running with -check
causes mingo to exit with a 0 status code and no output
if the module’s go.mod
file declares the correct version of Go or higher,
or a non-zero status and an error message otherwise.
Running with -strict
is similar
but requires go.mod
to declare exactly the right version.
Including dependencies with -deps all
(the default)
allows go
directives in imported modules’ go.mod
files
to change the result.
This includes both direct and indirect imports.
Use -deps direct
to consider direct imports only,
and -deps none
to exclude imports.
What version of Go should you declare in your go.mod
file?
For maximum compatibility it should be the oldest version of Go that can compile your code.
For example, if your code uses a for range
statement that does not include a variable assignment,
you need at least Go 1.4,
which first introduced variable-free for range
statements.
And if you use the context
package from the standard library,
you need at least Go 1.7.
On the other hand if you use the function context.Cause
that requirement bumps up to Go 1.20.
One thing you should not do is to routinely increase the version in your go.mod
when a new version of Go comes out.
When you do you risk breaking compatibility for some of your callers.
Practically speaking there’s no point declaring a version of Go earlier than 1.11 in your go.mod
,
since that’s the first version that understood go.mod
files.
But mingo will still report earlier version numbers when warranted
(somewhat pedantically).
Mingo is a good illustration of how to write a static analysis tool in and for Go. See Tour.md for an in-depth discussion of how the code works.