repostatus/draw.go

479 lines
14 KiB
Go

package repostatus
import (
"strconv"
"strings"
"go.wit.com/lib/gadgets"
"go.wit.com/log"
"go.wit.com/widget"
)
// creates the actual widgets.
// it's assumed you are always passing in a box
func (rs *RepoStatus) draw(goSrcPath string, realPath string) {
if !rs.Ready() {
return
}
// display the status of the git repository
rs.drawGitStatus(goSrcPath, realPath)
// display the git branches and options
rs.drawGitBranches()
// show standard git commit and merge controls
rs.drawGitCommands()
}
func (rs *RepoStatus) drawGitBranches() {
rs.gitBranchesGroup = rs.window.Box().NewGroup("branches")
newgrid := rs.gitBranchesGroup.NewGrid("gridnuts", 2, 2)
rs.masterDrop = gadgets.NewBasicDropdown(newgrid, "main branch")
rs.masterDrop.Custom = func() {
log.Log(WARN, "Switching main branch to:", rs.masterDrop.String())
rs.masterBranchVersion.SetLabel(rs.masterDrop.String())
rs.mainWorkingName.SetValue(rs.masterDrop.String())
}
rs.develDrop = gadgets.NewBasicDropdown(newgrid, "devel branch")
rs.develDrop.Custom = func() {
log.Log(WARN, "Switching devel branch to:", rs.develDrop.String())
rs.develBranchVersion.SetLabel(rs.develDrop.String())
rs.develWorkingName.SetValue(rs.develDrop.String())
}
rs.userDrop = gadgets.NewBasicDropdown(newgrid, "user branch")
rs.userDrop.Custom = func() {
log.Log(WARN, "Switching user branch to:", rs.userDrop.String())
rs.userBranchVersion.SetLabel(rs.userDrop.String())
rs.userWorkingName.SetValue(rs.userDrop.String())
}
rs.lasttag = gadgets.NewOneLiner(newgrid, "last tag")
rs.masterBranchVersion = gadgets.NewOneLiner(newgrid, "master")
rs.develBranchVersion = gadgets.NewOneLiner(newgrid, "devel")
rs.userBranchVersion = gadgets.NewOneLiner(newgrid, "user")
rs.currentBranch = gadgets.NewOneLiner(newgrid, "current branch")
rs.currentVersion = gadgets.NewOneLiner(newgrid, "current version")
/*
var master = ""
all := rs.getBranches()
for _, branch := range all {
log.Log(INFO, "getBranches()", branch)
rs.masterDrop.AddText(branch)
rs.develDrop.AddText(branch)
rs.userDrop.AddText(branch)
if branch == "master" {
master = "master"
}
if branch == "main" {
master = "main"
}
}
*/
// relabel the various gadgets with the right branch name
// rs.masterBranchVersion.SetLabel(master)
rs.showBranchesButton = newgrid.NewButton("getBranches()", func() {
all := rs.getBranches()
i := len(all)
log.Log(WARN, "branch count =", i)
})
rs.checkBranchesButton = newgrid.NewButton("CheckBranches()", func() {
if rs.CheckBranches() {
log.Log(WARN, "Branches are perfect")
} else {
log.Log(WARN, "Branches are not perfect")
}
})
newgrid.NewButton("show .git/config", func() {
if rs.gitConfig == nil {
log.Log(WARN, "Nonexistant or damaged .git/config", rs.String())
return
}
log.Log(WARN, ".git/config:", rs.realPath.String())
// The info:
for name, remote := range rs.gitConfig.remotes {
log.Log(WARN, " ", name, "url:", remote.url)
}
for name, branch := range rs.gitConfig.branches {
log.Log(WARN, " ", name, "remote:", branch.remote, "merge", branch.merge)
}
})
newgrid.NewButton("check go.sum", func() {
if rs.ReadGoMod() {
log.Log(INFO, "parsed go.mod", rs.realPath.String())
} else {
log.Log(WARN, "Something went wrong parsing go.mod", rs.realPath.String())
}
log.Log(WARN, "go.sum:", rs.realPath.String())
for depname, version := range rs.goConfig {
log.Log(WARN, " ", depname, version)
}
})
}
func (rs *RepoStatus) drawGitStatus(goSrcPath string, realPath string) {
rs.gitStatusGroup = rs.window.Box().NewGroup("What GO Knows It Has")
newgrid := rs.gitStatusGroup.NewGrid("gridnuts", 2, 2)
newgrid.Margin()
newgrid.Pad()
rs.path = gadgets.NewOneLiner(newgrid, "path")
rs.goSrcPath = gadgets.NewOneLiner(newgrid, goSrcPath)
rs.realPath = gadgets.NewOneLiner(newgrid, realPath)
rs.realPath.Hide()
rs.mainWorkingName = gadgets.NewOneLiner(newgrid, "main working branch")
rs.mainWorkingName.SetValue("???")
rs.develWorkingName = gadgets.NewOneLiner(newgrid, "devel working branch")
rs.develWorkingName.SetValue("devel")
rs.userWorkingName = gadgets.NewOneLiner(newgrid, "user working branch")
rs.userWorkingName.SetValue("uid")
rs.tagsDrop = gadgets.NewBasicDropdown(newgrid, "all releases")
// git for-each-ref --sort=taggerdate --format '%(tag) ,,,_,,, %(subject)' refs/tags
var cmd []string
cmd = append(cmd, "git", "for-each-ref", "--sort=taggerdate", "--format", "%(tag) %(subject)", "refs/tags")
_, _, output := RunCmd(rs.realPath.String(), cmd)
log.Log(INFO, output)
for _, line := range strings.Split(output, "\n") {
rs.tagsDrop.AddText(line)
}
// rs.masterBranchVersion = gadgets.NewOneLiner(newgrid, "master")
// rs.develBranchVersion = gadgets.NewOneLiner(newgrid, "devel")
// rs.userBranchVersion = gadgets.NewOneLiner(newgrid, "user")
rs.dirtyLabel = gadgets.NewOneLiner(newgrid, "dirty")
rs.speed = gadgets.NewOneLiner(newgrid, "refresh speed =")
rs.speedActual = gadgets.NewOneLiner(newgrid, "speed actual =")
}
func (rs *RepoStatus) drawGitCommands() {
rs.gitCommandsGroup = rs.window.Box().NewGroup("git commands")
newgrid := rs.gitCommandsGroup.NewGrid("gridnuts", 2, 2)
newgrid.NewButton("update", func() {
rs.Update()
})
newgrid.NewButton("git pull", func() {
var cmd []string
cmd = append(cmd, "git", "pull")
err, b, output := RunCmd(rs.realPath.String(), cmd)
log.Warn("Did git pull here", err, b, output)
})
rs.major = gadgets.NewBasicCombobox(newgrid, "major")
rs.major.Custom = func() {
rs.setTag()
rs.generateCmd()
}
rs.minor = gadgets.NewBasicCombobox(newgrid, "minor")
rs.minor.Custom = func() {
rs.setTag()
rs.generateCmd()
}
rs.revision = gadgets.NewBasicCombobox(newgrid, "revision")
rs.revision.Custom = func() {
rs.setTag()
rs.generateCmd()
}
newgrid.NewLabel("new tag version")
rs.newversion = newgrid.NewLabel("0.0.1")
rs.versionMessage = gadgets.NewBasicEntry(newgrid, "tag message")
rs.versionMessage.Custom = func() {
rs.generateCmd()
}
rs.versionCmdOutput = gadgets.NewOneLiner(newgrid, "tag cmd")
label := "merge " + rs.masterDrop.String() + " to devel"
rs.develMerge = newgrid.NewButton(label, func() {
rs.Disable()
master := rs.masterDrop.String()
rs.checkoutBranch("master", master)
if rs.getCurrentBranchName() != master {
log.Warn("something went wrong switching to the master branch. full stop!")
return
}
if !rs.runGitCommands() {
log.Warn("SOMETHING WENT WRONG")
return
}
rs.Update()
rs.Enable()
log.Warn("THINGS SEEM OK")
})
rs.releaseVersion = newgrid.NewButton("tag and release new version", func() {
if !rs.generateCmd() {
log.Warn("something is wrong. fix the errors first")
return
}
rs.releaseVersion.Disable()
log.Warn("COMMIT IT HERE")
if !rs.runGitCommands() {
log.Warn("SOMETHING WENT WRONG")
}
rs.Update()
log.Warn("THINGS SEEM OK")
})
newgrid.Margin()
newgrid.Pad()
}
func (rs *RepoStatus) setTag() bool {
lasttag := rs.lasttag.String()
var major, minor, revision string
major, minor, revision = splitVersion(lasttag)
olda, _ := strconv.Atoi(major)
oldb, _ := strconv.Atoi(minor)
oldc, _ := strconv.Atoi(revision)
log.Log(INFO, "current version here", lasttag)
log.Log(INFO, "current release a,b,c =", major, minor, revision)
newa, _ := strconv.Atoi(rs.major.String())
newver := strconv.Itoa(newa)
if newa < olda {
log.Warn("new version bad", newver, "vs old version", lasttag, "newa =", newa, "olda =", olda)
rs.newversion.SetLabel("bad")
return false
}
if newa > olda {
log.Log(INFO, "new version ok", newver, "vs old version", lasttag)
rs.newversion.SetLabel(newver)
rs.minor.SetText("")
rs.revision.SetText("")
return true
}
newb, _ := strconv.Atoi(rs.minor.String())
newver = strconv.Itoa(newa) + "." + strconv.Itoa(newb)
if newb < oldb {
log.Warn("new version bad", newver, "vs old version", lasttag, "newb =", newb, "oldb =", oldb)
rs.newversion.SetLabel("bad")
return false
}
if newb > oldb {
log.Log(INFO, "new version ok", newver, "vs old version", lasttag)
rs.newversion.SetLabel(newver)
rs.revision.SetText("")
return true
}
newc, _ := strconv.Atoi(rs.revision.String())
newver = strconv.Itoa(newa) + "." + strconv.Itoa(newb) + "." + strconv.Itoa(newc)
if newc <= oldc {
log.Warn("new version bad", newver, "vs old version", lasttag)
rs.newversion.SetLabel("bad")
return false
}
log.Log(INFO, "new version ok", newver, "vs old version", lasttag)
rs.newversion.SetLabel(newver)
return true
}
func (rs *RepoStatus) incrementVersion() {
lasttag := rs.lasttag.String()
var major, minor, revision string
major, minor, revision = splitVersion(lasttag)
log.Warn("Should release version here", lasttag)
log.Log(INFO, "Should release a,b,c", major, minor, revision)
a, _ := strconv.Atoi(major)
b, _ := strconv.Atoi(minor)
c, _ := strconv.Atoi(revision)
rs.major.AddText(widget.GetString(a))
rs.major.AddText(widget.GetString(a + 1))
rs.major.SetText(widget.GetString(a))
rs.minor.AddText(widget.GetString(b))
rs.minor.AddText(widget.GetString(b + 1))
rs.minor.SetText(widget.GetString(b))
// rs.c := strconv.Atoi(revision)
rs.revision.AddText(widget.GetString(c + 1))
rs.revision.AddText(widget.GetString(c + 2))
rs.revision.SetText(widget.GetString(c + 1))
}
func (rs *RepoStatus) recommend() {
log.Log(INFO, "Is repo dirty?", rs.dirtyLabel.String())
log.Log(INFO, "list the known tags")
rs.DisableEverything()
rs.populateTags()
log.Log(INFO, "Does devel == user?", rs.develBranchVersion.String(), rs.userBranchVersion.String())
if rs.develBranchVersion.String() != rs.userBranchVersion.String() {
log.Log(INFO, "devel does not equal user")
log.Log(INFO, "merge or squash?")
rs.EnableMergeDevel()
rs.setMergeUserCommands()
label := "merge user into " + rs.GetDevelBranchName()
rs.develMerge.SetLabel(label)
return
}
log.Log(INFO, "Does master == devel? ", rs.masterBranchVersion.String(), rs.develBranchVersion.String())
if rs.masterBranchVersion.String() != rs.develBranchVersion.String() {
log.Log(INFO, "master does not equal devel. merge devel into master")
rs.EnableMergeDevel()
rs.setMergeDevelCommands()
label := "merge devel into " + rs.GetMasterBranchName()
rs.develMerge.SetLabel(label)
return
}
rs.getLastTagVersion()
if rs.lasttag.String() != rs.masterBranchVersion.String() {
log.Log(INFO, "master does not equal last tag")
rs.incrementVersion()
rs.EnableSelectTag()
rs.setTag()
return
}
log.Log(INFO, "Is repo pushed upstream? git.wit.org or github?")
}
func (rs *RepoStatus) generateCmd() bool {
// the length of 24 is arbitrary, but should be short
// they should be things like perhaps, major release names
// or something the users might see.
// aka: "Topsy", "Picasso", "Buzz", etc
if !rs.setTag() {
log.Log(INFO, "tag sucked. fix your tag version")
rs.versionMessage.SetLabel("tag message (bad version)")
rs.releaseVersion.Disable()
return false
}
log.Log(INFO, "tag is valid!!!!")
rs.setGitCommands()
if rs.versionMessage.String() == "" {
log.Log(INFO, "tag message is empty!!!!")
rs.releaseVersion.Disable()
return false
}
if len(rs.versionMessage.String()) > 24 {
rs.versionMessage.SetLabel("tag message (too long)")
} else {
rs.versionMessage.SetLabel("tag message")
}
rs.releaseVersion.Enable()
return true
}
func (rs *RepoStatus) runGitCommands() bool {
for _, line := range rs.versionCmds {
s := strings.Join(line, " ")
log.Log(INFO, "NEED TO RUN:", s)
rs.develMerge.SetText(s)
err, b, output := runCmd(rs.realPath.String(), line)
if err != nil {
log.Warn("ABEND EXECUTION")
log.Warn("error =", err)
log.Warn("output =", output)
return false
}
log.Log(INFO, "Returned with b =", b)
log.Log(INFO, "output was =", output)
log.Log(INFO, "RUN DONE")
}
return true
}
func (rs *RepoStatus) setGitCommands() {
var line1, line2, line3 []string
var all [][]string
newTag := rs.newversion.String()
line1 = append(line1, "git", "tag", "v"+newTag, "-m", rs.versionMessage.String())
all = append(all, line1)
line2 = append(line2, "git", "push", "--tags")
all = append(all, line2)
line3 = append(line3, "git", "push", "--prune", "--tags")
all = append(all, line3)
rs.versionCmds = all
var tmp []string
// convert to displayable to the user text
for _, line := range all {
s := strings.Join(line, " ")
log.Log(INFO, "s =", s)
tmp = append(tmp, s)
}
rs.versionCmdOutput.SetValue(strings.Join(tmp, "\n"))
}
func (rs *RepoStatus) setMergeDevelCommands() {
var line1, line2, line3 []string
var all [][]string
master := rs.GetMasterBranchName()
devel := rs.GetDevelBranchName()
line1 = append(line1, "git", "checkout", master)
all = append(all, line1)
line2 = append(line2, "git", "merge", devel)
all = append(all, line2)
line3 = append(line3, "git", "push")
all = append(all, line3)
rs.versionCmds = all
var tmp []string
// convert to displayable to the user text
for _, line := range all {
s := strings.Join(line, " ")
log.Log(INFO, "s =", s)
tmp = append(tmp, s)
}
rs.versionCmdOutput.SetValue(strings.Join(tmp, "\n"))
}
func (rs *RepoStatus) setMergeUserCommands() {
var line1, line2, line3 []string
var all [][]string
devel := rs.GetDevelBranchName()
user := rs.GetUserBranchName()
line1 = append(line1, "git", "checkout", devel)
all = append(all, line1)
line2 = append(line2, "git", "merge", user)
all = append(all, line2)
line3 = append(line3, "git", "push")
all = append(all, line3)
rs.versionCmds = all
var tmp []string
// convert to displayable to the user text
for _, line := range all {
s := strings.Join(line, " ")
log.Log(INFO, "s =", s)
tmp = append(tmp, s)
}
rs.versionCmdOutput.SetValue(strings.Join(tmp, "\n"))
}