From 0b4f4d76866ccc500112cfe553240c47961258e2 Mon Sep 17 00:00:00 2001 From: Jeff Carr Date: Fri, 16 Feb 2024 17:55:13 -0600 Subject: [PATCH] ready to work on creating branches --- branchesBox.go | 17 +----- common.go | 17 +++++- draw.go | 1 - git.go | 147 ++++++++++++++++++++++++++++++++++--------------- gitConfig.go | 9 +-- modifyBox.go | 6 +- structs.go | 5 +- tagWindow.go | 31 +++++++++++ update.go | 89 +++++++++--------------------- 9 files changed, 184 insertions(+), 138 deletions(-) diff --git a/branchesBox.go b/branchesBox.go index 354fe81..86aac4a 100644 --- a/branchesBox.go +++ b/branchesBox.go @@ -1,26 +1,11 @@ package repostatus import ( - "path/filepath" - "go.wit.com/gui" "go.wit.com/lib/gadgets" "go.wit.com/log" ) -func (rs *RepoStatus) TagExists(findname string) bool { - allTags := rs.Tags.ListAll() - for _, t := range allTags { - tagname := t.TagString() - path, filename := filepath.Split(tagname) - if filename == findname { - log.Info("found tag:", path, filename, "from", rs.Path()) - return true - } - } - return false -} - func (rs *RepoStatus) makeBranchesBox(parent *gui.Node) { rs.gitBranchesGroup = parent.NewGroup("branches") // `progname:"BRANCHES"` // can the toolkits use these for i18n support? newgrid := rs.gitBranchesGroup.NewGrid("gridnuts", 0, 0) @@ -51,7 +36,7 @@ func (rs *RepoStatus) makeBranchesBox(parent *gui.Node) { } else { log.Info("branch switched to", bname, "failed") } - rs.UpdateCurrent() + rs.UpdateNew() }) rs.targetBranch = newgrid.NewDropdown() // `progname:"TARGET"` diff --git a/common.go b/common.go index 9df2b74..94e3a4b 100644 --- a/common.go +++ b/common.go @@ -9,12 +9,23 @@ import ( // reports externally if something has changed // since the last time it was asked about it -func (rs *RepoStatus) Changed() bool { +func (rs *RepoStatus) Changed() (string, bool) { if !rs.Ready() { - return false + return "", false } - return rs.changed + return rs.Changes(), rs.changed +} + +// keeps a human readable list of things that have +// changed +func (rs *RepoStatus) Changes() string { + return rs.changes +} + +func (rs *RepoStatus) NoteChange(s string) { + rs.changed = true + rs.changes += s + "\n" } // deprecate this. returns the gopath right now diff --git a/draw.go b/draw.go index 00707e7..765cbd6 100644 --- a/draw.go +++ b/draw.go @@ -260,7 +260,6 @@ func (rs *RepoStatus) recommend() { rs.develMergeB.SetLabel(label) return } - rs.getLastTagVersion() if rs.lasttag.String() != rs.masterBranchVersion.String() { log.Log(INFO, "master does not equal last tag") rs.incrementVersion() diff --git a/git.go b/git.go index 517e328..e47b828 100644 --- a/git.go +++ b/git.go @@ -1,6 +1,7 @@ package repostatus import ( + "errors" "strings" "time" "unicode/utf8" @@ -26,53 +27,88 @@ func (rs *RepoStatus) GetLastTagVersion() string { return rs.lasttag.String() } -func (rs *RepoStatus) getCurrentBranchName() string { +// stores the current branch name +func (rs *RepoStatus) checkCurrentBranchName() string { + currentname := rs.currentBranch.String() out := run(rs.realPath.String(), "git", "branch --show-current") - log.Log(INFO, "getCurrentBranchName() =", out) + if currentname == out { + // nothing changed + return currentname + } rs.currentBranch.SetValue(out) + if currentname == "" { + return out // don't note if there was nothing before + } + rs.NoteChange("current branch has changed from " + currentname + " to " + out) return out } -func (rs *RepoStatus) gitDescribeTags(name string) (string, error) { +func (rs *RepoStatus) getCurrentBranchName() string { + return rs.currentBranch.String() +} + +func (rs *RepoStatus) gitDescribeByHash(hash string) (string, error) { + if hash == "" { + return "", errors.New("hash was blank") + } + err, out := rs.RunCmd([]string{"git", "describe", "--tags", "--always", hash}) + if err != nil { + log.Warn("not in a git repo or bad hash?", err, rs.Path()) + return "", err + } + out = strings.TrimSpace(out) + return out, err +} + +func (rs *RepoStatus) gitDescribeByName(name string) (string, error) { name = strings.TrimSpace(name) if name == "" { // git will return the current tag - err, out := rs.RunCmd([]string{"git", "describe", "--tags"}) + err, out := rs.RunCmd([]string{"git", "describe", "--tags", "--always"}) if err != nil { log.Warn("not in a git repo?", err, rs.Path()) return "", err } + out = strings.TrimSpace(out) return out, err } - err, out := rs.RunCmd([]string{"git", "describe", "--tags", name}) + if !rs.LocalTagExists(name) { + // tag does not exist + return "", errors.New("git fatal: Not a valid object name") + } + cmd := []string{"git", "describe", "--tags", "--always", name} + err, out := rs.RunCmd(cmd) if err != nil { - log.Warn("not in a git repo or bad tag?", err, rs.Path()) + log.Warn("cmd =", cmd) + log.Warn("err =", err) + log.Warn("not in a git repo or bad tag?", rs.Path()) return "", err } + out = strings.TrimSpace(out) return out, err } // todo: don't run git every time? -func (rs *RepoStatus) getCurrentBranchVersion() string { - out, _ := rs.gitDescribeTags("") - log.Log(INFO, "getCurrentBranchVersion()", out) +func (rs *RepoStatus) checkCurrentBranchVersion() string { + out, _ := rs.gitDescribeByName("") + log.Log(INFO, "checkCurrentBranchVersion()", 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 +func (rs *RepoStatus) getCurrentBranchVersion() string { + return rs.currentVersion.String() +} - 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 +// this should get the most recent tag +func (rs *RepoStatus) setLastTagVersion() { + hash := run(rs.realPath.String(), "git", "rev-list --tags --max-count=1") + log.Log(INFO, "getLastTagVersion()", hash) + + name, _ := rs.gitDescribeByHash(hash) + rs.lasttag.SetText(name) + return } func (rs *RepoStatus) populateTags() { @@ -141,17 +177,32 @@ func (rs *RepoStatus) CheckDirty() bool { 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(bname string) bool { + if rs.CheckDirty() { + log.Log(INFO, rs.realPath.String(), "is dirty") + log.Info("bname is dirty", bname, rs.Path()) + return false + } + if !rs.TagExists(bname) { + // tag does not exist + log.Info("bname already exists", bname, rs.Path()) + return false + } + cName := rs.GetCurrentBranchName() + if cName == bname { + // already on branch + return true + } + cmd := []string{"git", "checkout", bname} + err, b, output := RunCmd(rs.realPath.String(), cmd) + if err != nil { + log.Log(INFO, err, b, output) + return false + } + rs.checkCurrentBranchName() + rs.checkCurrentBranchVersion() + return true } -*/ func (rs *RepoStatus) CheckoutMaster() bool { if rs.CheckDirty() { @@ -308,7 +359,6 @@ func (rs *RepoStatus) setDevelWorkingName(s string) { func (rs *RepoStatus) setUserWorkingName(s string) { rs.userWorkingName.SetValue(s) rs.userBranchVersion.SetLabel(s) - // rs.userDrop.SetText(s) } // returns "master", "devel", os.Username, etc @@ -340,31 +390,42 @@ func (rs *RepoStatus) GetUserVersion() string { return name } -func (rs *RepoStatus) SetMasterVersion(s string) { - if rs.GetMasterVersion() == s { +func (rs *RepoStatus) setMasterVersion(s string) { + old := rs.GetMasterVersion() + if old == s { return } - rs.changed = true - log.Verbose("git", rs.GetMasterBranchName(), "is now version =", s) rs.masterBranchVersion.SetValue(s) + if old == "" { + return // don't note if there was nothing before + } + rs.NoteChange("master branch has been changed from " + old + " to " + s) } -func (rs *RepoStatus) SetDevelVersion(s string) { - if rs.GetDevelVersion() == s { +func (rs *RepoStatus) setDevelVersion(s string) { + old := rs.GetDevelVersion() + if old == s { return } - rs.changed = true + if old == "" { + // don't note nothing + } else { + rs.NoteChange("devel branch has been changed from " + old + " to " + s) + } rs.develBranchVersion.SetValue(s) - log.Verbose("git", rs.GetDevelBranchName(), "s now version =", s) } -func (rs *RepoStatus) SetUserVersion(s string) { - if rs.GetUserVersion() == s { +func (rs *RepoStatus) setUserVersion(s string) { + old := rs.GetUserVersion() + if old == s { return } - rs.changed = true + if old == "" { + // don't note nothing + } else { + rs.NoteChange("user branch has been changed from " + old + " to " + s) + } rs.userBranchVersion.SetValue(s) - // log.Verbose("git", rs.GetUserBranchName(), "is now version =", s) } func (rs *RepoStatus) GetStatus() string { diff --git a/gitConfig.go b/gitConfig.go index 9fc4737..2f70773 100644 --- a/gitConfig.go +++ b/gitConfig.go @@ -269,10 +269,7 @@ func (rs *RepoStatus) processBranch(branch string) { } } - var cmd []string - cmd = append(cmd, "git", "describe", "--tags", newhash) - _, _, output := RunCmd(rs.realPath.String(), cmd) - output = strings.TrimSpace(output) - rs.gitConfig.versions[newhash] = output - log.Log(INFO, " hash: version", output) + name, _ := rs.gitDescribeByHash(newhash) + rs.gitConfig.versions[newhash] = name + log.Log(INFO, " hash: version", name) } diff --git a/modifyBox.go b/modifyBox.go index 8dfd289..4df7886 100644 --- a/modifyBox.go +++ b/modifyBox.go @@ -10,14 +10,10 @@ func (rs *RepoStatus) drawGitCommands(box *gui.Node) { rs.gitCommandsGroup = box.NewGroup("modify") newgrid := rs.gitCommandsGroup.NewGrid("gridnuts", 0, 0) - newgrid.NewButton("UpdateNew()", func() { + newgrid.NewButton("Rescan Repo", func() { rs.UpdateNew() }) - newgrid.NewButton("updateOld()", func() { - rs.UpdateOld() - }) - newgrid.NewButton("CheckDirty()", func() { if rs.CheckDirty() { log.Log(WARN, "is dirty") diff --git a/structs.go b/structs.go index 7b7bcd7..be8feb8 100644 --- a/structs.go +++ b/structs.go @@ -6,8 +6,11 @@ import ( ) type RepoStatus struct { - ready bool + ready bool + + // keeps track of changes that might have happened changed bool + changes string tags map[string]string diff --git a/tagWindow.go b/tagWindow.go index 80f14cf..f6a349d 100644 --- a/tagWindow.go +++ b/tagWindow.go @@ -1,6 +1,7 @@ package repostatus import ( + "path/filepath" "regexp" "slices" "strings" @@ -281,3 +282,33 @@ func (rt *repoTag) Show() { rt.subject.Show() rt.deleteB.Show() } + +func (rs *RepoStatus) TagExists(findname string) bool { + allTags := rs.Tags.ListAll() + for _, t := range allTags { + tagname := t.TagString() + _, filename := filepath.Split(tagname) + if filename == findname { + // log.Info("found tag:", path, filename, "from", rs.Path()) + return true + } + } + return false +} + +func (rs *RepoStatus) LocalTagExists(findname string) bool { + allTags := rs.Tags.ListAll() + for _, t := range allTags { + tagname := t.TagString() + if strings.HasPrefix(tagname, "refs/remotes") { + continue + } + path, filename := filepath.Split(tagname) + log.Log(INFO, "tag:", path, filename, "from", rs.Path()) + if filename == findname { + log.Log(INFO, "found tag:", path, filename, "from", rs.Path()) + return true + } + } + return false +} diff --git a/update.go b/update.go index 3cafce2..8e60e8c 100644 --- a/update.go +++ b/update.go @@ -29,55 +29,45 @@ func (rs *RepoStatus) UpdateNew() { log.Error(errors.New("Update() is not ready yet")) return } - // do things that are safe even if the git tree is dirty - // rs.path.SetValue(rs.repopath) - rs.getCurrentBranchName() - // rs.window.SetTitle(rs.repopath + " GO repo Details") - rs.getCurrentBranchVersion() - rs.getLastTagVersion() + + // store the current checked out branch name and version + rs.checkCurrentBranchName() + rs.checkCurrentBranchVersion() + + // read in the tags rs.populateTags() + + // record if the repo is dirty rs.CheckDirty() - // get the master branch version + // store the last tag version + rs.setLastTagVersion() + + // store the master branch version mName := rs.GetMasterBranchName() - cmd := []string{"git", "describe", "--tags", mName} - err, out := rs.RunCmd(cmd) - if err == nil { - log.Log(INFO, "git cmd =", cmd, "worked =", out) - rs.SetMasterVersion(out) - } else { - log.Log(WARN, "git cmd =", cmd) - log.Log(WARN, "git err =", err) - log.Log(WARN, "git master failed", mName, rs.Path()) - } + out, _ := rs.gitDescribeByName(mName) + rs.setMasterVersion(out) - // get the devel branch version + // store the devel branch version dName := rs.GetDevelBranchName() - cmd = []string{"git", "describe", "--tags", dName} - err, out = rs.RunCmd(cmd) - if err == nil { - log.Log(INFO, "git cmd =", cmd, "worked =", out) - rs.SetDevelVersion(out) + if dName == "" { + rs.setDevelVersion("") } else { - log.Log(WARN, "git cmd =", cmd) - log.Log(WARN, "git err =", err) - log.Log(WARN, "git devel failed", dName, rs.Path()) + out, _ = rs.gitDescribeByName(dName) + rs.setDevelVersion(out) } - // get the user branch version + // store the user branch version uName := rs.GetUserBranchName() - cmd = []string{"git", "describe", "--tags", uName} - err, out = rs.RunCmd(cmd) - if err == nil { - log.Log(INFO, "git cmd =", cmd, "worked =", out) - rs.SetUserVersion(out) + if uName == "" { + rs.setUserVersion("") } else { - log.Log(WARN, "git cmd =", cmd) - log.Log(WARN, "git err =", err) - log.Log(WARN, "git user failed", uName, rs.Path()) + out, _ = rs.gitDescribeByName(uName) + rs.setUserVersion(out) } } +/* // deprecate / redo what is left of this func (rs *RepoStatus) UpdateOld() { if !rs.Ready() { @@ -120,6 +110,7 @@ func (rs *RepoStatus) UpdateOld() { rs.setSpeed(duration) log.Log(INFO, "Update() END") } +*/ func (rs *RepoStatus) setSpeed(duration time.Duration) { s := fmt.Sprint(duration) @@ -194,31 +185,3 @@ func (rs *RepoStatus) EnableSelectTag() { rs.releaseVersion.Enable() } } - -// This doesn't switch branches -func (rs *RepoStatus) UpdateCurrent() { - if !rs.Ready() { - log.Log(WARN, "can't update yet. ready is false") - log.Error(errors.New("Update() is not ready yet")) - return - } - log.Log(INFO, "Update() START") - rs.getCurrentBranchName() - rs.getCurrentBranchVersion() - rs.getLastTagVersion() - rs.populateTags() - rs.CheckDirty() - - // read in the .git/config each update - rs.readGitConfig() - - // this looks into .git somewhat - rs.CheckBranches() - - if rs.dirtyLabel.String() != "no" { - // the repo is dirty - log.Warn("dirty label != no. actual value:", rs.dirtyLabel.String()) - rs.DisableEverything() - return - } -}