// Copyright 2017-2025 WIT.COM Inc. All rights reserved. // Use of this source code is governed by the GPL 3.0 package main import ( "fmt" "sync" "go.wit.com/gui" "go.wit.com/lib/gadgets" "go.wit.com/lib/protobuf/forgepb" "go.wit.com/log" ) type stdPatchsetTableWin struct { sync.Mutex win *gadgets.GenericWindow // the machines gui window box *gui.Node // the machines gui parent box widget TB *forgepb.PatchsetsTable // the gui table buffer update bool // if the window should be updated } func (w *stdPatchsetTableWin) Toggle() { if w == nil { return } if w.win == nil { return } w.win.Toggle() } func makePatchsetsWin() *stdPatchsetTableWin { dwin := new(stdPatchsetTableWin) dwin.win = gadgets.NewGenericWindow("forge current patchsets", "patchset options") dwin.win.Custom = func() { log.Info("test delete window here") } grid := dwin.win.Group.RawGrid() grid.NewButton("ondisk", func() { openPatchsets() if me.psets == nil { log.Info("No Patchsets loaded") return } dwin.doPatchsetsTable(me.psets) }) grid.NewButton("upstream", func() { psets, err := me.forge.GetPatchesets() if err != nil { log.Info("Get Patchsets failed", err) return } dwin.doPatchsetsTable(psets) }) grid.NewButton("analyse and save patchsets", func() { if me.psets == nil { log.Info("No Patchsets loaded") return } all := me.psets.All() for all.Scan() { pset := all.Next() if pset.State == "" { log.Info("What is up with?", pset.Name) setPatchsetState(pset) } else { log.Info("patchset already had state", pset.Name, pset.State) } } savePatchsets() }) // make a box at the bottom of the window for the protobuf table dwin.box = dwin.win.Bottom.Box().SetProgName("TBOX") // load and show the current patch sets openPatchsets() if me.psets == nil { log.Info("Open Patchsets failed") return dwin } dwin.doPatchsetsTable(me.psets) return dwin } func (dwin *stdPatchsetTableWin) doPatchsetsTable(currentPatchsets *forgepb.Patchsets) { dwin.Lock() defer dwin.Unlock() if dwin.TB != nil { dwin.TB.Delete() dwin.TB = nil } // display the protobuf dwin.TB = AddPatchsetsPB(dwin.box, currentPatchsets) f := func(pset *forgepb.Patchset) { log.Info("Triggered. do something here", pset.Name) /* win := makePatchWindow(pset) win.Show() */ } dwin.TB.Custom(f) } func AddPatchsetsPB(tbox *gui.Node, pb *forgepb.Patchsets) *forgepb.PatchsetsTable { t := pb.NewTable("PatchsetsPB") t.NewUuid() t.SetParent(tbox) t.AddStringFunc("#", func(p *forgepb.Patchset) string { return fmt.Sprintf("%d", p.Patches.Len()) }) testf := func(p *forgepb.Patchset) string { return "validate" } tp := t.AddButtonFunc("Analyze", testf) tp.Custom = func(p *forgepb.Patchset) { setPatchsetState(p) log.Info("patchset state", p.Name, "is", p.State) } vp := t.AddButtonFunc("View Patchset", func(p *forgepb.Patchset) string { return p.Name }) vp.Custom = func(pset *forgepb.Patchset) { log.Info("show patches here", pset.Name) makePatchesWin(pset.Patches) // patchwin := makePatchesWin() // patchwin.doPatchesTable(pset.Patches) /* win := makePatchWindow(pset) win.Show() */ } t.AddComment() t.AddState() ctimef := func(p *forgepb.Patchset) string { ctime := p.Ctime.AsTime() return ctime.Format("2006/01/02 15:04") } t.AddStringFunc("ctime", ctimef) /* etimef := func(e *forgepb.Patchset) string { etime := e.Etime.AsTime() s := etime.Format("2006/01/02 15:04") if strings.HasPrefix(s, "1970/") { // just show a blank if it's not set return "" } return s } t.AddStringFunc("etime", etimef) */ t.AddStringFunc("Author", func(p *forgepb.Patchset) string { return fmt.Sprintf("%s <%s>", p.GitAuthorName, p.GitAuthorEmail) }) t.AddUuid() t.ShowTable() return t } func setPatchsetState(p *forgepb.Patchset) { var bad bool var good bool var done bool = true all := p.Patches.All() for all.Scan() { patch := all.Next() // log.Info("patch:", patch.StartHash, patch.CommitHash, patch.RepoNamespace, patch.Filename) repo := me.forge.FindByGoPath(patch.RepoNamespace) if repo == nil { log.Info("couldn't find repo", patch.RepoNamespace) bad = true continue } if _, err := repo.GetHashName(patch.CommitHash); err == nil { // this patch has been applied patch.Applied = true done = true continue } if name, err := repo.GetHashName(patch.StartHash); err == nil { // it might be possible to apply this patch log.Info("patch may be good:", patch.RepoNamespace, name, patch.CommitHash, patch.Filename) good = true } else { // probably screwed up git trees log.Info("patch with unknown origin:", patch.RepoNamespace, name, err, patch.CommitHash, patch.Filename) bad = true } } if bad { p.State = "BAD" return } if good { p.State = "TRY" return } if done { p.State = "DONE" return } }