summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Carr <[email protected]>2024-01-09 15:34:53 -0600
committerJeff Carr <[email protected]>2024-01-09 15:34:53 -0600
commit87346d9452b38db517e76e070f11928060bc2b99 (patch)
tree2e6ff93e368fda0a1581496985798fe4c1de3569
initial commit
-rw-r--r--args.go32
-rw-r--r--common.go85
-rw-r--r--draw.go48
-rw-r--r--git.go81
-rw-r--r--new.go35
-rw-r--r--structs.go38
-rw-r--r--timer.go17
-rw-r--r--unix.go54
-rw-r--r--update.go57
9 files changed, 447 insertions, 0 deletions
diff --git a/args.go b/args.go
new file mode 100644
index 0000000..d342ac8
--- /dev/null
+++ b/args.go
@@ -0,0 +1,32 @@
+package repostatus
+
+/*
+ this enables command line options from other packages like 'gui' and 'log'
+*/
+
+import (
+ "go.wit.com/log"
+)
+
+var NOW *log.LogFlag
+var INFO *log.LogFlag
+
+var SPEW *log.LogFlag
+var WARN *log.LogFlag
+
+var CHANGE *log.LogFlag
+var STATUS *log.LogFlag
+
+func init() {
+ full := "go.wit.com/gui/gadgets/repostatus"
+ short := "repostatus"
+
+ NOW = log.NewFlag( "NOW", true, full, short, "temp debugging stuff")
+ INFO = log.NewFlag("INFO", false, full, short, "normal debugging stuff")
+
+ WARN = log.NewFlag("WARN", true, full, short, "bad things")
+ SPEW = log.NewFlag("SPEW", false, full, short, "spew stuff")
+
+ CHANGE = log.NewFlag("CHANGE", true, full, short, "when repo changes")
+ STATUS = log.NewFlag("STATUS", false, full, short, "current status")
+}
diff --git a/common.go b/common.go
new file mode 100644
index 0000000..c70356e
--- /dev/null
+++ b/common.go
@@ -0,0 +1,85 @@
+package repostatus
+
+import (
+ "go.wit.com/log"
+ "go.wit.com/gui/gui"
+)
+
+// 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
+ 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 (ls *RepoStatus) Draw() {
+ if ! ls.Ready() {return}
+ log.Log(CHANGE, "Draw() window ready =", ls.ready)
+ ls.window.Draw()
+ ls.ready = true
+}
+func (ls *RepoStatus) Draw2() {
+ if ! ls.Ready() {return}
+ log.Log(CHANGE, "draw(ls) ready =", ls.ready)
+ draw(ls)
+}
+
+func (ls *RepoStatus) Show() {
+ if ! ls.Ready() {return}
+ log.Log(CHANGE, "Show() window ready =", ls.ready)
+ ls.window.Show()
+ ls.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 (ls *RepoStatus) Toggle() {
+ if ! ls.Ready() {return}
+ log.Log(CHANGE, "Toggle() window ready =", ls.ready)
+ if ls.hidden {
+ ls.Show()
+ } else {
+ ls.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 (ls *RepoStatus) Initialized() bool {
+ log.Log(CHANGE, "checking Initialized()")
+ if ls == nil {return false}
+ if ls.parent == nil {return false}
+ return true
+}
+
+func (ls *RepoStatus) SetParent(p *gui.Node) {
+ log.Log(CHANGE, "Attempting SetParent")
+ if ls == nil {return}
+ if ls.parent == nil {
+ log.Log(CHANGE, "SetParent =", p)
+ ls.parent = p
+ return
+ } else {
+ log.Log(CHANGE, "SetParent was already set to =", ls.parent)
+ }
+}
diff --git a/draw.go b/draw.go
new file mode 100644
index 0000000..33d655f
--- /dev/null
+++ b/draw.go
@@ -0,0 +1,48 @@
+package repostatus
+
+import (
+ "go.wit.com/log"
+ "go.wit.com/gui/gadgets"
+)
+
+// creates the actual widgets.
+// it's assumed you are always passing in a box
+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.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.masterBranch = gadgets.NewOneLiner(rs.grid, "master")
+ rs.develBranch = gadgets.NewOneLiner(rs.grid, "devel")
+ rs.jcarrBranch = gadgets.NewOneLiner(rs.grid, "jcarr")
+
+ rs.dirtyLabel = gadgets.NewOneLiner(rs.grid, "dirty")
+
+ rs.speed = gadgets.NewOneLiner(rs.grid, "refresh speed =")
+ rs.speedActual = gadgets.NewOneLiner(rs.grid, "speed actual =")
+
+ rs.grid.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.populateTags()
+ log.Warn("Does master == devel? ")
+ log.Warn("Does devel == jcarr?")
+ log.Warn("Is repo pushed upstream? git.wit.org or github?")
+ })
+
+ rs.grid.Margin()
+ rs.grid.Pad()
+}
diff --git a/git.go b/git.go
new file mode 100644
index 0000000..477e956
--- /dev/null
+++ b/git.go
@@ -0,0 +1,81 @@
+package repostatus
+
+import (
+ "go.wit.com/log"
+)
+
+func (rs *RepoStatus) getCurrentBranchName() string {
+ out := run(rs.repopath, "git", "branch --show-current")
+ log.Warn("getCurrentBranchName() =", out)
+ rs.currentBranch.Set(out)
+ return out
+}
+
+func (rs *RepoStatus) getCurrentBranchVersion() string {
+ out := run(rs.repopath, "git", "describe --tags")
+ log.Warn("getCurrentBranchVersion()", out)
+ rs.currentVersion.Set(out)
+ return out
+}
+
+func (rs *RepoStatus) getLastTagVersion() string {
+ out := run(rs.repopath, "git", "rev-list --tags --max-count=1")
+ log.Warn("getLastTagVersion()", out)
+ rs.lasttagrev = out
+
+ lastreal := "describe --tags " + out
+ // out = run(r.path, "git", "describe --tags c871d5ecf051a7dc4e3a77157cdbc0a457eb9ae1")
+ out = run(rs.repopath, "git", lastreal)
+ rs.lasttag.Set(out)
+ // rs.lastLabel.Set(out)
+ return out
+}
+
+func (rs *RepoStatus) populateTags() {
+ tmp := fullpath(rs.repopath + "/.git/refs/tags")
+ log.Warn("populateTags() path =", tmp)
+ for _, tag := range listFiles(tmp) {
+ if rs.tags[tag] == "" {
+ log.Warn("populateTags() Adding new tag", tag)
+ rs.tagsDrop.AddText(tag)
+ rs.tags[tag] = "origin"
+ }
+ }
+ rs.tagsDrop.SetText(rs.lasttagrev)
+}
+
+func (rs *RepoStatus) checkDirty() bool {
+ out := run(rs.repopath, "git", "diff-index HEAD")
+ if out == "" {
+ log.Warn("checkDirty() no", rs.repopath)
+ rs.dirtyLabel.Set("no")
+ return false
+ } else {
+ log.Warn("checkDirty() true", rs.repopath)
+ rs.dirtyLabel.Set("dirty")
+ return true
+ }
+
+}
+
+func (rs *RepoStatus) checkoutBranch(branch string) {
+ if rs.checkDirty() {
+ log.Warn("checkoutBranch() checkDirty() == true for repo", rs.repopath, "looking for branch:", branch)
+ return
+ }
+ out := run(rs.repopath, "git", "checkout " + branch)
+ log.Warn(rs.repopath, "git checkout " + branch, "returned", out)
+
+ realname := rs.getCurrentBranchName()
+ realversion := rs.getCurrentBranchVersion()
+ log.Warn(rs.repopath, "realname =", realname, "realversion =", realversion)
+ if realname == "jcarr" {
+ rs.jcarrBranch.Set(realversion)
+ }
+ if realname == "devel" {
+ rs.develBranch.Set(realversion)
+ }
+ if realname == "master" {
+ rs.masterBranch.Set(realversion)
+ }
+}
diff --git a/new.go b/new.go
new file mode 100644
index 0000000..c18480e
--- /dev/null
+++ b/new.go
@@ -0,0 +1,35 @@
+package repostatus
+
+import (
+ "go.wit.com/log"
+
+ "go.wit.com/gui/gui"
+ "go.wit.com/gui/gadgets"
+)
+
+func New(p *gui.Node, path string) *RepoStatus {
+ rs := &RepoStatus {
+ hidden: true,
+ ready: false,
+ parent: p,
+ repopath: path,
+ }
+ rs.tags = make(map[string]string)
+ return rs
+}
+
+func (rs *RepoStatus) InitWindow() {
+ if ! rs.Initialized() {
+ log.Log(WARN, "not initalized yet (no parent for the window?)")
+ return
+ }
+ if rs.window != nil {
+ log.Log(WARN, "You already have a window")
+ rs.ready = true
+ return
+ }
+
+ log.Log(WARN, "Creating the Window")
+ rs.window = gadgets.NewBasicWindow(rs.parent, "GO Repo Details")
+ rs.ready = true
+}
diff --git a/structs.go b/structs.go
new file mode 100644
index 0000000..b2b8b94
--- /dev/null
+++ b/structs.go
@@ -0,0 +1,38 @@
+package repostatus
+
+import (
+ "go.wit.com/gui/gui"
+ "go.wit.com/gui/gadgets"
+)
+
+type RepoStatus struct {
+ ready bool
+ hidden bool
+ changed bool
+
+ repopath string
+ lasttagrev string
+ tags map[string]string
+
+ parent *gui.Node
+
+ window *gadgets.BasicWindow
+ group *gui.Node
+ grid *gui.Node
+
+// status *gadgets.OneLiner
+ dirtyLabel *gadgets.OneLiner
+ path *gadgets.OneLiner
+
+ currentBranch *gadgets.OneLiner
+ currentVersion *gadgets.OneLiner
+ tagsDrop *gui.Node
+
+ lasttag *gadgets.OneLiner
+ masterBranch *gadgets.OneLiner
+ develBranch *gadgets.OneLiner
+ jcarrBranch *gadgets.OneLiner
+
+ speed *gadgets.OneLiner
+ speedActual *gadgets.OneLiner
+}
diff --git a/timer.go b/timer.go
new file mode 100644
index 0000000..9e9e589
--- /dev/null
+++ b/timer.go
@@ -0,0 +1,17 @@
+package repostatus
+
+import (
+ "time"
+)
+
+// timeFunction takes a function as an argument and returns the execution time.
+func timeFunction(f func()) time.Duration {
+ startTime := time.Now() // Record the start time
+ f() // Execute the function
+ return time.Since(startTime) // Calculate the elapsed time
+}
+
+func (ls *RepoStatus) SetSpeedActual(s string) {
+ if ! ls.Ready() {return}
+ ls.speedActual.Set(s)
+}
diff --git a/unix.go b/unix.go
new file mode 100644
index 0000000..1f31700
--- /dev/null
+++ b/unix.go
@@ -0,0 +1,54 @@
+// This is a simple example
+package repostatus
+
+import (
+ "os"
+ "os/exec"
+ "strings"
+
+ "go.wit.com/log"
+)
+
+func fullpath(repo string) string {
+ return "/home/jcarr/go/src/" + repo
+}
+
+func run(path string, thing string, cmdline string) string {
+ parts := strings.Split(cmdline, " ")
+ // 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, "cmd error'd out", parts)
+ return ""
+ }
+
+ tmp := string(output)
+ tmp = strings.TrimSpace(tmp)
+
+ // Print the output
+ log.Log(WARN, "run()", path, thing, cmdline, "=", tmp)
+ return tmp
+}
+
+func listFiles(directory string) []string {
+ var files []string
+ fileInfo, err := os.ReadDir(directory)
+ if err != nil {
+ log.Error(err)
+ return nil
+ }
+
+ for _, file := range fileInfo {
+ if !file.IsDir() {
+ files = append(files, file.Name())
+ }
+ }
+
+ return files
+}
diff --git a/update.go b/update.go
new file mode 100644
index 0000000..e7544d6
--- /dev/null
+++ b/update.go
@@ -0,0 +1,57 @@
+package repostatus
+
+import (
+ "fmt"
+ "time"
+ "errors"
+
+ "go.wit.com/log"
+)
+
+func (rs *RepoStatus) Update() {
+ 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(WARN, "Update() START")
+ duration := timeFunction(func () {
+ 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")
+ })
+ rs.setSpeed(duration)
+ log.Log(WARN, "Update() END")
+}
+
+func (rs *RepoStatus) setSpeed(duration time.Duration) {
+ s := fmt.Sprint(duration)
+ if rs.speedActual == nil {
+ log.Log(WARN, "can't actually warn")
+ return
+ }
+ rs.speedActual.Set(s)
+
+ if (duration > 500 * time.Millisecond ) {
+ rs.speed.Set("SLOW")
+ } else if (duration > 100 * time.Millisecond ) {
+ rs.speed.Set("OK")
+ } else {
+ rs.speed.Set("FAST")
+ }
+}