github.com/moby/docker@v26.1.3+incompatible/internal/mod/mod.go (about)

     1  package mod
     2  
     3  import (
     4  	"runtime/debug"
     5  	"sync"
     6  
     7  	"golang.org/x/mod/module"
     8  	"golang.org/x/mod/semver"
     9  )
    10  
    11  var (
    12  	buildInfoOnce sync.Once
    13  	buildInfo     *debug.BuildInfo
    14  )
    15  
    16  func Version(name string) (modVersion string) {
    17  	return moduleVersion(name, readBuildInfo())
    18  }
    19  
    20  func moduleVersion(name string, bi *debug.BuildInfo) (modVersion string) {
    21  	if bi == nil {
    22  		return
    23  	}
    24  	// iterate over all dependencies and find buildkit
    25  	for _, dep := range bi.Deps {
    26  		if dep.Path != name {
    27  			continue
    28  		}
    29  		// get the version of buildkit dependency
    30  		modVersion = dep.Version
    31  		if dep.Replace != nil {
    32  			// if the version is replaced, get the replaced version
    33  			modVersion = dep.Replace.Version
    34  		}
    35  		if !module.IsPseudoVersion(modVersion) {
    36  			return
    37  		}
    38  		// if the version is a pseudo version, get the base version
    39  		// e.g. v0.10.7-0.20230306143919-70f2ad56d3e5 => v0.10.6
    40  		if base, err := module.PseudoVersionBase(modVersion); err == nil && base != "" {
    41  			// set canonical version of the base version (removes +incompatible suffix)
    42  			// e.g. v2.1.2+incompatible => v2.1.2
    43  			base = semver.Canonical(base)
    44  			// if the version is a pseudo version, get the revision
    45  			// e.g. v0.10.7-0.20230306143919-70f2ad56d3e5 => 70f2ad56d3e5
    46  			if rev, err := module.PseudoVersionRev(modVersion); err == nil && rev != "" {
    47  				// append the revision to the version
    48  				// e.g. v0.10.7-0.20230306143919-70f2ad56d3e5 => v0.10.6+70f2ad56d3e5
    49  				modVersion = base + "+" + rev
    50  			} else {
    51  				// if the revision is not available, use the base version
    52  				modVersion = base
    53  			}
    54  		}
    55  		break
    56  	}
    57  	return
    58  }
    59  
    60  func readBuildInfo() *debug.BuildInfo {
    61  	buildInfoOnce.Do(func() {
    62  		buildInfo, _ = debug.ReadBuildInfo()
    63  	})
    64  	return buildInfo
    65  }