Thanks Ian for the fast and authoritative answer. I'll do what you suggest.
Cheers, Tom On Tuesday, March 31, 2020 at 2:31:19 AM UTC+1, Ian Lance Taylor wrote: > > On Mon, Mar 30, 2020 at 6:22 PM Tom Payne <twp...@gmail.com <javascript:>> > 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/99265a86-1f78-407f-8b70-6152a595c99a%40googlegroups.com.