package gitpb // runs git, parses output // types faster than you can import ( "errors" "path/filepath" "strings" "unicode" "go.wit.com/log" ) func (repo *Repo) GetLastTag() string { cmd := []string{"git", "rev-list", "--tags", "--max-count=1"} result := repo.RunQuiet(cmd) // log.Info("getLastTagVersion()", result.Stdout) if len(result.Stdout) != 1 { log.Log(GITPBWARN, "git LastTag() error:", result.Stdout) return "" } hash := result.Stdout[0] cmd = []string{"git", "describe", "--tags", "--always", hash} result = repo.RunQuiet(cmd) if len(result.Stdout) != 1 { log.Log(GITPBWARN, "git LastTag() error:", result.Stdout) return "" } return result.Stdout[0] } func (repo *Repo) GitMasterVersion() string { bname := repo.GetMasterBranchName() v, err := repo.gitVersionByName(bname) /* count := repo.LenGitTags() log.Info(repo.GoPath, "tag count", count) repo.UpdateGitTags() count = repo.LenGitTags() log.Info(repo.GoPath, "tag count", count) */ if err == nil { return v } else { log.Log(GITPBWARN, "gitpb.GitMasterVersion() error:", err) return "" } } func (repo *Repo) GitDevelVersion() string { bname := repo.GetDevelBranchName() v, err := repo.gitVersionByName(bname) if err == nil { return v } else { log.Log(GITPBWARN, "gitpb.GitDevelVersion() error:", err) return "" } } func (repo *Repo) GitUserVersion() string { bname := repo.GetUserBranchName() v, err := repo.gitVersionByName(bname) if err == nil { return v } else { log.Log(GITPBWARN, "gitpb.GitUserVersion() error:", err) return "" } } func (repo *Repo) GetCurrentBranchName() string { r := repo.RunQuiet([]string{"git", "branch", "--show-current"}) output := strings.Join(r.Stdout, "\n") if r.Error != nil { log.Log(GITPBWARN, "GetCurrentBranchName() not in a git repo?", r.Error, repo.GoPath) log.Log(GITPBWARN, "GetCurrentBranchName() output might have worked anyway:", output) } return strings.TrimSpace(output) } func (repo *Repo) GetCurrentBranchVersion() string { r := repo.RunQuiet([]string{"git", "describe", "--tags", "--always"}) output := strings.Join(r.Stdout, "\n") if r.Error != nil { log.Log(GITPBWARN, "GetCurrentBranchVersion() not in a git repo?", r.Error, repo.GoPath) log.Log(GITPBWARN, "GetCurrentBranchVersion() output might have worked anyway:", output) } return strings.TrimSpace(output) } func (repo *Repo) gitDescribeByHash(hash string) (string, error) { if hash == "" { return "", errors.New("hash was blank") } r := repo.RunQuiet([]string{"git", "describe", "--tags", "--always", hash}) out := strings.Join(r.Stdout, "\n") if r.Error != nil { log.Warn("not in a git repo or bad hash?", r.Error, repo.GoPath) return out, r.Error } return out, r.Error } // this should get the most recent tag func (repo *Repo) GetLastTagVersion() string { r := repo.RunQuiet([]string{"git", "rev-list", "--tags", "--max-count=1"}) hash := strings.Join(r.Stdout, "\n") hash = strings.TrimSpace(hash) log.Log(GITPB, "getLastTagVersion()", hash) name, _ := repo.gitDescribeByHash(hash) return name } func (repo *Repo) DebianReleaseVersion() string { lasttag := repo.GetLastTagVersion() newv := trimNonNumericFromStart(lasttag) if newv == "" { newv = "0.0" if lasttag != "" { newv += "-" + lasttag } } return newv } func (repo *Repo) DebianCurrentVersion() string { cbversion := repo.GetCurrentBranchVersion() newv := trimNonNumericFromStart(cbversion) if newv == "" { newv = "0.0" } if repo.CheckDirty() { newv += "-dirty" } return newv } func (repo *Repo) gitVersionByName(name string) (string, error) { name = strings.TrimSpace(name) if name == "" { // git will return the current tag r := repo.RunQuiet([]string{"git", "describe", "--tags", "--always"}) output := strings.Join(r.Stdout, "\n") if r.Error != nil { log.Log(GITPBWARN, "gitDescribeByName() output might have worked anyway:", output) log.Log(GITPBWARN, "gitDescribeByName() not in a git repo?", r.Error, repo.GoPath) return "", r.Error } return strings.TrimSpace(output), nil } if !repo.IsBranch(name) { // tag does not exist log.Log(GITPBWARN, "LocalTagExists()", name, "did not exist") return "", errors.New("gitDescribeByName() git fatal: Not a valid object name: " + name) } cmd := []string{"git", "describe", "--tags", "--always", name} result := repo.RunQuiet(cmd) output := strings.Join(result.Stdout, "\n") if result.Error != nil { log.Log(GITPBWARN, "cmd =", cmd) log.Log(GITPBWARN, "err =", result.Error) log.Log(GITPBWARN, "output (might have worked with error?) =", output) log.Log(GITPBWARN, "not in a git repo or bad tag?", repo.GoPath) return "", result.Error } return strings.TrimSpace(output), nil } // find a branch name // will find "master" or "devel" // will also find "v0.1.1" // or will find "patches-from-foo" // will return *any* match on any git branch because it doesn't // matter much here yet // eventually this will be worked out by forge in some future code that hasn't been made yet func (repo *Repo) IsBranch(findname string) bool { loop := repo.Tags.All() for loop.Scan() { t := loop.Next() // log.Info("LocalTagExists() tag:", t.Refname) tagname := t.Refname if strings.HasPrefix(tagname, "refs/remotes") { continue } path, filename := filepath.Split(tagname) log.Log(GITPB, "gitpb.IsBranch() tag:", path, filename, "from", repo.GoPath) if filename == findname { log.Log(GITPB, "gitpb.IsBranch() found tag:", path, filename, "from", repo.GoPath) return true } } log.Log(GITPB, "did not find tag:", findname, "in", repo.GoPath) return false } func trimNonNumericFromStart(s string) string { for i, r := range s { if unicode.IsDigit(r) { return s[i:] } } return "" }