repostatus/git.go

344 lines
8.8 KiB
Go

package repostatus
import (
"strings"
"unicode/utf8"
"io/ioutil"
"go.wit.com/log"
)
func (rs *RepoStatus) String() string {
return rs.path.String()
}
/*
func (rs *RepoStatus) GetPath() string {
return rs.path.String()
}
*/
func (rs *RepoStatus) GetCurrentBranchName() string {
return rs.currentBranch.String()
}
func (rs *RepoStatus) GetCurrentBranchVersion() string {
return rs.currentVersion.String()
}
func (rs *RepoStatus) GetLastTagVersion() string {
return rs.lasttag.String()
}
func (rs *RepoStatus) getCurrentBranchName() string {
out := run(rs.realPath.String(), "git", "branch --show-current")
log.Log(INFO, "getCurrentBranchName() =", out)
rs.currentBranch.SetValue(out)
return out
}
func (rs *RepoStatus) getCurrentBranchVersion() string {
out := run(rs.realPath.String(), "git", "describe --tags")
log.Log(INFO, "getCurrentBranchVersion()", out)
rs.currentVersion.SetValue(out)
return out
}
func (rs *RepoStatus) getLastTagVersion() string {
out := run(rs.realPath.String(), "git", "rev-list --tags --max-count=1")
log.Log(INFO, "getLastTagVersion()", out)
// rs.lasttagrev = out
lastreal := "describe --tags " + out
// out = run(r.path, "git", "describe --tags c871d5ecf051a7dc4e3a77157cdbc0a457eb9ae1")
out = run(rs.realPath.String(), "git", lastreal)
rs.lasttag.SetValue(out)
rs.tagsDrop.SetText(out)
// rs.lastLabel.SetText(out)
return out
}
func (rs *RepoStatus) populateTags() {
tmp := rs.realPath.String() + "/.git/refs/tags"
log.Log(INFO, "populateTags() path =", tmp)
for _, tag := range listFiles(tmp) {
if rs.tags[tag] == "" {
log.Log(INFO, "populateTags() Adding new tag", tag)
rs.tagsDrop.AddText(tag)
rs.tags[tag] = "origin"
}
}
// rs.tagsDrop.SetText(rs.lasttagrev)
}
func (rs *RepoStatus) getBranches() []string {
var all []string
var heads []string
var remotes []string
heads = listFiles(rs.realPath.String() + "/.git/refs/heads")
remotes = listFiles(rs.realPath.String() + "/.git/refs/remotes")
all = heads
all = append(all, remotes...)
for _, branch := range all {
log.Log(INFO, "getBranches()", branch)
}
return all
}
func (rs *RepoStatus) CheckDirty() bool {
cmd := []string{"git", "status"}
path := rs.realPath.String()
err, b, out := RunCmd(path, cmd)
if err != nil {
log.Warn("CheckDirty() b =", b)
log.Warn("CheckDirty() cmd =", cmd)
log.Warn("CheckDirty() path =", path)
log.Warn("CheckDirty() out =", out)
log.Warn("CheckDirty() err =", err)
log.Error(err, "CheckDirty() error")
rs.dirtyLabel.SetValue("error")
return true
}
last := out[strings.LastIndex(out, "\n")+1:]
if last == "nothing to commit, working tree clean" {
log.Log(INFO, "CheckDirty() b =", b, "path =", path, "out =", out)
log.Log(INFO, "CheckDirty() no", rs.realPath.String())
rs.dirtyLabel.SetValue("no")
return false
}
// sometimes b gets exit status 1 when there isn't anything that has changed
// run git status fixes that for some reason.
log.Log(WARN, "CheckDirty() true", rs.realPath.String())
log.Log(WARN, "CheckDirty() cmd =", cmd)
log.Log(WARN, "CheckDirty() b =", b)
log.Log(WARN, "CheckDirty() path =", path)
log.Log(WARN, "CheckDirty() out =", out)
log.Log(WARN, "CheckDirty() err =", err)
rs.dirtyLabel.SetValue("dirty")
return true
}
func (rs *RepoStatus) CheckoutBranch(branch string) (string, string) {
// run(rs.realPath.String(), "git", "checkout " + branch)
realname := rs.getCurrentBranchName()
realversion := rs.getCurrentBranchVersion()
log.Log(INFO, rs.realPath.String(), "realname =", realname, "realversion =", realversion)
return realname, realversion
}
func (rs *RepoStatus) checkoutBranch(level string, branch string) {
if rs.CheckDirty() {
log.Log(INFO, "checkoutBranch() checkDirty() == true for repo", rs.realPath.String(), "looking for branch:", branch)
return
}
out := run(rs.realPath.String(), "git", "checkout "+branch)
log.Log(INFO, rs.realPath.String(), "git checkout "+branch, "returned", out)
realname := rs.getCurrentBranchName()
realversion := rs.getCurrentBranchVersion()
log.Log(INFO, rs.realPath.String(), "realname =", realname, "realversion =", realversion)
switch level {
case "master":
rs.masterBranchVersion.SetValue(realversion)
case "devel":
rs.develBranchVersion.SetValue(realversion)
case "user":
rs.userBranchVersion.SetValue(realversion)
default:
}
}
func (rs *RepoStatus) SetMainWorkingName(s string) {
if rs == nil {
log.Info("rs == nil", s)
return
}
if rs.gitConfig == nil {
log.Info("rs.gitConfig == nil", s)
rs.mainWorkingName.SetValue(s)
return
}
if rs.gitConfig.branches == nil {
log.Info("rs.gitConfig.branches == nil", s)
rs.mainWorkingName.SetValue(s)
return
}
_, ok := rs.gitConfig.branches[s]
if ok {
log.Info("git branch", s, "seems to exist")
rs.mainWorkingName.SetValue(s)
return
}
s = "master"
_, ok = rs.gitConfig.branches[s]
if ok {
log.Info("git branch", s, "seems to exist")
rs.mainWorkingName.SetValue(s)
return
}
s = "main"
_, ok = rs.gitConfig.branches[s]
if ok {
log.Info("git branch", s, "seems to exist")
rs.mainWorkingName.SetValue(s)
return
}
s = "notsure"
log.Warn("git branch", s, "does not seem to exist. TODO: figure out the server default")
for name, _ := range rs.gitConfig.branches {
log.Warn("git branch found. use this?", name)
}
rs.mainWorkingName.SetValue(s)
}
func (rs *RepoStatus) SetDevelWorkingName(s string) {
rs.develWorkingName.SetValue(s)
rs.develBranchVersion.SetLabel(s)
}
func (rs *RepoStatus) SetUserWorkingName(s string) {
rs.userWorkingName.SetValue(s)
rs.userBranchVersion.SetLabel(s)
// rs.userDrop.SetText(s)
}
// returns "master", "devel", os.Username, etc
func (rs *RepoStatus) GetMasterBranchName() string {
name := rs.mainWorkingName.String()
return name
}
func (rs *RepoStatus) GetDevelBranchName() string {
name := rs.develWorkingName.String()
return name
}
func (rs *RepoStatus) GetUserBranchName() string {
name := rs.userWorkingName.String()
return name
}
// returns the git versions like "1.3-2-laksdjf" or whatever
func (rs *RepoStatus) GetMasterVersion() string {
name := rs.masterBranchVersion.String()
return name
}
func (rs *RepoStatus) GetDevelVersion() string {
name := rs.develBranchVersion.String()
return name
}
func (rs *RepoStatus) GetUserVersion() string {
name := rs.userBranchVersion.String()
return name
}
func (rs *RepoStatus) SetMasterVersion(s string) {
if rs.GetMasterVersion() == s {
return
}
rs.changed = true
log.Verbose("git", rs.GetMasterBranchName(), "is now version =", s)
rs.masterBranchVersion.SetValue(s)
}
func (rs *RepoStatus) SetDevelVersion(s string) {
if rs.GetDevelVersion() == s {
return
}
rs.changed = true
rs.develBranchVersion.SetValue(s)
log.Verbose("git", rs.GetDevelBranchName(), "s now version =", s)
}
func (rs *RepoStatus) SetUserVersion(s string) {
if rs.GetUserVersion() == s {
return
}
rs.changed = true
rs.userBranchVersion.SetValue(s)
// log.Verbose("git", rs.GetUserBranchName(), "is now version =", s)
}
func (rs *RepoStatus) GetStatus() string {
rs.changed = false
if rs.CheckDirty() {
log.Log(INFO, "CheckDirty() true")
return "dirty"
}
if rs.userBranchVersion.String() != rs.develBranchVersion.String() {
return "merge to devel"
}
if rs.develBranchVersion.String() != rs.masterBranchVersion.String() {
return "merge to main"
}
if rs.lasttag.String() != rs.masterBranchVersion.String() {
return "ready to tag version"
}
if rs.CheckBranches() {
log.Log(INFO, "Branches are Perfect")
return "PERFECT"
}
log.Log(INFO, rs.String(), "Branches are not Perfect")
return "unknown branches"
}
// TODO: make this report the error somewhere
func (rs *RepoStatus) CheckBranches() bool {
var hashCheck string
var perfect bool = true
all := rs.getBranches()
path := rs.realPath.String() + "/.git/refs/"
for _, b := range all {
parts := strings.Split(b, "/")
rdir := "heads"
if len(parts) == 2 {
rdir = "remotes"
}
fullfile := path + "/" + rdir + "/" + b
// check if the ref name is "HEAD". if so, skip
runeCount := utf8.RuneCountInString(fullfile)
// Convert the string to a slice of runes
runes := []rune(fullfile)
// Slice the last 4 runes
lastFour := runes[runeCount-4:]
if string(lastFour) == "HEAD" {
log.Log(INFO, "skip HEAD fullfile", fullfile)
continue
}
content, _ := ioutil.ReadFile(fullfile)
hash := strings.TrimSpace(string(content))
if hashCheck == "" {
hashCheck = hash
}
var cmd []string
cmd = append(cmd, "git", "show", "-s", "--format=%ci", hash)
_, _, output := RunCmd(rs.realPath.String(), cmd)
// git show -s --format=%ci <hash> will give you the time
// log.Log(INFO, fullfile)
if hash == hashCheck {
log.Log(INFO, hash, output, b)
} else {
log.Warn("UNKNOWN BRANCHES IN THIS REPO")
rs.versionCmdOutput.SetText("UNKNOWN BRANCHES")
perfect = false
parts := strings.Split(b, "/")
log.Warn("git push", parts)
}
}
return perfect
}