diff --git a/common.go b/common.go index c70356e..bde96ba 100644 --- a/common.go +++ b/common.go @@ -7,79 +7,79 @@ import ( // reports externally if something has changed // since the last time it was asked about it -func (ls *RepoStatus) Changed() bool { - if ! ls.Ready() {return false} - if ls.changed { - ls.changed = false +func (rs *RepoStatus) Changed() bool { + if ! rs.Ready() {return false} + if rs.changed { + rs.changed = false return true } return false } -func (ls *RepoStatus) Make() { - if ! ls.Ready() {return} - log.Log(CHANGE, "Make() window ready =", ls.ready) - ls.window.Make() - ls.ready = true +func (rs *RepoStatus) Make() { + if ! rs.Ready() {return} + log.Log(CHANGE, "Make() window ready =", rs.ready) + rs.window.Make() + rs.ready = true } -func (ls *RepoStatus) Draw() { - if ! ls.Ready() {return} - log.Log(CHANGE, "Draw() window ready =", ls.ready) - ls.window.Draw() - ls.ready = true +func (rs *RepoStatus) Draw() { + if ! rs.Ready() {return} + log.Log(CHANGE, "Draw() window ready =", rs.ready) + rs.window.Draw() + rs.ready = true } -func (ls *RepoStatus) Draw2() { - if ! ls.Ready() {return} - log.Log(CHANGE, "draw(ls) ready =", ls.ready) - draw(ls) +func (rs *RepoStatus) Draw2() { + if ! rs.Ready() {return} + log.Log(CHANGE, "draw(rs) ready =", rs.ready) + draw(rs) } -func (ls *RepoStatus) Show() { - if ! ls.Ready() {return} - log.Log(CHANGE, "Show() window ready =", ls.ready) - ls.window.Show() - ls.hidden = false +func (rs *RepoStatus) Show() { + if ! rs.Ready() {return} + log.Log(CHANGE, "Show() window ready =", rs.ready) + rs.window.Show() + rs.hidden = false } -func (ls *RepoStatus) Hide() { - if ! ls.Ready() {return} - log.Log(CHANGE, "Hide() window ready =", ls.ready) - ls.window.Hide() - ls.hidden = true +func (rs *RepoStatus) Hide() { + if ! rs.Ready() {return} + log.Log(CHANGE, "Hide() window ready =", rs.ready) + rs.window.Hide() + rs.hidden = true } -func (ls *RepoStatus) Toggle() { - if ! ls.Ready() {return} - log.Log(CHANGE, "Toggle() window ready =", ls.ready) - if ls.hidden { - ls.Show() +func (rs *RepoStatus) Toggle() { + if ! rs.Ready() {return} + log.Log(CHANGE, "Toggle() window ready =", rs.ready) + if rs.hidden { + rs.Show() } else { - ls.Hide() + rs.Hide() } } -func (ls *RepoStatus) Ready() bool { - log.Log(SPEW, "Ready() maybe not ready? ls =", ls) - if ls == nil {return false} - if ls.window == nil {return false} - return ls.ready +func (rs *RepoStatus) Ready() bool { + log.Log(SPEW, "Ready() maybe not ready? rs =", rs) + if rs == nil {return false} + if rs.window == nil {return false} + return rs.ready } -func (ls *RepoStatus) Initialized() bool { +func (rs *RepoStatus) Initialized() bool { log.Log(CHANGE, "checking Initialized()") - if ls == nil {return false} - if ls.parent == nil {return false} + if rs == nil {return false} + if rs.parent == nil {return false} return true } -func (ls *RepoStatus) SetParent(p *gui.Node) { +func (rs *RepoStatus) SetParent(p *gui.Node) { log.Log(CHANGE, "Attempting SetParent") - if ls == nil {return} - if ls.parent == nil { + if rs == nil {return} + if rs.parent == nil { log.Log(CHANGE, "SetParent =", p) - ls.parent = p + rs.parent = p return } else { - log.Log(CHANGE, "SetParent was already set to =", ls.parent) + log.Log(CHANGE, "SetParent was already set to =", rs.parent) } } diff --git a/draw.go b/draw.go index 35e8d4c..fa0edc3 100644 --- a/draw.go +++ b/draw.go @@ -2,6 +2,7 @@ package repostatus import ( "strconv" + "strings" "go.wit.com/log" "go.wit.com/gui/gadgets" @@ -12,18 +13,16 @@ import ( func draw(rs *RepoStatus) { if ! rs.Ready() {return} rs.group = rs.window.Box().NewGroup("What GO Knows It Has") - rs.grid = rs.group.NewGrid("gridnuts", 2, 2) - rs.grid.SetNext(1,1) + rs.grid.Margin() + rs.grid.Pad() rs.path = gadgets.NewOneLiner(rs.grid, "path") rs.currentBranch = gadgets.NewOneLiner(rs.grid, "branch") rs.lasttag = gadgets.NewOneLiner(rs.grid, "last tag") rs.currentVersion = gadgets.NewOneLiner(rs.grid, "Version") - - rs.grid.NewLabel("tags") - rs.tagsDrop = rs.grid.NewDropdown("tags") + rs.tagsDrop = gadgets.NewBasicDropdown(rs.grid, "existing tags") rs.masterBranch = gadgets.NewOneLiner(rs.grid, "master") rs.develBranch = gadgets.NewOneLiner(rs.grid, "devel") rs.jcarrBranch = gadgets.NewOneLiner(rs.grid, "jcarr") @@ -33,38 +32,14 @@ func draw(rs *RepoStatus) { rs.speed = gadgets.NewOneLiner(rs.grid, "refresh speed =") rs.speedActual = gadgets.NewOneLiner(rs.grid, "speed actual =") - rs.grid.NewButton("update", func() { + rs.vgroup = rs.window.Box().NewGroup("git commands") + newgrid := rs.vgroup.NewGrid("gridnuts", 2, 2) + + newgrid.NewButton("update", func() { rs.Update() }) - rs.grid.NewButton("recommend", func() { - log.Warn("Is repo dirty?", rs.dirtyLabel.Get()) - log.Warn("list the known tags") - rs.develMerge.Disable() - rs.releaseVersion.Disable() - rs.populateTags() - log.Warn("Does devel == jcarr?", rs.develBranch.Get(), rs.jcarrBranch.Get()) - if rs.develBranch.Get() != rs.jcarrBranch.Get() { - log.Warn("devel does not equal jcarr") - log.Warn("merge or squash?") - return - } - log.Warn("Does master == devel? ", rs.masterBranch.Get(), rs.develBranch.Get()) - if rs.masterBranch.Get() != rs.develBranch.Get() { - log.Warn("master does not equal devel. merge devel into master") - rs.develMerge.Enable() - return - } - rs.getLastTagVersion() - if rs.lasttag.Get() != rs.masterBranch.Get() { - log.Warn("master does not equal last tag") - rs.incrementVersion() - rs.releaseVersion.Enable() - return - } - log.Warn("Is repo pushed upstream? git.wit.org or github?") - }) - rs.develMerge = rs.grid.NewButton("merge devel to master", func() { + rs.develMerge = newgrid.NewButton("merge devel to master", func() { rs.checkoutBranch("master") if rs.getCurrentBranchName() != "master" { log.Warn("something went wrong switching to the master branch. full stop!") @@ -75,24 +50,100 @@ func draw(rs *RepoStatus) { log.Warn("devel is merged? merginess is complete. perhaps", out) rs.develMerge.Disable() // don't let this run twice for now }) - rs.develMerge.Disable() - rs.releaseVersion = rs.grid.NewButton("tag and release version", func() { - a := rs.major.Get() - b := rs.minor.Get() - c := rs.revision.Get() - newver := a + "." + b + "." + c - log.Warn("Should tag version:", newver) + rs.major = gadgets.NewBasicCombobox(newgrid, "master") + 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("3.1.4") + + rs.versionMessage = gadgets.NewBasicEntry(newgrid, "tag message") + rs.versionMessage.Custom = func () { + rs.generateCmd() + } + rs.versionCmdOutput = gadgets.NewOneLiner(newgrid, "tag cmd") + + rs.releaseVersion = newgrid.NewButton("tag and release new version", func() { + if ! rs.generateCmd() { + log.Warn("something is wrong. fix the errors first") + return + } + log.Warn("COMMIT IT HERE") + rs.runGitCommands() }) - rs.releaseVersion.Disable() - rs.vgroup = rs.window.Box().NewGroup("Version") - rs.major = gadgets.NewBasicCombobox(rs.grid, "master") - rs.minor = gadgets.NewBasicCombobox(rs.grid, "minor") - rs.revision = gadgets.NewBasicCombobox(rs.grid, "revision") + newgrid.Margin() + newgrid.Pad() - rs.grid.Margin() - rs.grid.Pad() + // figure out what the state of the git repository is + rs.Update() +} + +func (rs *RepoStatus) setTag() bool { + lasttag := rs.lasttag.Get() + var major, minor, revision string + major, minor, revision = splitVersion(lasttag) + + olda, _ := strconv.Atoi(major) + oldb, _ := strconv.Atoi(minor) + oldc, _ := strconv.Atoi(revision) + + log.Warn("current version here", lasttag) + log.Warn("current release a,b,c =", major, minor, revision) + + newa, _ := strconv.Atoi(rs.major.Get()) + newb, _ := strconv.Atoi(rs.minor.Get()) + newc, _ := strconv.Atoi(rs.revision.Get()) + + newver := strconv.Itoa(newa) + if newa < olda { + log.Warn("new version bad", newver, "vs old version", lasttag) + rs.newversion.Set("bad") + return false + } + if newa > olda { + log.Warn("new version ok", newver, "vs old version", lasttag) + rs.newversion.Set(newver) + rs.minor.Set("") + rs.revision.Set("") + return true + } + + newver = strconv.Itoa(newa) + "." + strconv.Itoa(newb) + if newb < oldb { + log.Warn("new version bad", newver, "vs old version", lasttag) + rs.newversion.Set("bad") + return false + } + + if newb > oldb { + log.Warn("new version ok", newver, "vs old version", lasttag) + rs.newversion.Set(newver) + rs.revision.Set("") + return true + } + + 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.Set("bad") + return false + } + log.Warn("new version ok", newver, "vs old version", lasttag) + rs.newversion.Set(newver) + return true } func (rs *RepoStatus) incrementVersion() { @@ -102,20 +153,113 @@ func (rs *RepoStatus) incrementVersion() { log.Warn("Should release version here", lasttag) log.Warn("Should release a,b,c", major, minor, revision) - rs.a, _ = strconv.Atoi(major) - rs.b, _ = strconv.Atoi(minor) - rs.c, _ = strconv.Atoi(revision) + a, _ := strconv.Atoi(major) + b, _ := strconv.Atoi(minor) + c, _ := strconv.Atoi(revision) - rs.major.Add(rs.a) - rs.major.Add(rs.a + 1) - rs.major.Set(rs.a) + rs.major.Add(a) + rs.major.Add(a + 1) + rs.major.Set(a) - rs.minor.Add(rs.b) - rs.minor.Add(rs.b + 1) - rs.minor.Set(rs.b) + rs.minor.Add(b) + rs.minor.Add(b + 1) + rs.minor.Set(b) // rs.c := strconv.Atoi(revision) - rs.revision.Add(rs.c + 1) - rs.revision.Add(rs.c + 2) - rs.revision.Set(rs.c + 1) + rs.revision.Add(c + 1) + rs.revision.Add(c + 2) + rs.revision.Set(c + 1) +} + +func (rs *RepoStatus) recommend() { + log.Warn("Is repo dirty?", rs.dirtyLabel.Get()) + log.Warn("list the known tags") + rs.DisableEverything() + rs.populateTags() + log.Warn("Does devel == jcarr?", rs.develBranch.Get(), rs.jcarrBranch.Get()) + if rs.develBranch.Get() != rs.jcarrBranch.Get() { + log.Warn("devel does not equal jcarr") + log.Warn("merge or squash?") + return + } + log.Warn("Does master == devel? ", rs.masterBranch.Get(), rs.develBranch.Get()) + if rs.masterBranch.Get() != rs.develBranch.Get() { + log.Warn("master does not equal devel. merge devel into master") + rs.EnableMergeDevel() + return + } + rs.getLastTagVersion() + if rs.lasttag.Get() != rs.masterBranch.Get() { + log.Warn("master does not equal last tag") + rs.incrementVersion() + rs.EnableSelectTag() + rs.setTag() + return + } + log.Warn("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.Warn("tag sucked. fix your tag version") + rs.versionMessage.SetLabel("tag message (bad version)") + rs.releaseVersion.Disable() + return false + } + + log.Warn("tag is valid!!!!") + rs.setGitCommands() + + if rs.versionMessage.Get() == "" { + log.Warn("tag message is empty!!!!") + rs.releaseVersion.Disable() + return false + } + if len(rs.versionMessage.Get()) > 24 { + rs.versionMessage.SetLabel("tag message (too long)") + } else { + rs.versionMessage.SetLabel("tag message") + } + rs.releaseVersion.Enable() + return true +} + +func (rs *RepoStatus) setGitCommands() { + var line1, line2, line3 []string + var all [][]string + + newTag := rs.newversion.GetText() + line1 = append(line1, "git", "tag", "v" + newTag, "-m", rs.versionMessage.Get()) + 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.Warn("s =", s) + tmp = append(tmp, s) + } + + rs.versionCmdOutput.Set(strings.Join(tmp, "\n")) +} +func (rs *RepoStatus) runGitCommands() { + for _, line := range rs.versionCmds { + s := strings.Join(line, " ") + log.Warn("NEED TO RUN:", s) + b, output := runCmd(rs.repopath, line) + log.Warn("Returned with b =", b) + log.Warn("output was =", output) + log.Warn("RUN DONE") + } } diff --git a/git.go b/git.go index 477e956..ad549e0 100644 --- a/git.go +++ b/git.go @@ -27,6 +27,7 @@ func (rs *RepoStatus) getLastTagVersion() string { // out = run(r.path, "git", "describe --tags c871d5ecf051a7dc4e3a77157cdbc0a457eb9ae1") out = run(rs.repopath, "git", lastreal) rs.lasttag.Set(out) + rs.tagsDrop.Set(out) // rs.lastLabel.Set(out) return out } @@ -37,11 +38,11 @@ func (rs *RepoStatus) populateTags() { for _, tag := range listFiles(tmp) { if rs.tags[tag] == "" { log.Warn("populateTags() Adding new tag", tag) - rs.tagsDrop.AddText(tag) + rs.tagsDrop.Add(tag) rs.tags[tag] = "origin" } } - rs.tagsDrop.SetText(rs.lasttagrev) + // rs.tagsDrop.Set(rs.lasttagrev) } func (rs *RepoStatus) checkDirty() bool { diff --git a/structs.go b/structs.go index 22915e8..844e2b3 100644 --- a/structs.go +++ b/structs.go @@ -26,7 +26,7 @@ type RepoStatus struct { currentBranch *gadgets.OneLiner currentVersion *gadgets.OneLiner - tagsDrop *gui.Node + tagsDrop *gadgets.BasicDropdown lasttag *gadgets.OneLiner masterBranch *gadgets.OneLiner @@ -36,14 +36,15 @@ type RepoStatus struct { develMerge *gui.Node releaseVersion *gui.Node - vgroup *gui.Node - minor *gadgets.BasicCombobox - major *gadgets.BasicCombobox - revision *gadgets.BasicCombobox + vgroup *gui.Node + minor *gadgets.BasicCombobox + major *gadgets.BasicCombobox + revision *gadgets.BasicCombobox + versionMessage *gadgets.BasicEntry + versionCmds [][]string + versionCmdOutput *gadgets.OneLiner - a int - b int - c int + newversion *gui.Node speed *gadgets.OneLiner speedActual *gadgets.OneLiner diff --git a/unix.go b/unix.go index e34aef6..cc49efc 100644 --- a/unix.go +++ b/unix.go @@ -102,3 +102,38 @@ func splitVersion(version string) (a, b, c string) { return parts[0], parts[1], parts[2] } } + +func runCmd(path string, parts []string) (bool, string) { + if len(parts) == 0 { + log.Warn("command line was empty") + return false, "" + } + if parts[0] == "" { + log.Warn("command line was empty") + return false, "" + } + thing := parts[0] + parts = parts[1:] + + log.Warn("path =", path, "thing =", thing, "cmdline =", parts) + // Create the command + cmd := exec.Command(thing, parts...) + + // Set the working directory + cmd.Dir = fullpath(path) + + // Execute the command + output, err := cmd.CombinedOutput() + if err != nil { + log.Error(err) + log.Warn("output was", output) + log.Warn("cmd exited with error", err) + return false, string(output) + } + + tmp := string(output) + tmp = strings.TrimSpace(tmp) + + // Print the output + return true, tmp +} diff --git a/update.go b/update.go index e7544d6..0ab1709 100644 --- a/update.go +++ b/update.go @@ -16,24 +16,33 @@ func (rs *RepoStatus) Update() { } log.Log(WARN, "Update() START") duration := timeFunction(func () { + // do things that are safe even if the git tree is dirty rs.path.Set(rs.repopath) rs.getCurrentBranchName() rs.window.Title(rs.repopath + " GO repo Details") rs.getCurrentBranchVersion() - rs.getLastTagVersion() rs.populateTags() - // rs.checkDirty() this runs - log.Log(WARN, "") - log.Log(WARN, "checkoutBranch master") - rs.checkoutBranch("master") - log.Log(WARN, "") - log.Log(WARN, "checkoutBranch devel") - rs.checkoutBranch("devel") - log.Log(WARN, "") - log.Log(WARN, "checkoutBranch jcarr") - rs.checkoutBranch("jcarr") + if rs.checkDirty() { + if rs.dirtyLabel.Get() != "no" { + rs.DisableEverything() + return + } + + // rs.checkDirty() this runs + log.Log(WARN, "") + log.Log(WARN, "checkoutBranch master") + rs.checkoutBranch("master") + log.Log(WARN, "") + log.Log(WARN, "checkoutBranch devel") + rs.checkoutBranch("devel") + log.Log(WARN, "") + log.Log(WARN, "checkoutBranch jcarr") + rs.checkoutBranch("jcarr") + + rs.recommend() + } }) rs.setSpeed(duration) log.Log(WARN, "Update() END") @@ -55,3 +64,44 @@ func (rs *RepoStatus) setSpeed(duration time.Duration) { rs.speed.Set("FAST") } } + +// disable all things besides Update() button +func (rs *RepoStatus) DisableEverything() { + + // choosing a major, minor or revision + rs.major.Disable() + rs.minor.Disable() + rs.revision.Disable() + + // disable adding a tag message + rs.versionMessage.Disable() + + // disable the merge devel to master button + rs.develMerge.Disable() + + // disable the tag a new version button + rs.releaseVersion.Disable() +} + +// this means devel needs to be merged to master +func (rs *RepoStatus) EnableMergeDevel() { + rs.DisableEverything() + + rs.develMerge.Enable() +} + +// this means you need to release a new version of the master repository +func (rs *RepoStatus) EnableSelectTag() { + rs.DisableEverything() + + // choosing a major, minor or revision + rs.major.Enable() + rs.minor.Enable() + rs.revision.Enable() + + // disable adding a tag message + rs.versionMessage.Enable() + + // force there to be a commit message + rs.releaseVersion.Disable() +}