Hi,

Go's backwards compatibility guarantee is fantastic, but only applies to 
the language, not the standard library. How to I cause a build-time failure 
if someone tries to build my project with a too-old Go version?

I have a Go project that uses (or would like to use) a few features 
introduced in the standard library more recently, e.g. the %w verb in 
fmt.Errorf for wrapping errors (introduced in Go 1.13 
<https://golang.org/doc/go1.13#error_wrapping>), and a fix to the 
text/template library (merged for Go 1.14 
<https://github.com/golang/go/issues/34483>). The nature of these features 
and fixes mean that my code will compile and build fine, but will fail at 
runtime when a codepath that relies on the feature or fix is executed, 
which will result in a late, weird error. I would like an early, loud 
failure at build time instead.

What's the best way to achieve this? As far as I can tell, there are a few 
options:


The Go version can be determined by either the runtime.Version() function 
or by the presence of build flags (e.g. go1.13, go1.14, etc.).


Calling runtime.Version() cannot result in a build time error (it can only 
be called once the code is running, which can only happen after a 
successful build) but could be used in either a test (so the old Go version 
gets caught when "go test" is run) or in an init() function to (say) panic 
on startup when tests or the program are run. This would look something 
like:

    import "runtime"

    func init() {
        if runtime.Version() < "1.13" { // string comparisons are not a 
good way to compare version strings, but you get the idea
            panic("go version too old")
        }
    }


I can create a Go file with build flags that is only built on older 
versions of Go, something like:

    // +build !go1.13

    build with go 1.13 or later // this is deliberately not valid go syntax

This causes an error if built with an earlier version of Go than 1.13, but 
the error message isn't very intuitive (something like "filename.go:3:1: 
expected 'package', found build") and the invalid Go syntax might confuse 
other Go tooling which tends to assume that every .go file contains 
more-or-less valid Go code.


Please note that I want to use these Go standard library features and fixes 
and provide an early, loud warning if they are not available. I know that I 
can use build flags to provide different code to different Go versions, but 
if I do that then I still have to maintain code for older Go versions. The 
core of this question is: how do I get a build error if my Go version is 
too old?


What's the recommended way to ensure a minimum Go version at build time? 
One of the above suggestions or another way?

Many thanks,
Tom



-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/7c9f2948-4187-4ccf-aebe-c524965a8be4%40googlegroups.com.

Reply via email to