package version import ( "strconv" "strings" ) // Version and Commit are injected separately at link time via -ldflags (see Makefile / Dockerfile). // Version is the exact git tag on HEAD (empty if untagged). Commit is the short git hash (empty if unavailable). var ( Version = "" Commit = "" ) func resolve() string { if isSemverTag(Version) { return Version } if Commit != "" { return Commit } return "dev" } func String() string { return resolve() } func Display() string { return resolve() } // isSemverTag reports whether tag looks like semver (optional "v" + major.minor.patch, pre-release suffix allowed). func isSemverTag(tag string) bool { if tag == "" { return false } core := tag if i := strings.IndexAny(core, "-+"); i >= 0 { core = core[:i] } core = strings.TrimPrefix(core, "v") parts := strings.Split(core, ".") if len(parts) != 3 { return false } for _, p := range parts { if p == "" { return false } for _, c := range p { if c < '0' || c > '9' { return false } } } return true } // Parts splits the git tag (Version) into major/minor/revision for NPM-style API responses. // Returns zeros when there is no semver tag (commit-only or dev builds). func Parts() (major, minor, revision int) { if !isSemverTag(Version) { return 0, 0, 0 } core := Version if i := strings.IndexAny(core, "-+"); i >= 0 { core = core[:i] } core = strings.TrimPrefix(core, "v") parts := strings.Split(core, ".") if len(parts) != 3 { return 0, 0, 0 } major, err0 := strconv.Atoi(parts[0]) minor, err1 := strconv.Atoi(parts[1]) revision, err2 := strconv.Atoi(parts[2]) if err0 != nil || err1 != nil || err2 != nil { return 0, 0, 0 } return major, minor, revision }