package main import ( "errors" "fmt" "os" "os/exec" "strings" "text/template" ) func sysCmd(name string, arg ...string) (string, error) { cmd := exec.Command(name, arg...) out, err := cmd.CombinedOutput() splitted := strings.Split(string(out), "\n") lines := make([]string, 0, len(splitted)) for _, l := range splitted { l = strings.TrimSpace(l) if l == "" { continue } lines = append(lines, l) } if len(lines) != 1 { fmt.Println(string(out)) return "", errors.New("Expects a single line") } return lines[0], err } func mustSysCmd(name string, arg ...string) string { out, err := sysCmd(name, arg...) if err != nil { panic(err) } return out } func getVersionTag(tags string) string { var candidates []string for _, t := range strings.Split(tags, " ") { if strings.HasPrefix(t, "v") { candidates = append(candidates, t) } } if len(candidates) == 0 { return "" } return candidates[0] } var outTemplate = template.Must(template.New("").Parse(`package {{ .package }} var Version = "{{ .version }}" var HgSha = "{{ .sha }}" var HgTopic = "{{ .topic }}" var HgBranch = "{{ .branch }}" var Build = "{{ .build }}" `)) func main() { sha := mustSysCmd("hg", "id", "--id") curVersion := getVersionTag(mustSysCmd("hg", "id", "--tags")) lastVersion := getVersionTag(mustSysCmd("hg", "id", "--tags", "-r", "limit(last(ancestors(.)&tag('re:v.*'))|.,1)")) modified := strings.HasSuffix(sha, "+") jobID := os.Getenv("CI_JOB_ID") topic, err := sysCmd("hg", "topic", "--current") if topic == "no active topic" { topic = "" } else if err != nil { panic(err) } branch := mustSysCmd("hg", "id", "--branch") var version string switch { case modified && lastVersion != "": version = lastVersion + "" case curVersion != "": version = curVersion case lastVersion != "": version = lastVersion + "-" + sha default: version = "v0.0.0-" + sha } vars := map[string]string{ "package": "main", "sha": sha, "version": version, "build": jobID, "topic": topic, "branch": branch, } out, err := os.Create("version.go") if err != nil { panic(err) } if err := outTemplate.Execute(out, vars); err != nil { panic(err) } }