blob: c1b35e10d5666047bc690cfea81c31c90dc67bf8 [file] [log] [blame]
package mod
import (
"runtime/debug"
"sync"
"golang.org/x/mod/module"
"golang.org/x/mod/semver"
)
var (
buildInfoOnce sync.Once
buildInfo *debug.BuildInfo
)
func Version(name string) (modVersion string) {
return moduleVersion(name, readBuildInfo())
}
func moduleVersion(name string, bi *debug.BuildInfo) (modVersion string) {
if bi == nil {
return
}
// iterate over all dependencies and find buildkit
for _, dep := range bi.Deps {
if dep.Path != name {
continue
}
// get the version of buildkit dependency
modVersion = dep.Version
if dep.Replace != nil {
// if the version is replaced, get the replaced version
modVersion = dep.Replace.Version
}
if !module.IsPseudoVersion(modVersion) {
return
}
// if the version is a pseudo version, get the base version
// e.g. v0.10.7-0.20230306143919-70f2ad56d3e5 => v0.10.6
if base, err := module.PseudoVersionBase(modVersion); err == nil && base != "" {
// set canonical version of the base version (removes +incompatible suffix)
// e.g. v2.1.2+incompatible => v2.1.2
base = semver.Canonical(base)
// if the version is a pseudo version, get the revision
// e.g. v0.10.7-0.20230306143919-70f2ad56d3e5 => 70f2ad56d3e5
if rev, err := module.PseudoVersionRev(modVersion); err == nil && rev != "" {
// append the revision to the version
// e.g. v0.10.7-0.20230306143919-70f2ad56d3e5 => v0.10.6+70f2ad56d3e5
modVersion = base + "+" + rev
} else {
// if the revision is not available, use the base version
modVersion = base
}
}
break
}
return
}
func readBuildInfo() *debug.BuildInfo {
buildInfoOnce.Do(func() {
buildInfo, _ = debug.ReadBuildInfo()
})
return buildInfo
}