version/mkversion: don't break on tagged go.mod entries

I thought our versioning scheme would make go.mod include a commit hash
even on stable builds. I was wrong. Fortunately, the rest of this code
wants anything that 'git rev-parse' understands (to convert it into a full
git hash), and tags qualify.

Signed-off-by: David Anderson <danderson@tailscale.com>
This commit is contained in:
David Anderson 2023-03-14 14:09:59 -07:00 committed by Dave Anderson
parent 6d3490f399
commit 9ebab961c9

View File

@ -150,14 +150,14 @@ func InfoFrom(dir string) (VersionInfo, error) {
} }
// Note, this mechanism doesn't correctly support go.mod replacements, // Note, this mechanism doesn't correctly support go.mod replacements,
// or go workdirs. We only parse out the commit hash from go.mod's // or go workdirs. We only parse out the commit ref from go.mod's
// "require" line, nothing else. // "require" line, nothing else.
tailscaleHash, err := tailscaleModuleHash(modBs) tailscaleRef, err := tailscaleModuleRef(modBs)
if err != nil { if err != nil {
return VersionInfo{}, err return VersionInfo{}, err
} }
v, err := infoFromCache(tailscaleHash, runner) v, err := infoFromCache(tailscaleRef, runner)
if err != nil { if err != nil {
return VersionInfo{}, err return VersionInfo{}, err
} }
@ -171,9 +171,10 @@ func InfoFrom(dir string) (VersionInfo, error) {
return mkOutput(v) return mkOutput(v)
} }
// tailscaleModuleHash returns the git hash of the 'require tailscale.com' line // tailscaleModuleRef returns the git ref of the 'require tailscale.com' line
// in the given go.mod bytes. // in the given go.mod bytes. The ref is either a short commit hash, or a git
func tailscaleModuleHash(modBs []byte) (string, error) { // tag.
func tailscaleModuleRef(modBs []byte) (string, error) {
mod, err := modfile.Parse("go.mod", modBs, nil) mod, err := modfile.Parse("go.mod", modBs, nil)
if err != nil { if err != nil {
return "", err return "", err
@ -187,7 +188,8 @@ func tailscaleModuleHash(modBs []byte) (string, error) {
if i := strings.LastIndexByte(req.Mod.Version, '-'); i != -1 { if i := strings.LastIndexByte(req.Mod.Version, '-'); i != -1 {
return req.Mod.Version[i+1:], nil return req.Mod.Version[i+1:], nil
} }
return "", fmt.Errorf("couldn't parse git hash from tailscale.com version %q", req.Mod.Version) // If there are no dashes, the version is a tag.
return req.Mod.Version, nil
} }
return "", fmt.Errorf("no require tailscale.com line in go.mod") return "", fmt.Errorf("no require tailscale.com line in go.mod")
} }
@ -310,7 +312,7 @@ type verInfo struct {
// sentinel patch number. // sentinel patch number.
const unknownPatchVersion = 9999999 const unknownPatchVersion = 9999999
func infoFromCache(shortHash string, runner dirRunner) (verInfo, error) { func infoFromCache(ref string, runner dirRunner) (verInfo, error) {
cacheDir, err := os.UserCacheDir() cacheDir, err := os.UserCacheDir()
if err != nil { if err != nil {
return verInfo{}, fmt.Errorf("Getting user cache dir: %w", err) return verInfo{}, fmt.Errorf("Getting user cache dir: %w", err)
@ -324,16 +326,16 @@ func infoFromCache(shortHash string, runner dirRunner) (verInfo, error) {
} }
} }
if !r.ok("git", "cat-file", "-e", shortHash) { if !r.ok("git", "cat-file", "-e", ref) {
if !r.ok("git", "fetch", "origin") { if !r.ok("git", "fetch", "origin") {
return verInfo{}, fmt.Errorf("updating OSS repo failed") return verInfo{}, fmt.Errorf("updating OSS repo failed")
} }
} }
hash, err := r.output("git", "rev-parse", shortHash) hash, err := r.output("git", "rev-parse", ref)
if err != nil { if err != nil {
return verInfo{}, err return verInfo{}, err
} }
date, err := r.output("git", "log", "-n1", "--format=%ct", shortHash) date, err := r.output("git", "log", "-n1", "--format=%ct", ref)
if err != nil { if err != nil {
return verInfo{}, err return verInfo{}, err
} }