xterm fixes

also a i18n syntax idea
   show all tags in the main window
This commit is contained in:
Jeff Carr 2024-02-15 22:50:50 -06:00
parent e6eb92845a
commit 2bc2096e84
10 changed files with 176 additions and 160 deletions

View File

@ -1,7 +1,5 @@
all:
@echo
@echo Run: make redomod
@echo
GO111MODULE=off go build
goimports:
goimports -w *.go

View File

@ -1,30 +1,33 @@
package repostatus
import (
"strings"
"go.wit.com/gui"
"go.wit.com/lib/gadgets"
"go.wit.com/log"
)
func (rs *RepoStatus) makeBranchesBox() {
rs.gitBranchesGroup = rs.window.Box().NewGroup("branches")
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)
rs.lasttag = gadgets.NewOneLiner(newgrid, "last tag")
rs.lasttag = gadgets.NewOneLiner(newgrid, "last tag") // `progname:"LASTTAG"`
newgrid.NextRow()
rs.masterBranchVersion = gadgets.NewOneLiner(newgrid, "master")
rs.masterBranchVersion = gadgets.NewOneLiner(newgrid, "master") // `progname:"MASTERBRANCH"`
newgrid.NextRow()
rs.develBranchVersion = gadgets.NewOneLiner(newgrid, "devel")
rs.develBranchVersion = gadgets.NewOneLiner(newgrid, "devel") // `progname:"DEVELBRANCH"`
newgrid.NextRow()
rs.userBranchVersion = gadgets.NewOneLiner(newgrid, "user")
rs.userBranchVersion = gadgets.NewOneLiner(newgrid, "user") // `progname:"USERBRANCH"`
newgrid.NextRow()
rs.currentBranch = gadgets.NewOneLiner(newgrid, "current branch")
rs.currentBranch = gadgets.NewOneLiner(newgrid, "current branch") // `progname:"CURRENTBRANCH"`
newgrid.NextRow()
rs.currentVersion = gadgets.NewOneLiner(newgrid, "current version")
rs.currentVersion = gadgets.NewOneLiner(newgrid, "current version") // `progname:"CURRENTVERSION"`
newgrid.NextRow()
rs.switchBranchB = newgrid.NewButton("Switch Branch", func() {
rs.switchBranchB = newgrid.NewButton("Switch Branch", func() { // `progname:"SWITCH"`
bname := rs.targetBranch.String()
log.Info("Should switch to branch", bname, "here")
@ -38,12 +41,16 @@ func (rs *RepoStatus) makeBranchesBox() {
rs.UpdateCurrent()
})
rs.targetBranch = newgrid.NewDropdown()
rs.targetBranch = newgrid.NewDropdown() // `progname:"TARGET"`
// rs.targetBranch.AddText("master")
newgrid.NextRow()
rs.showBranchesButton = newgrid.NewButton("scan branches()", func() {
all := rs.getBranches()
err, out := rs.RunCmd([]string{"git", "branch", "--all"})
if err != nil {
log.Log(WARN, "git branch failed", rs.String())
}
all := strings.Split(out, "\n")
for i, s := range all {
log.Log(WARN, "found branch", i, s)
rs.targetBranch.AddText(s)

View File

@ -17,6 +17,30 @@ func (rs *RepoStatus) Changed() bool {
return rs.changed
}
// deprecate this. returns the gopath right now
func (rs *RepoStatus) String() string {
log.Warn("RepoStatus.String() is to be deprecated")
return rs.path.String()
}
// returns the go path for the repo. "go.wit.com/apps/autotypist"
func (rs *RepoStatus) GoName() string {
return rs.goSrcPath.String()
}
// returns the filesystem path to the repo
func (rs *RepoStatus) Path() string {
return rs.realPath.String()
}
/*
func (rs *RepoStatus) GetPath() string {
return rs.path.String()
}
*/
/*
func (rs *RepoStatus) Draw() {
if !rs.Ready() {
return
@ -24,6 +48,7 @@ func (rs *RepoStatus) Draw() {
log.Log(CHANGE, "Draw() window ready =", rs.ready)
rs.window.TestDraw()
}
*/
func (rs *RepoStatus) Show() {
if !rs.Ready() {
@ -100,7 +125,8 @@ func (rs *RepoStatus) Build() bool {
return false
}
log.Info("need to build here", rs.String())
rs.RunCmd([]string{"go", "build", "-v", "-x"})
// rs.RunCmd([]string{"go", "build", "-v", "-x"})
rs.XtermBash([]string{"go", "build", "-v", "-x"})
if rs.Exists(name) {
log.Warn("build worked", name)
return true

22
draw.go
View File

@ -4,30 +4,14 @@ import (
"strconv"
"strings"
"go.wit.com/gui"
"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() {
if !rs.Ready() {
return
}
// display the status of the git repository
rs.drawGitStatus()
// display the git branches and options
rs.makeBranchesBox()
// show standard git commit and merge controls
rs.drawGitCommands()
}
func (rs *RepoStatus) drawGitStatus() {
rs.gitStatusGroup = rs.window.Box().NewGroup("What GIT Knows It Has")
func (rs *RepoStatus) drawGitStatus(box *gui.Node) {
rs.gitStatusGroup = box.NewGroup("What GIT Knows It Has")
newgrid := rs.gitStatusGroup.NewGrid("gridnuts", 2, 2)
newgrid.Margin()
newgrid.Pad()

15
git.go
View File

@ -2,6 +2,7 @@ package repostatus
import (
"strings"
"time"
"unicode/utf8"
"io/ioutil"
@ -9,16 +10,6 @@ import (
"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()
}
@ -27,6 +18,10 @@ func (rs *RepoStatus) GetCurrentBranchVersion() string {
return rs.currentVersion.String()
}
func (rs *RepoStatus) LastTagAge() (time.Time, string) {
return time.Now(), rs.lasttag.String()
}
func (rs *RepoStatus) GetLastTagVersion() string {
return rs.lasttag.String()
}

View File

@ -1,12 +1,13 @@
package repostatus
import (
"go.wit.com/gui"
"go.wit.com/lib/gadgets"
"go.wit.com/log"
)
func (rs *RepoStatus) drawGitCommands() {
rs.gitCommandsGroup = rs.window.Box().NewGroup("modify")
func (rs *RepoStatus) drawGitCommands(box *gui.Node) {
rs.gitCommandsGroup = box.NewGroup("modify")
newgrid := rs.gitCommandsGroup.NewGrid("gridnuts", 0, 0)
newgrid.NewButton("update", func() {
@ -25,19 +26,6 @@ func (rs *RepoStatus) drawGitCommands() {
}
})
newgrid.NewButton("git tags window", func() {
if rs.TagsW == nil {
log.Warn("error: found rs.TagsW == nil")
rs.TagsW = rs.TagWindow()
return
}
if rs.TagsW.Hidden() {
rs.TagsW.Show()
} else {
rs.TagsW.Show()
}
})
newgrid.NewButton("show .git/config", func() {
if rs.gitConfig == nil {
log.Log(WARN, "Nonexistant or damaged .git/config", rs.String())

43
new.go
View File

@ -11,6 +11,10 @@ import (
var windowMap map[string]*RepoStatus
func init() {
windowMap = make(map[string]*RepoStatus)
}
func ListAll() {
for path, rs := range windowMap {
log.Warn(rs.GetMasterVersion(), path)
@ -35,16 +39,27 @@ func NewRepoStatusWindow(path string) *RepoStatus {
return windowMap[path]
}
var realpath string
homeDir, err := os.UserHomeDir()
if err != nil {
log.Log(WARN, "Error getting home directory:", err)
return nil
}
goSrcDir := filepath.Join(homeDir, "go/src")
realpath := filepath.Join(goSrcDir, path)
filename := filepath.Join(goSrcDir, path, ".git/config")
// allow arbitrary paths, otherwise, assume the repo is in ~/go/src
if strings.HasPrefix(path, "/") {
realpath = path
} else if strings.HasPrefix(path, "~") {
// TODO: example this to homedir
tmp := strings.TrimPrefix(path, "~")
realpath = filepath.Join(homeDir, tmp)
} else {
realpath = filepath.Join(goSrcDir, path)
}
filename := filepath.Join(realpath, ".git/config")
_, err = os.Open(filename)
if err != nil {
@ -60,18 +75,34 @@ func NewRepoStatusWindow(path string) *RepoStatus {
rs.window = gadgets.RawBasicWindow("GO Repo Details " + path)
rs.window.Horizontal()
rs.window.Make()
basebox := rs.window.Box()
group := basebox.NewGroup("stuff")
primarybox := group.Box()
primarybox.Horizontal()
box2 := group.Box()
rs.ready = true
rs.window.Custom = func() {
rs.Hide()
log.Warn("repostatus user closed the window()")
}
rs.draw()
// display the status of the git repository
rs.drawGitStatus(primarybox)
// display the git branches and options
rs.makeBranchesBox(primarybox)
// show standard git commit and merge controls
rs.drawGitCommands(primarybox)
// save ~/go/src & the whole path strings
rs.path.SetValue(path)
rs.goSrcPath.SetValue(goSrcDir)
rs.realPath.SetValue(realpath)
// add all the tags
rs.makeTagBox(box2)
rs.readGitConfig()
rs.readOnly.SetValue("true")
@ -86,7 +117,3 @@ func NewRepoStatusWindow(path string) *RepoStatus {
windowMap[path] = rs
return rs
}
func init() {
windowMap = make(map[string]*RepoStatus)
}

View File

@ -13,8 +13,8 @@ type RepoStatus struct {
window *gadgets.BasicWindow
// a window to manage your .git tags
TagsW *repoTags
// a box of all the git tags
Tags *gitTagBox
dirtyLabel *gadgets.OneLiner
readOnly *gadgets.OneLiner

View File

@ -6,7 +6,6 @@ import (
"strings"
"go.wit.com/gui"
"go.wit.com/lib/gadgets"
"go.wit.com/log"
)
@ -30,13 +29,8 @@ type repoTag struct {
deleteB *gui.Node
}
type repoTags struct {
// the originating repository
rs *RepoStatus
// the window for the tags
window *gadgets.BasicWindow
// a GUI box of all the tags in a repo
type gitTagBox struct {
// the box to list all the tags in
box *gui.Node
group *gui.Node
@ -46,64 +40,43 @@ type repoTags struct {
tags []*repoTag
}
func (tw *repoTags) Hidden() bool {
return tw.window.Hidden()
func (rs *RepoStatus) makeTagBox(box *gui.Node) {
if rs.Tags != nil {
log.Log(WARN, "already scanned tags")
return
}
tagB := new(gitTagBox)
rs.Tags = tagB
tagB.group = box.NewGroup(".git tags for " + rs.String())
func (tw *repoTags) Show() {
log.Info("tw *repoTags Show()")
tw.window.Show()
}
func (tw *repoTags) Hide() {
log.Info("tw *repoTags Hide()")
tw.window.Hide()
}
func (rs *RepoStatus) TagWindow() *repoTags {
// return the window if it was already created
tags := new(repoTags)
rs.TagsW = tags
tags.rs = rs
tags.window = gadgets.RawBasicWindow("tags " + rs.String()).Make()
vbox := tags.window.Box()
tags.newTagBox(vbox)
return tags
}
func (tagW *repoTags) newTagBox(box *gui.Node) {
tagW.group = box.NewGroup(".git tags for " + tagW.rs.String())
// tagW.group.NewButton("prune tags", func() {
// tagW.Prune()
// tagB.group.NewButton("prune tags", func() {
// tagB.Prune()
// })
var dups *gui.Node
dups = tagW.group.NewCheckbox("Show duplicate tags").SetChecked(false)
dups = tagB.group.NewCheckbox("Show duplicate tags").SetChecked(false)
dups.Custom = func() {
if dups.Checked() {
tagW.Prune()
tagB.Prune()
} else {
for _, t := range tagW.tags {
for _, t := range tagB.tags {
t.Show()
}
}
}
tagW.group.NewButton("delete all", func() {
for i, t := range tagW.tags {
tagB.group.NewButton("delete all", func() {
for i, t := range tagB.tags {
if t.hidden {
// log.Info("tag is hidden", i, t.tag.String())
continue
}
log.Info("tag is shown", i, t.tag.String())
tagW.Delete(t)
rs.DeleteTag(t)
}
})
grid := tagW.group.NewGrid("tags", 0, 0)
tagW.grid = grid
grid := tagB.group.NewGrid("tags", 0, 0)
tagB.grid = grid
grid.NewLabel("version")
grid.NewLabel("ref")
@ -117,11 +90,11 @@ func (tagW *repoTags) newTagBox(box *gui.Node) {
// git rev-parse HEAD
// if last tag == HEAD, then remove it
tags := []string{"%(tag)", "%(*objectname)", "%(taggerdate:raw)", "%(subject)"}
tags := []string{"%(tag)", "%(*objectname)", "%(taggerdate:raw)", "%(subject)", "%(*authorname)", "%(*authoremail)"}
format := strings.Join(tags, "_,,,_")
cmd := []string{"git", "for-each-ref", "--sort=taggerdate", "--format", format}
log.Info("RUNNING:", strings.Join(cmd, " "))
err, output := tagW.rs.RunCmd(cmd)
err, output := rs.RunCmd(cmd)
if err != nil {
output = "git error_,,,_a_,,,_b_,,,c"
}
@ -129,7 +102,7 @@ func (tagW *repoTags) newTagBox(box *gui.Node) {
lines := strings.Split(output, "\n")
// reverse the git order
slices.Reverse(lines)
tagW.tags = make([]*repoTag, 0)
tagB.tags = make([]*repoTag, 0)
for i, line := range lines {
var parts []string
@ -143,7 +116,7 @@ func (tagW *repoTags) newTagBox(box *gui.Node) {
rTag.tag = grid.NewLabel(parts[0])
rTag.ref = grid.NewEntrybox(parts[1])
stamp, dur := getDateStamp(parts[2]) //
_, stamp, dur := getDateStamp(parts[2]) //
rTag.date = grid.NewLabel(stamp)
grid.NewLabel(dur)
@ -155,14 +128,14 @@ func (tagW *repoTags) newTagBox(box *gui.Node) {
all = append(all, []string{"git", "tag", "--delete", tagversion})
all = append(all, []string{"git", "push", "--delete", "origin", tagversion})
if tagW.rs.DoAll(all) {
log.Info("TAG DELETED", tagW.rs.String(), tagversion)
if rs.DoAll(all) {
log.Info("TAG DELETED", rs.String(), tagversion)
} else {
log.Info("TAG DELETE FAILED", tagW.rs.String(), tagversion)
log.Info("TAG DELETE FAILED", rs.String(), tagversion)
}
})
tagW.tags = append(tagW.tags, rTag)
tagB.tags = append(tagB.tags, rTag)
// works like a typerwriter
grid.NextRow()
}
@ -170,7 +143,7 @@ func (tagW *repoTags) newTagBox(box *gui.Node) {
// slices.Reverse(rtags.tags)
}
func (rtags *repoTags) ListAll() []*repoTag {
func (rtags *gitTagBox) ListAll() []*repoTag {
var tags []*repoTag
for _, t := range rtags.tags {
tags = append(tags, t)
@ -178,7 +151,7 @@ func (rtags *repoTags) ListAll() []*repoTag {
return tags
}
func (rtags *repoTags) List() []*repoTag {
func (rtags *gitTagBox) List() []*repoTag {
var tags []*repoTag
for _, t := range rtags.tags {
if t.hidden {
@ -191,7 +164,7 @@ func (rtags *repoTags) List() []*repoTag {
return tags
}
func (rtags *repoTags) Prune() {
func (rtags *gitTagBox) Prune() {
dups := make(map[string]*repoTag)
for i, t := range rtags.tags {
if t == nil {
@ -212,7 +185,7 @@ func (rtags *repoTags) Prune() {
}
// hide tags worth keeping
func (rtags *repoTags) PruneSmart() {
func (rtags *gitTagBox) PruneSmart() {
// always keep the first tag
var first bool = true
@ -265,9 +238,7 @@ func (rtags *repoTags) PruneSmart() {
// deleting it locally triggers some but when
// the git server was uncontactable (over IPv6 if that matters, probably it doesn't)
// and then the local delete re-added it into the tag
func (rtags *repoTags) Delete(rt *repoTag) {
rs := rtags.rs
func (rs *RepoStatus) DeleteTag(rt *repoTag) {
cmd := []string{"git", "push", "--delete", "origin", rt.tag.String()}
log.Info("RUN:", cmd)
err, output := rs.RunCmd(cmd)

72
unix.go
View File

@ -119,6 +119,11 @@ func splitVersion(version string) (a, b, c string) {
}
}
func (rs *RepoStatus) RunCmdEcho(parts []string) (error, string) {
log.Info("RunCmdEcho()", parts)
return rs.RunCmd(parts)
}
func (rs *RepoStatus) RunCmd(parts []string) (error, string) {
path := rs.realPath.String()
err, _, output := shell.RunCmd(path, parts)
@ -269,22 +274,23 @@ func readFileToString(filename string) (string, error) {
return strings.TrimSpace(string(data)), nil
}
func getDateStamp(raw string) (string, string) {
func getDateStamp(raw string) (time.Time, string, string) {
parts := strings.Split(raw, " ")
if len(parts) == 0 {
// raw was blank here
return "Jan 4 1977", "40y" // eh, why not. it'll be easy to grep for this
// return "Jan 4 1977", "40y" // eh, why not. it'll be easy to grep for this
return time.Now(), "Jan 4 1977", "40y" // eh, why not. it'll be easy to grep for this
}
i, err := strconv.ParseInt(parts[0], 10, 64) // base 10 string, return int64
if err != nil {
log.Warn("Error converting timestamp:", raw)
log.Warn("Error converting timestamp err =", err)
return raw, ""
return time.Now(), "", ""
}
// Parse the Unix timestamp into a time.Time object
gitTagDate := time.Unix(i, 0)
return gitTagDate.UTC().Format("2006/01/02 15:04:05 UTC"), getDurationStamp(gitTagDate)
return gitTagDate, gitTagDate.UTC().Format("2006/01/02 15:04:05 UTC"), getDurationStamp(gitTagDate)
}
func getDurationStamp(t time.Time) string {
@ -323,16 +329,18 @@ func formatDuration(d time.Duration) string {
return result
}
func (rs *RepoStatus) XtermNohup(cmdline string) {
shell.XtermCmd(rs.Path(), []string{cmdline})
}
func (rs *RepoStatus) Xterm(cmdline string) {
shell.XtermCmd(rs.Path(), []string{cmdline})
}
func (rs *RepoStatus) XtermWait(cmdline string) {
shell.XtermCmdWait(rs.Path(), []string{cmdline})
}
/*
func (rs *RepoStatus) XtermNohup(args []string) {
var argsX = []string{"xterm", "-geometry", "120x40"}
/*
if xtermHold.Checked() {
log.Println("hold = true")
argsXterm = append(argsXterm, "-hold")
} else {
log.Println("hold = false")
}
*/
argsX = append(argsX, "-e", "bash", "-c")
argsX = append(argsX, args...)
log.Info("xterm cmd=", argsX)
@ -353,17 +361,11 @@ func (rs *RepoStatus) XtermNohup(args []string) {
log.Info("cmd =", argsX)
}
}
*/
/*
func (rs *RepoStatus) Xterm(args []string) {
var argsX = []string{"-geometry", "120x40"}
/*
if xtermHold.Checked() {
log.Println("hold = true")
argsXterm = append(argsXterm, "-hold")
} else {
log.Println("hold = false")
}
*/
argsX = append(argsX, "-e", "bash", "-c")
argsX = append(argsX, args...)
log.Info("xterm cmd=", argsX)
@ -382,18 +384,36 @@ func (rs *RepoStatus) Xterm(args []string) {
log.Info("cmd = xterm", argsX)
}
}
*/
/*
func (rs *RepoStatus) XtermHold(args []string) {
var argsX = []string{"-hold", "-geometry", "120x40"}
/*
if xtermHold.Checked() {
log.Println("hold = true")
argsXterm = append(argsXterm, "-hold")
tmp := strings.Join(args, " ") + ";bash"
argsX = append(argsX, "-e", "bash", "-c", tmp)
argsX = append(argsX, args...)
log.Info("xterm cmd=", argsX)
// set less to not exit on small diff's
os.Setenv("LESS", "-+F -+X -R")
cmd := exec.Command("xterm", argsX...)
path := rs.realPath.String()
cmd.Dir = path
if err := cmd.Run(); err != nil {
log.Info("xterm.Run() failed")
log.Info("path =", path)
log.Info("cmd = xterm", argsX)
} else {
log.Println("hold = false")
log.Info("xterm.Run() worked")
log.Info("path =", path)
log.Info("cmd = xterm", argsX)
}
}
*/
argsX = append(argsX, "-e", "bash", "-c")
func (rs *RepoStatus) XtermBash(args []string) {
var argsX = []string{"-geometry", "120x40"}
tmp := strings.Join(args, " ") + ";bash"
argsX = append(argsX, "-e", "bash", "-c", tmp)
argsX = append(argsX, args...)
log.Info("xterm cmd=", argsX)
// set less to not exit on small diff's