forge/doGui.go

548 lines
13 KiB
Go
Raw Normal View History

2025-02-01 11:57:52 -06:00
// Copyright 2017-2025 WIT.COM Inc. All rights reserved.
// Use of this source code is governed by the GPL 3.0
2024-12-05 12:29:47 -06:00
package main
// An app to submit patches for the 30 GO GUI repos
import (
2025-02-21 08:20:44 -06:00
"fmt"
2025-01-19 02:56:48 -06:00
"os"
"time"
2025-01-19 02:56:48 -06:00
2024-12-05 12:29:47 -06:00
"go.wit.com/gui"
2025-02-13 20:10:45 -06:00
"go.wit.com/lib/debugger"
2024-12-05 12:29:47 -06:00
"go.wit.com/lib/gadgets"
"go.wit.com/lib/gui/shell"
2025-02-13 22:52:10 -06:00
"go.wit.com/lib/protobuf/gitpb"
2024-12-05 12:29:47 -06:00
"go.wit.com/log"
)
2025-01-08 04:07:33 -06:00
func debug() {
2025-02-21 18:31:26 -06:00
time.Sleep(2 * time.Second)
2025-02-10 23:42:21 -06:00
for {
2025-02-21 18:49:33 -06:00
var found *gitpb.Repos
2025-02-21 08:20:44 -06:00
now := time.Now()
tmp := fmt.Sprintf("All (%d)", me.forge.Repos.Len())
me.repoAllB.SetLabel(tmp)
2025-02-21 18:49:33 -06:00
found = findMergeToDevel()
tmp = fmt.Sprintf("needs merge to devel (%d)", found.Len())
2025-02-21 08:20:44 -06:00
me.repoDevelMergeB.SetLabel(tmp)
2025-02-21 18:49:33 -06:00
found = gitpb.NewRepos()
2025-02-21 08:20:44 -06:00
all := me.forge.Repos.SortByFullPath()
for all.Scan() {
repo := all.Next()
if me.forge.Config.IsReadOnly(repo.GetGoPath()) {
continue
}
2025-02-21 18:49:33 -06:00
found.AppendByGoPath(repo)
2025-02-21 08:20:44 -06:00
}
2025-02-21 18:49:33 -06:00
tmp = fmt.Sprintf("writable (%d)", found.Len())
2025-02-21 08:20:44 -06:00
me.repoWritableB.SetLabel(tmp)
2025-02-21 18:31:26 -06:00
doCheckDirtyAndConfigSave()
2025-02-21 18:49:33 -06:00
found = findDirty()
2025-02-21 18:31:26 -06:00
tmp = fmt.Sprintf("dirty (%d)", found.Len())
2025-02-21 08:20:44 -06:00
me.repoDirtyB.SetLabel(tmp)
log.Printf("finished a forge scan here in (%s)\n", shell.FormatDuration(time.Since(now)))
2025-02-10 23:42:21 -06:00
time.Sleep(90 * time.Second)
2025-02-21 08:20:44 -06:00
2025-02-10 23:42:21 -06:00
}
2025-01-08 04:07:33 -06:00
}
2024-12-05 12:29:47 -06:00
func doGui() {
if me.forge.Config.GetDefaultGui() == "" {
me.forge.Config.DefaultGui = "gocui"
me.forge.ConfigSave()
}
2024-12-05 12:29:47 -06:00
me.myGui = gui.New()
me.myGui.InitEmbed(resources)
me.myGui.SetAppDefaultPlugin(me.forge.Config.DefaultGui) // sets the default GUI plugin to use
2024-12-05 12:29:47 -06:00
me.myGui.Default()
2025-01-30 07:30:04 -06:00
mainWindow := gadgets.RawBasicWindow("Forge: (this kinda works sometimes)")
mainWindow.Make()
mainWindow.Show()
mainWindow.Custom = func() {
2025-01-19 02:56:48 -06:00
log.Warn("MAIN WINDOW CLOSE")
now := time.Now()
2025-01-19 02:56:48 -06:00
count := me.forge.RillReload()
log.Info("Repo Reload count =", count)
if count != 0 {
me.forge.ConfigSave()
}
log.Printf("rill repos.Reload() took (%s)\n", shell.FormatDuration(time.Since(now)))
2025-01-19 02:56:48 -06:00
os.Exit(0)
}
2025-01-30 07:30:04 -06:00
drawWindow(mainWindow)
2024-12-05 12:29:47 -06:00
// sits here forever
debug()
2024-12-05 12:29:47 -06:00
2025-01-20 02:50:07 -06:00
}
2025-01-30 07:30:04 -06:00
func drawWindow(win *gadgets.BasicWindow) {
box := win.Box()
vbox := box.NewVerticalBox("BOX2")
2025-01-20 02:50:07 -06:00
group1 := vbox.NewGroup("Forge Settings")
grid := group1.NewGrid("buildOptions", 0, 0)
// me.autoWorkingPwd = gadgets.NewOneLiner(grid, "working directory (pwd)")
me.goSrcPwd = gadgets.NewOneLiner(grid, "repo src home")
2025-02-22 04:46:45 -06:00
grid.NewLabel("")
2025-02-22 06:52:40 -06:00
var howtoWin *genericWindow
me.demoB = grid.NewButton("Howto", func() {
if howtoWin != nil {
howtoWin.Toggle()
return
}
howtoWin = makeHowtoWin()
2025-02-22 04:46:45 -06:00
})
2025-01-20 02:50:07 -06:00
grid.NextRow()
2025-02-22 06:52:40 -06:00
me.goSrcPwd.SetText(me.forge.GetGoSrc())
2025-01-20 02:50:07 -06:00
// use ENV GIT_AUTHOR
me.gitAuthor = gadgets.NewOneLiner(grid, "Git Author")
grid.NextRow()
if os.Getenv("GIT_AUTHOR_NAME") == "" {
me.gitAuthor.SetText("ENV GIT_AUTHOR_NAME is unset")
} else {
author := os.Getenv("GIT_AUTHOR_NAME")
author += " <" + os.Getenv("GIT_AUTHOR_EMAIL") + ">"
me.gitAuthor.SetText(author)
}
// select the branch you want to test, build and develop against
// this lets you select your user branch, but, when you are happy
// you can merge everything into the devel branch and make sure it actually
// works. Then, when that is good, merge and version everything in master
2025-01-30 07:21:08 -06:00
me.setBranchB = grid.NewButton("git checkout", func() {
win.Disable()
defer win.Enable()
if me.autoCreateBranches.Checked() {
argv.Force = true
} else {
argv.Force = false
2025-01-20 02:50:07 -06:00
}
2025-02-09 03:17:56 -06:00
// do the checkout
if err := doCheckoutShared(); err != nil {
2025-02-09 03:17:56 -06:00
log.Info("checkout error:", err)
} else {
log.Info("checkout was ok")
2025-01-20 02:50:07 -06:00
}
})
2025-02-10 23:42:21 -06:00
/*
me.setBranchB = grid.NewButton("git repos", func() {
t := me.forge.Repos.NewTable()
fp := t.AddFullPath("Full Path")
fp.Custom( func() {
log.Info("this is the full path")
})
t.AddMasterVersion("master version")
t.Show()
})
*/
2025-01-30 07:21:08 -06:00
me.newBranch = grid.NewDropdown()
2025-01-20 02:50:07 -06:00
me.newBranch.AddText("master")
me.newBranch.AddText("devel")
2025-02-22 06:52:40 -06:00
me.newBranch.AddText(me.forge.Config.GetUsername())
me.newBranch.SetText(me.forge.Config.GetUsername())
me.argvCheckoutUser = true
me.newBranch.Custom = func() {
// toggle global values shared by the command line and the gui for doCheckout()
me.argvCheckoutUser = false
me.argvCheckoutDevel = false
me.argvCheckoutMaster = false
switch me.newBranch.String() {
case "master":
me.argvCheckoutMaster = true
case "devel":
me.argvCheckoutDevel = true
default:
me.argvCheckoutUser = true
}
2025-02-09 08:28:28 -06:00
log.Info("forged changed to default:", me.newBranch.String())
}
2025-01-20 02:50:07 -06:00
// checking this will automatically make the branches off of devel
2025-01-30 07:21:08 -06:00
me.autoCreateBranches = grid.NewCheckbox("auto create branches").SetChecked(true)
2025-01-20 02:50:07 -06:00
grid.NextRow()
2025-02-21 05:41:30 -06:00
group2 := vbox.NewGroup("Repos")
grid = group2.RawGrid()
2025-02-21 08:20:44 -06:00
me.repoDirtyB = grid.NewButton("dirty", func() {
2025-02-21 18:31:26 -06:00
doCheckDirtyAndConfigSave()
found := findDirty()
_, box := makeStandardReposWindow("dirty repos", found)
2025-02-22 03:40:37 -06:00
hbox := box.Box().Horizontal()
hbox.NewButton("commit all", func() {
2025-02-21 18:31:26 -06:00
all := found.SortByFullPath()
for all.Scan() {
repo := all.Next()
log.Info("do commit here on", repo.GetGoPath())
}
log.Info("TODO: fix this")
log.Info("run 'forge commit --all'")
})
2025-02-21 05:41:30 -06:00
})
2025-02-21 08:20:44 -06:00
me.repoWritableB = grid.NewButton("writable", func() {
me.found = new(gitpb.Repos)
all := me.forge.Repos.SortByFullPath()
for all.Scan() {
repo := all.Next()
if me.forge.Config.IsReadOnly(repo.GetGoPath()) {
continue
}
me.found.AppendByGoPath(repo)
}
makeStandardReposWindow("Repos that you have write access to", me.found)
2025-02-21 08:20:44 -06:00
})
2025-02-21 16:55:17 -06:00
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)
})
me.repoDevelMergeB = grid.NewButton("merge", func() {
2025-02-21 18:49:33 -06:00
found := findMergeToDevel()
2025-02-22 18:46:00 -06:00
_, box := makeStandardReposWindow("repos to merge from user to devel", found)
hbox := box.Box().Horizontal()
hbox.NewButton("merge all", func() {
2025-02-22 18:55:46 -06:00
win.Disable()
defer win.Enable()
2025-02-22 18:46:00 -06:00
all := found.SortByFullPath()
for all.Scan() {
repo := all.Next()
2025-02-22 18:55:46 -06:00
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
}
2025-02-22 19:11:42 -06:00
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
}
2025-02-22 18:55:46 -06:00
2025-02-22 18:46:00 -06:00
}
})
2025-02-20 06:49:16 -06:00
})
2025-02-21 09:13:54 -06:00
var problemsWin *repoProblemsWindow
grid.NewButton("Repo Problems", func() {
if problemsWin != nil {
problemsWin.Toggle()
return
}
problemsWin = makeRepoProblemsWindow()
2025-02-21 08:20:44 -06:00
})
2025-02-21 09:13:54 -06:00
grid.NextRow()
2025-02-21 08:20:44 -06:00
2025-02-21 09:13:54 -06:00
group2 = vbox.NewGroup("Merge")
grid = group2.RawGrid()
2025-02-13 22:52:10 -06:00
grid.NewButton("merge to devel", func() {
win.Disable()
defer win.Enable()
2025-02-13 23:20:24 -06:00
mergeUserToDevel(me.autoCreateBranches.Checked())
})
grid.NewButton("merge to master", func() {
win.Disable()
defer win.Enable()
mergeDevelToMaster(me.autoCreateBranches.Checked())
})
2025-02-14 19:15:39 -06:00
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")
}
2025-02-14 19:17:56 -06:00
mergeUserToDevel(me.autoCreateBranches.Checked())
2025-02-14 19:15:39 -06:00
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(me.autoCreateBranches.Checked())
})
2025-02-21 05:41:30 -06:00
2025-02-21 09:13:54 -06:00
group3 := vbox.NewGroup("work in progress")
2025-02-21 05:41:30 -06:00
grid = group3.RawGrid()
2025-02-21 09:13:54 -06:00
grid.NewButton("forge ConfigSave()", func() {
me.forge.ConfigSave()
})
grid.NewButton("debugger()", func() {
debugger.DebugWindow()
})
var patchWin *patchesWindow
grid.NewButton("Patches Window", func() {
if patchWin != nil {
patchWin.Toggle()
2025-02-21 05:41:30 -06:00
return
}
2025-02-21 09:13:54 -06:00
patchWin = new(patchesWindow)
patchWin.initWindow()
patchWin.Show()
2025-02-21 05:41:30 -06:00
})
}
// this is the magic that generates a window directly from the protocol buffer
func makeStandardReposGrid(pb *gitpb.Repos) *gitpb.ReposTable {
t := pb.NewTable("testDirty")
sf := t.AddStringFunc("repo", func(r *gitpb.Repo) string {
return r.GetGoPath()
})
// t.Custom = func() {
// log.Info("close grid?")
// }
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()
return t
}
2025-02-21 09:13:54 -06:00
// this is the magic that generates a window directly from the protocol buffer
2025-02-21 18:31:26 -06:00
func makeStandardReposWindow(title string, pb *gitpb.Repos) (*gitpb.ReposTable, *gui.Node) {
win := gadgets.RawBasicWindow(title)
win.Make()
win.Show()
win.Custom = func() {
// sets the hidden flag to false so Toggle() works
win.Hide()
2025-02-21 05:41:30 -06:00
}
box := win.Box().NewBox("bw vbox", false)
t := makeStandardReposGrid(pb)
t.SetParent(box)
2025-02-21 05:41:30 -06:00
t.ShowTable()
2025-02-21 18:31:26 -06:00
return t, box
2025-02-13 23:20:24 -06:00
}
2025-02-21 18:49:33 -06:00
func findMergeToDevel() *gitpb.Repos {
found := gitpb.NewRepos()
2025-02-13 23:46:11 -06:00
all := me.forge.Repos.SortByFullPath()
for all.Scan() {
repo := all.Next()
// this sees if user has patches for devel. If it does, add it to me.found
if repo.CountDiffObjects(repo.GetUserBranchName(), repo.GetDevelBranchName()) > 0 {
2025-02-21 18:49:33 -06:00
found.AppendByGoPath(repo)
2025-02-13 23:46:11 -06:00
}
}
now := time.Now()
2025-02-21 18:49:33 -06:00
if found.Len() == 0 {
2025-02-13 23:46:11 -06:00
log.Info("nothing to merge with devel")
2025-02-21 18:49:33 -06:00
return found
2025-02-13 23:46:11 -06:00
}
2025-02-21 18:49:33 -06:00
// me.forge.PrintHumanTable(found)
2025-02-13 23:46:11 -06:00
// check for merges from devel
total, count, nope, _ := IsEverythingOnDevel()
log.Printf("devel branch check. %d total repos. (%d ok) (%d not on devel branch) (%s)\n", total, count, nope, shell.FormatDuration(time.Since(now)))
2025-02-21 18:49:33 -06:00
return found
2025-02-13 23:46:11 -06:00
}
2025-02-13 23:20:24 -06:00
func findMergeToMaster() {
me.found = new(gitpb.Repos)
all := me.forge.Repos.SortByFullPath()
for all.Scan() {
repo := all.Next()
if me.forge.Config.IsReadOnly(repo.GetGoPath()) {
continue
2025-02-13 22:52:10 -06:00
}
2025-02-13 23:38:22 -06:00
/*
if repo.IsDirty() {
continue
}
if repo.GetMasterVersion() != repo.GetDevelVersion() {
me.found.AppendByGoPath(repo)
continue
}
*/
// this sees if devel is behind master. IT SHOULD NOT BE
if repo.CountDiffObjects(repo.GetMasterBranchName(), repo.GetDevelBranchName()) == 0 {
// everything is normal
} else {
repo.State = "DEVEL < MASTER"
log.Info("SERIOUS ERROR. DEVEL BRANCH IS BEHIND MASTER", repo.GetGoPath())
}
// this sees if devel has patches for master. If it does, add it to me.found
2025-02-13 23:46:11 -06:00
if repo.CountDiffObjects(repo.GetDevelBranchName(), repo.GetMasterBranchName()) > 0 {
2025-02-13 23:20:24 -06:00
me.found.AppendByGoPath(repo)
}
}
now := time.Now()
if me.found.Len() == 0 {
log.Info("nothing to merge with master")
return
}
me.forge.PrintHumanTable(me.found)
2025-02-13 22:52:10 -06:00
2025-02-13 23:20:24 -06:00
// check for merges from devel
total, count, nope, _ := IsEverythingOnMaster()
log.Printf("Master branch check. %d total repos. (%d ok) (%d not on master branch) (%s)\n", total, count, nope, shell.FormatDuration(time.Since(now)))
}
func mergeDevelToMaster(doit bool) {
findMergeToMaster()
if !doit {
return
}
all := me.found.SortByFullPath()
for all.Scan() {
repo := all.Next()
log.Info("repo:", repo.GetGoPath())
if result, err := repo.MergeToMaster(); err == nil {
log.Warn("THINGS SEEM OK", repo.GetFullPath())
for _, line := range result.Stdout {
log.Warn("stdout:", line)
}
for _, line := range result.Stderr {
log.Warn("stderr:", line)
}
2025-02-13 22:52:10 -06:00
} else {
2025-02-13 23:20:24 -06:00
log.Warn("THINGS FAILED ", repo.GetFullPath())
log.Warn("err", err)
if result == nil {
break
}
for _, line := range result.Stdout {
log.Warn("stdout:", line)
}
for _, line := range result.Stderr {
log.Warn("stderr:", line)
}
log.Warn("THINGS FAILED ", repo.GetFullPath())
break
2025-02-13 22:52:10 -06:00
}
2025-02-13 23:20:24 -06:00
me.forge.SetConfigSave(true)
// view.Update()
}
me.forge.ConfigSave()
}
2025-02-13 22:52:10 -06:00
2025-02-13 23:20:24 -06:00
func mergeUserToDevel(doit bool) {
2025-02-21 18:49:33 -06:00
found := findMergeToDevel()
2025-02-13 23:20:24 -06:00
if !doit {
return
}
2025-02-21 18:49:33 -06:00
all := found.SortByFullPath()
2025-02-13 23:20:24 -06:00
for all.Scan() {
repo := all.Next()
2025-02-18 09:39:30 -06:00
bruser := repo.GetUserBranchName()
brdevel := repo.GetDevelBranchName()
if repo.GetUserVersion() == "uerr" {
// no user branch
return
}
log.Info("trying", bruser, repo.GetUserVersion())
b1 := repo.CountDiffObjects(bruser, brdevel) // should be zero
if b1 == 0 {
// log.Info("User is already merged into Devel", repo.GetGoPath(), cmd)
return
}
log.Info("merging user into devel repo:", repo.GetGoPath())
2025-02-13 23:20:24 -06:00
if result, err := repo.MergeToDevel(); err == nil {
log.Warn("THINGS SEEM OK", repo.GetFullPath())
for _, line := range result.Stdout {
log.Warn("stdout:", line)
}
for _, line := range result.Stderr {
log.Warn("stderr:", line)
}
} else {
log.Warn("THINGS FAILED ", repo.GetFullPath())
log.Warn("err", err)
if result == nil {
2025-02-13 22:52:10 -06:00
break
}
2025-02-13 23:20:24 -06:00
for _, line := range result.Stdout {
log.Warn("stdout:", line)
}
for _, line := range result.Stderr {
log.Warn("stderr:", line)
}
break
2025-02-13 22:52:10 -06:00
}
2025-02-13 23:20:24 -06:00
me.forge.SetConfigSave(true)
// view.Update()
}
me.forge.ConfigSave()
2024-12-05 12:29:47 -06:00
}