package main import ( "regexp" "runtime/debug" "strings" ) // defaultVersion is the version of this source tree, and what a build that // carries no better answer reports: a go build or go run from a checkout. It // is bumped with each release, in the same commit the tag is cut from, so a // build from that commit says the same thing however it was made. const defaultVersion = "v0.6.0" func init() { version = resolveVersion(version, debug.ReadBuildInfo) } // resolveVersion picks the version to report, trying the sources from the // most to the least deliberate: // // 1. stamped, which is whatever -ldflags "-X main.version=..." put there. // goreleaser does this for every release archive, from the tag being // built, so it is the one answer that cannot be stale. // 2. The main module's version in the build info. go install // github.com/johannSo/codey/cmd/codey@v0.7.0 records v0.7.0 there, and // no flag is involved, so without this such an install would report // whatever defaultVersion said at that commit — right only if someone // remembered to bump it. // 3. defaultVersion. // // The build info is passed in rather than read here so the order can be // tested; a test binary's own build info says nothing useful. func resolveVersion(stamped string, buildInfo func() (*debug.BuildInfo, bool)) string { if v := strings.TrimSpace(stamped); v != "" { // goreleaser's {{.Version}} is the tag without its v. The v goes // back on so a release reads the way every other build does: // "codey v0.7.0", not sometimes "codey 0.7.0". if v[0] >= '0' && v[0] <= '9' { v = "v" + v } return v } if info, ok := buildInfo(); ok && info != nil && isRelease(info.Main.Version) { return info.Main.Version } return defaultVersion } // pseudoVersion matches the tail Go gives a module version that is not a tag: // a fourteen-digit UTC timestamp and a twelve-character commit hash, as in // v0.0.0-20261002101500-219352e3b1c4. var pseudoVersion = regexp.MustCompile(`[-.]\d{14}-[0-9a-f]{12}$`) // isRelease reports whether a build-info module version names a tag. Since Go // 1.24 a plain go build in a git checkout stamps one too, derived from the // nearest tag and the commit, and with no tag in reach that is // v0.0.0-