summaryrefslogtreecommitdiff
path: root/windowReposFix.go
diff options
context:
space:
mode:
Diffstat (limited to 'windowReposFix.go')
-rw-r--r--windowReposFix.go615
1 files changed, 615 insertions, 0 deletions
diff --git a/windowReposFix.go b/windowReposFix.go
new file mode 100644
index 0000000..f643164
--- /dev/null
+++ b/windowReposFix.go
@@ -0,0 +1,615 @@
+// Copyright 2017-2025 WIT.COM Inc. All rights reserved.
+// Use of this source code is governed by the GPL 3.0
+
+package main
+
+// An app to submit patches for the 30 GO GUI repos
+
+import (
+ "fmt"
+ "os"
+ "sync"
+ "time"
+
+ "go.wit.com/gui"
+ "go.wit.com/lib/debugger"
+ "go.wit.com/lib/gadgets"
+ "go.wit.com/lib/protobuf/gitpb"
+ "go.wit.com/log"
+)
+
+type stdReposTableWin struct {
+ sync.Mutex
+ win *gadgets.GenericWindow // the machines gui window
+ boxTB *gui.Node // the machines gui parent box widget
+ TB *gitpb.ReposTable // the gui table buffer
+ pb *gitpb.Repos // the current repos protobuf
+ update bool // if the window should be updated
+}
+
+func (w *stdReposTableWin) Toggle() {
+ if w == nil {
+ return
+ }
+ if w.win == nil {
+ return
+ }
+ w.win.Toggle()
+}
+
+func makeReposWin() *stdReposTableWin {
+ rwin := new(stdReposTableWin)
+ win := gadgets.NewGenericWindow("git repos", "All about git repos")
+ rwin.win = win
+ grid := win.Group.RawGrid()
+
+ me.repoDirtyB = grid.NewButton("dirty", func() {
+ doCheckDirtyAndConfigSave()
+ found := findDirty()
+ tb, box := makeStandardReposWindow("dirty repos", found)
+ hbox := box.Box().Horizontal()
+ hbox.NewButton("commit all", func() {
+ for repo := range found.IterByFullPath() {
+ log.Info("do commit here on", repo.GetGoPath())
+ }
+ log.Info("TODO: fix this")
+ log.Info("run 'forge commit --all'")
+ })
+ hbox.NewButton("update table", func() {
+ me.forge.PrintHumanTable(found)
+ found2 := findDirty()
+ me.forge.PrintHumanTable(found2)
+ // tb.Update()
+ // tb.UpdateTable(found2)
+ })
+ hbox.NewButton("delete table", func() {
+ tb.Delete()
+ })
+ })
+
+ var writeWin *gadgets.GenericWindow
+ me.repoWritableB = grid.NewButton("writable", func() {
+ // if the window exists, just toggle it open or closed
+ if writeWin != nil {
+ writeWin.Toggle()
+ return
+ }
+
+ // make the window for the first time
+ found := new(gitpb.Repos)
+ for repo := range me.forge.Repos.IterByFullPath() {
+ if me.forge.Config.IsReadOnly(repo.GetGoPath()) {
+ continue
+ }
+
+ found.AppendByGoPath(repo)
+
+ }
+ writeWin, _ = makeWritableWindow(found)
+ writeWin.Win.Custom = func() {
+ log.Info("closing window. could do somethine here")
+ }
+ })
+
+ me.repoAllB = grid.NewButton("All", func() {
+ me.found = new(gitpb.Repos)
+ all := me.forge.Repos.SortByFullPath()
+ for all.Scan() {
+ repo := all.Next()
+ me.found.AppendByGoPath(repo)
+
+ }
+ makeStandardReposWindow("All repos", me.found)
+ })
+
+ var insertWin *gadgets.GenericWindow
+ me.repoWritableB = grid.NewButton("insert test", func() {
+ // if the window exists, just toggle it open or closed
+ if insertWin != nil {
+ insertWin.Toggle()
+ return
+ }
+
+ insertWin = makeWindowForPB()
+ insertWin.Win.Custom = func() {
+ log.Info("test delete window here")
+ }
+ grid := insertWin.Group.RawGrid()
+
+ var t *gitpb.ReposTable
+ grid.NewButton("dirty", func() {
+ if t != nil {
+ t.Delete()
+ t = nil
+ }
+ found := findDirty()
+
+ // display the protobuf
+ t = addWindowPB(insertWin, found)
+ f := func(repo *gitpb.Repo) {
+ log.Info("got to ReposTable.Custom() id =", repo.GetGoPath(), repo.GetCurrentVersion())
+ }
+ t.Custom(f)
+ log.Info("table has uuid", t.GetUuid())
+ })
+
+ grid.NewButton("all", func() {
+ if t != nil {
+ t.Delete()
+ t = nil
+ }
+ found := new(gitpb.Repos)
+ all := me.forge.Repos.SortByFullPath()
+ for all.Scan() {
+ repo := all.Next()
+ found.AppendByGoPath(repo)
+
+ }
+ // display the protobuf
+ t = addWindowPB(insertWin, found)
+ f := func(repo *gitpb.Repo) {
+ log.Info("got to ReposTable.Custom() id =", repo.GetGoPath(), repo.GetCurrentVersion())
+ }
+ t.Custom(f)
+ log.Info("table has uuid", t.GetUuid())
+ })
+
+ grid.NewButton("writeable", func() {
+ if t != nil {
+ t.Delete()
+ t = nil
+ }
+ found := new(gitpb.Repos)
+ all := me.forge.Repos.SortByFullPath()
+ for all.Scan() {
+ repo := all.Next()
+ if me.forge.Config.IsReadOnly(repo.GetGoPath()) {
+ continue
+ }
+
+ found.AppendByGoPath(repo)
+
+ }
+
+ // make the window for the first time
+ t = addWindowPB(insertWin, found)
+ f := func(repo *gitpb.Repo) {
+ log.Info("got to ReposTable.Custom() id =", repo.GetGoPath(), repo.GetCurrentVersion())
+ }
+ t.Custom(f)
+ log.Info("table has uuid", t.GetUuid())
+ })
+ })
+
+ grid.NewButton("Configure", func() {
+ log.Info("add a forge config window here")
+ })
+
+ win.Top.NewGroup("misc (works in progress)")
+
+ grid = win.Top.RawGrid()
+ var found *gitpb.Repos
+ var txt string
+
+ found = develBehindMasterProblem()
+ txt = fmt.Sprintf("devel is behind master (%d)", found.Len())
+ grid.NewButton(txt, func() {
+ win := gadgets.RawBasicWindow("devel branches that are out of sync with master")
+ win.Make()
+ win.Show()
+ win.Custom = func() {
+ // sets the hidden flag to false so Toggle() works
+ win.Hide()
+ }
+ box := win.Box().NewBox("bw vbox", false)
+
+ found := develBehindMasterProblem()
+ group := box.NewGroup("test buttons")
+ hbox := group.Box().Horizontal()
+ hbox.NewButton("git merge master devel", func() {
+ all := found.SortByFullPath()
+ for all.Scan() {
+ repo := all.Next()
+ mname := repo.GetMasterBranchName()
+ dname := repo.GetDevelBranchName()
+ if dname != repo.GetCurrentBranchName() {
+ log.Info("Repo is not on the devel branch", repo.GetGoPath())
+ }
+ cmd := []string{"git", "merge", mname}
+ log.Info(repo.GetGoPath(), cmd)
+ repo.RunVerbose(cmd)
+ }
+ })
+ hbox.NewButton("test", func() {
+ })
+
+ t := makeDevelBehindMaster(found)
+ t.SetParent(box)
+ t.ShowTable()
+ })
+
+ found = remoteUserBranchProblem()
+ txt = fmt.Sprintf("user branch is remote (%d)", found.Len())
+ grid.NewButton(txt, func() {
+ win := gadgets.RawBasicWindow("repos that seem to have remote user branches")
+ win.Make()
+ win.Show()
+ win.Custom = func() {
+ // sets the hidden flag to false so Toggle() works
+ win.Hide()
+ }
+ box := win.Box().NewBox("bw vbox", false)
+
+ found := remoteUserBranchProblem()
+ group := box.NewGroup("test buttons")
+ hbox := group.Box().Horizontal()
+ hbox.NewButton("git branch delete", func() {
+ win.Disable()
+ defer win.Enable()
+ all := found.SortByFullPath()
+ for all.Scan() {
+ repo := all.Next()
+ brname := repo.GetUserBranchName()
+ // git push origin --delete jcarr
+ os.Setenv("GIT_TERMINAL_PROMPT", "0")
+ cmd := []string{"git", "push", "origin", "--delete", brname}
+ log.Info("You may want to run:", repo.GetGoPath(), cmd)
+ repo.RunVerbose(cmd)
+ os.Unsetenv("GIT_TERMINAL_PROMPT")
+
+ // git branch --delete --remote origin/jcarr
+ cmd = []string{"git", "branch", "--delete", "--remote", "origin/" + brname}
+ log.Info(repo.GetGoPath(), cmd)
+ repo.RunVerbose(cmd)
+ repo.Reload()
+ }
+ me.forge.SetConfigSave(true)
+ me.forge.ConfigSave()
+ })
+
+ t := makeStandardReposGrid(found)
+ t.SetParent(box)
+ t.ShowTable()
+ })
+
+ rwin.boxTB = win.Bottom.Box()
+
+ grid.NewButton("dirty on bottom", func() {
+ log.Info("try to show dirty repos on bottom")
+ found := findDirty()
+ rwin.doReposTable(found)
+
+ })
+ grid.NextRow()
+
+ found = develRemoteProblem()
+ txt = fmt.Sprintf("remote devel != local devel (%d)", found.Len())
+ grid.NewButton(txt, func() {
+ found := develRemoteProblem()
+ makeStandardReposWindow(txt, found)
+ })
+
+ found = masterRemoteProblem()
+ txt = fmt.Sprintf("remote master != local master (%d)", found.Len())
+ grid.NewButton(txt, func() {
+ found := masterRemoteProblem()
+ makeStandardReposWindow(txt, found)
+ })
+ grid.NextRow()
+
+ makeHackModeWindow(win)
+ return rwin
+}
+
+// table of devel errors behind master
+func makeDevelBehindMaster(pb *gitpb.Repos) *gitpb.ReposTable {
+ t := pb.NewTable("testDirty")
+ t.NewUuid()
+ sf := t.AddStringFunc("repo", func(r *gitpb.Repo) string {
+ return r.GetGoPath()
+ })
+ sf.Custom = func(r *gitpb.Repo) {
+ log.Info("merge master into devel here", r.GetGoPath())
+ }
+ t.AddTimeFunc("age", func(repo *gitpb.Repo) time.Time {
+ return repo.NewestTime()
+ })
+ t.AddMasterVersion()
+ t.AddDevelVersion()
+ t.AddState()
+ return t
+}
+
+// default window for active running droplets
+func (rwin *stdReposTableWin) doReposTable(pb *gitpb.Repos) {
+ rwin.Lock()
+ defer rwin.Unlock()
+ if rwin.TB != nil {
+ rwin.TB.Delete()
+ rwin.TB = nil
+ }
+
+ rwin.pb = pb
+
+ t := makeStandardReposGrid(pb)
+ t.SetParent(rwin.boxTB)
+ t.ShowTable()
+ rwin.TB = t
+}
+
+func makeHackModeWindow(win *gadgets.GenericWindow) {
+ group := win.Top.NewGroup("This is a work in progress")
+ grid := group.RawGrid()
+ grid.NewButton("git pull", func() {
+ log.Info("todo: run git pull on each repo")
+ })
+
+ me.repoDevelMergeB = grid.NewButton("merge", func() {
+ found := findMergeToDevel()
+ _, box := makeStandardReposWindow("repos to merge from user to devel", found)
+ hbox := box.Box().Horizontal()
+ hbox.NewButton("merge all", func() {
+ win.Disable()
+ defer win.Enable()
+ all := found.SortByFullPath()
+ for all.Scan() {
+ repo := all.Next()
+ if repo.CheckDirty() {
+ log.Info("repo is dirty", repo.GetGoPath())
+ continue
+ }
+ log.Info("Starting merge on", repo.GetGoPath())
+ if repo.CheckoutDevel() {
+ log.Info("checkout devel failed", repo.GetGoPath())
+ return
+ }
+ if _, err := repo.MergeToDevel(); err != nil {
+ log.Info("merge from user failed", repo.GetGoPath(), err)
+ // log.Info(strings.Join(r.Stdout, "\n"))
+ // log.Info(strings.Join(r.Stderr, "\n"))
+ return
+ }
+ if repo.CheckoutMaster() {
+ log.Info("checkout master failed", repo.GetGoPath())
+ return
+ }
+ if _, err := repo.MergeToMaster(); err != nil {
+ log.Info("merge from devel failed", repo.GetGoPath(), err)
+ return
+ }
+
+ }
+ })
+ })
+ grid.NextRow()
+
+ group2 := win.Top.NewGroup("Merge")
+ grid = group2.RawGrid()
+
+ grid.NewButton("merge to devel", func() {
+ win.Disable()
+ defer win.Enable()
+
+ mergeUserToDevel(true)
+ })
+
+ grid.NewButton("merge to master", func() {
+ win.Disable()
+ defer win.Enable()
+
+ mergeDevelToMaster(true)
+ })
+
+ grid.NewButton("merge all", func() {
+ win.Disable()
+ defer win.Enable()
+
+ me.argvCheckoutUser = false
+ me.argvCheckoutDevel = true
+ me.argvCheckoutMaster = false
+ if err := doCheckoutShared(); err != nil {
+ log.Info("checkout error:", err)
+ } else {
+ log.Info("checkout was ok")
+ }
+
+ mergeUserToDevel(true)
+
+ me.argvCheckoutUser = false
+ me.argvCheckoutDevel = false
+ me.argvCheckoutMaster = true
+ if err := doCheckoutShared(); err != nil {
+ log.Info("checkout error:", err)
+ } else {
+ log.Info("checkout was ok")
+ }
+
+ mergeDevelToMaster(true)
+ })
+
+ group3 := win.Top.NewGroup("work in progress")
+ grid = group3.RawGrid()
+
+ grid.NewButton("forge ConfigSave()", func() {
+ me.forge.ConfigSave()
+ })
+
+ grid.NewButton("debugger()", func() {
+ debugger.DebugWindow()
+ })
+}
+
+func develBehindMasterProblem() *gitpb.Repos {
+ found := new(gitpb.Repos)
+ all := me.forge.Repos.SortByFullPath()
+ for all.Scan() {
+ repo := all.Next()
+ if repo.GetDevelVersion() == repo.GetMasterVersion() {
+ continue
+ }
+ found.AppendByGoPath(repo)
+
+ }
+ return found
+}
+
+func remoteUserBranchProblem() *gitpb.Repos {
+ found := new(gitpb.Repos)
+ all := me.forge.Repos.SortByFullPath()
+ for all.Scan() {
+ repo := all.Next()
+ username := repo.GetUserBranchName()
+ if repo.IsBranchRemote(username) {
+ found.AppendByGoPath(repo)
+ }
+
+ }
+ return found
+}
+
+func develRemoteProblem() *gitpb.Repos {
+ found := new(gitpb.Repos)
+ all := me.forge.Repos.SortByFullPath()
+ for all.Scan() {
+ repo := all.Next()
+ brname := repo.GetDevelBranchName()
+ if !repo.IsBranchRemote(brname) {
+ // log.Info("repo does not have remote devel branch", repo.GetGoPath())
+ continue
+ }
+ lhash := repo.GetLocalHash(brname)
+ rhash := repo.GetRemoteHash(brname)
+ // log.Info(lhash, rhash, repo.GetGoPath())
+ if lhash == "" || rhash == "" {
+ // something is wrong if either of these are blank
+ found.AppendByGoPath(repo)
+ continue
+ }
+ if lhash == rhash {
+ continue
+ }
+ found.AppendByGoPath(repo)
+
+ }
+ return found
+}
+
+func masterRemoteProblem() *gitpb.Repos {
+ found := new(gitpb.Repos)
+ all := me.forge.Repos.SortByFullPath()
+ for all.Scan() {
+ repo := all.Next()
+ brname := repo.GetMasterBranchName()
+ if !repo.IsBranchRemote(brname) {
+ // log.Info("repo does not have remote devel branch", repo.GetGoPath())
+ continue
+ }
+ lhash := repo.GetLocalHash(brname)
+ rhash := repo.GetRemoteHash(brname)
+ // log.Info(lhash, rhash, repo.GetGoPath())
+ if lhash == "" || rhash == "" {
+ // something is wrong if either of these are blank
+ found.AppendByGoPath(repo)
+ continue
+ }
+ if lhash == rhash {
+ continue
+ }
+ found.AppendByGoPath(repo)
+
+ }
+ return found
+}
+
+func makeWritableWindow(pb *gitpb.Repos) (*gadgets.GenericWindow, *gitpb.ReposTable) {
+ win := gadgets.NewGenericWindow("Repos You have write access to", "Configure")
+ t := pb.NewTable("testForgeRepos")
+ t.NewUuid()
+
+ grid := win.Group.RawGrid()
+ grid.NewButton("git pull", func() {
+ log.Info("todo: run git pull on each repo")
+ })
+
+ /*
+ grid.NewButton("do repos.ReScan()", func() {
+ t.Update()
+ })
+ */
+
+ tbox := win.Bottom.Box()
+ t.SetParent(tbox)
+
+ sf := t.AddStringFunc("repo", func(r *gitpb.Repo) string {
+ return r.GetGoPath()
+ })
+ sf.Custom = func(r *gitpb.Repo) {
+ log.Info("do button click on", r.GetGoPath())
+ }
+ t.AddTimeFunc("age", func(repo *gitpb.Repo) time.Time {
+ return repo.NewestTime()
+ })
+ t.AddMasterVersion()
+ t.AddDevelVersion()
+ t.AddUserVersion()
+ t.AddCurrentBranchName()
+ t.AddState()
+ t.ShowTable()
+ return win, t
+}
+
+func makeWindowForPB() *gadgets.GenericWindow {
+ win := gadgets.NewGenericWindow("Raw PB View", "Configure")
+
+ return win
+}
+
+func addWindowPB(win *gadgets.GenericWindow, pb *gitpb.Repos) *gitpb.ReposTable {
+ t := pb.NewTable("testForgeRepos")
+ t.NewUuid()
+ tbox := win.Bottom.Box().SetProgName("TBOX")
+ t.SetParent(tbox)
+
+ sf := t.AddStringFunc("repo", func(r *gitpb.Repo) string {
+ return r.GetGoPath()
+ })
+ sf.Custom = func(r *gitpb.Repo) {
+ log.Info("do button click on", r.GetGoPath())
+ }
+ t.AddTimeFunc("age", func(repo *gitpb.Repo) time.Time {
+ return repo.NewestTime()
+ })
+ t.AddMasterVersion()
+ t.AddDevelVersion()
+ t.AddUserVersion()
+ t.AddCurrentBranchName()
+ t.AddState()
+ f := func(repo *gitpb.Repo) string {
+ log.Info("repo =", repo.GetGoPath(), repo.GetCurrentVersion())
+ return repo.GetGoPath()
+ }
+ t.AddButtonFunc("cur version", f)
+ t.ShowTable()
+ return t
+}
+
+func makeReposWindowNew() *gadgets.GenericWindow {
+ win := gadgets.NewGenericWindow("git repos", "Filter")
+ win.Custom = func() {
+ // sets the hidden flag to false so Toggle() works
+ win.Hide()
+ }
+
+ hbox := win.Group.Box().Horizontal()
+ hbox.NewCheckbox("broken")
+ hbox.NewCheckbox("dirty")
+ hbox.NewCheckbox("mine")
+ hbox.NewButton("fix all", func() {
+ log.Info("try to fix everything here")
+ })
+
+ t := makeStandardReposGrid(me.forge.Repos)
+ t.SetParent(win.Bottom)
+ t.ShowTable()
+ return win
+}