Vectrum
Sign In
68 lines · 2.7 KB · Go
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.2"

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-<time>-<hash>: true, but a worse answer than defaultVersion for
// someone building the tree they have checked out. So only a tag counts.
// "(devel)" is what a build with no version control information gets, and a
// "+dirty" suffix means the tree had uncommitted changes, which is not the
// tagged source either.
func isRelease(v string) bool {
	if v == "" || v == "(devel)" || strings.Contains(v, "+") {
		return false
	}
	return !pseudoVersion.MatchString(v)
}