| 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 | |
| } |