On Mon, Mar 30, 2020 at 6:22 PM Tom Payne <twpa...@gmail.com> wrote:
>
> 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?

Pedantically, I would say that Go's backward compatibility does apply
to the standard library, but that what you are talking about is
forward compatibility.


> 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), and a fix to the 
> text/template library (merged for Go 1.14). 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?


I think that most people use build tags, but instead of introducing a
compilation error, they either provide reduced functionality when
built with older Go versions, or they write something like

const s = "this package requires Go 1.14" + 0

Ian

-- 
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/CAOyqgcVU4bvAwjRARnSc8B%2BdW55k1k7k8JT3K_Kp7TpyRHkEiA%40mail.gmail.com.

Reply via email to