Compare commits
34 Commits
Author | SHA1 | Date |
---|---|---|
|
3efb520fe0 | |
|
0dea6a2553 | |
|
807049f6c7 | |
|
86e513d845 | |
|
5d57a8968d | |
|
e2d33ea496 | |
|
d3938adf63 | |
|
08b7f2406c | |
|
041be81af1 | |
|
4fc9d038ca | |
|
1ea9bdf841 | |
|
1d50f9eb69 | |
|
d962ff8db0 | |
|
d2a0aa3098 | |
|
47b7222445 | |
|
2616d0d8b4 | |
|
0219d69bfb | |
|
391d47318b | |
|
1282c17e81 | |
|
9f367cb39b | |
|
2f8da5a8be | |
|
912c5a9bb9 | |
|
715b63b1c8 | |
|
ad5d8dbb87 | |
|
8a24141803 | |
|
1c733adfce | |
|
1defa8d582 | |
|
f061bf9730 | |
|
6d62858d69 | |
|
cc8800bf60 | |
|
ef6da4aa17 | |
|
52c9fece43 | |
|
06cf0f7d84 | |
|
99e30376f0 |
9
Makefile
9
Makefile
|
@ -35,7 +35,7 @@ plugin:
|
|||
# -cp ../../toolkits/gocui/gocui.so resources/
|
||||
|
||||
andlabs: clean install
|
||||
forge --gui andlabs
|
||||
forge --gui gocui --gui-verbose --gui-file ../../toolkits/andlabs/andlabs.so
|
||||
|
||||
gocui: install
|
||||
forge --gui gocui --gui-verbose --gui-file ../../toolkits/gocui/gocui.so >/tmp/forge.log 2>&1
|
||||
|
@ -50,10 +50,15 @@ goimports:
|
|||
clean:
|
||||
-rm -f forge go.*
|
||||
# -rm -f ~/go/src/repos.pb
|
||||
go-mod-clean --purge
|
||||
go-mod-clean purge
|
||||
|
||||
identify-protobuf:
|
||||
autogenpb --identify ~/go/src/repos.pb
|
||||
|
||||
devel:
|
||||
forge clean devel --force --verbose
|
||||
|
||||
pull: install
|
||||
forge pull dirty
|
||||
FORGE_URL="http://forge.grid.wit.com:2520/" forge pull
|
||||
# forge pull patches
|
||||
|
|
15
README.md
15
README.md
|
@ -49,3 +49,18 @@ make # this runs GO111MODULE=off go build insuring that y
|
|||
## Debian packages:
|
||||
|
||||
Instructions are on https://mirrors.wit.com/
|
||||
|
||||
## possible 'git bug' integration ideas:
|
||||
|
||||
```
|
||||
git pull origin +refs/bugs/\*:refs/bugs/\*
|
||||
git pull origin +refs/identities/\*:refs/identities/\*
|
||||
|
||||
|
||||
# remove the caches
|
||||
rm -rf .git/git-bug
|
||||
|
||||
|
||||
# rebuild the cache with any command
|
||||
git bug user
|
||||
```
|
||||
|
|
|
@ -48,8 +48,6 @@ func savePatchset(pset *forgepb.Patchset) error {
|
|||
|
||||
// re-run git CheckDirty() on everything
|
||||
func IsAnythingDirty() bool {
|
||||
me.found = new(gitpb.Repos)
|
||||
findAll() // select all the repos
|
||||
doCheckDirtyAndConfigSave()
|
||||
found := findDirty()
|
||||
if found.Len() == 0 {
|
||||
|
|
36
argv.go
36
argv.go
|
@ -17,13 +17,15 @@ var argv args
|
|||
type args struct {
|
||||
Checkout *CheckoutCmd `arg:"subcommand:checkout" help:"switch branches using 'git checkout'"`
|
||||
Clean *CleanCmd `arg:"subcommand:clean" help:"start over at the beginning"`
|
||||
Commit *EmptyCmd `arg:"subcommand:commit" help:"'git commit' but errors out if on wrong branch"`
|
||||
Commit *CommitCmd `arg:"subcommand:commit" help:"'git commit' but errors out if on wrong branch"`
|
||||
Config *ConfigCmd `arg:"subcommand:config" help:"show your .config/forge/ settings"`
|
||||
Dirty *DirtyCmd `arg:"subcommand:dirty" help:"show repos git says are dirty"`
|
||||
Debug *DebugCmd `arg:"subcommand:debug" help:"debug forge"`
|
||||
Dirty *DirtyCmd `arg:"subcommand:dirty" help:"show dirty git repos"`
|
||||
GitFetch *FindCmd `arg:"subcommand:fetch" help:"run 'git fetch master'"`
|
||||
List *FindCmd `arg:"subcommand:list" help:"print a table of the current repos"`
|
||||
Merge *MergeCmd `arg:"subcommand:merge" help:"merge branches"`
|
||||
Patch *PatchCmd `arg:"subcommand:patch" help:"make patchsets"`
|
||||
GitPull *FindCmd `arg:"subcommand:pull" help:"run 'git pull'"`
|
||||
Pull *PullCmd `arg:"subcommand:pull" help:"run 'git pull'"`
|
||||
URL string `arg:"--connect" help:"forge url"`
|
||||
All bool `arg:"--all" help:"git commit --all"`
|
||||
Build string `arg:"--build" help:"build a repo"`
|
||||
|
@ -33,12 +35,15 @@ type args struct {
|
|||
Verbose bool `arg:"--verbose" help:"show more output"`
|
||||
Bash bool `arg:"--bash" help:"generate bash completion"`
|
||||
BashAuto []string `arg:"--auto-complete" help:"todo: move this to go-arg"`
|
||||
// Show string `arg:"--show" help:"show a repo"`
|
||||
}
|
||||
|
||||
type EmptyCmd struct {
|
||||
}
|
||||
|
||||
type CommitCmd struct {
|
||||
Submit bool `arg:"--submit" default:"true" help:"submit the patches to forge"`
|
||||
}
|
||||
|
||||
type testCmd string
|
||||
|
||||
type CleanCmd struct {
|
||||
|
@ -62,6 +67,13 @@ type PatchCmd struct {
|
|||
Submit string `arg:"--submit" help:"submit your commits"`
|
||||
}
|
||||
|
||||
type PullCmd struct {
|
||||
Test *EmptyCmd `arg:"subcommand:test" help:"list repos that need 'git pull'"`
|
||||
Dirty *EmptyCmd `arg:"subcommand:dirty" help:"only check dirty repos"`
|
||||
Patches *EmptyCmd `arg:"subcommand:patches" help:"only check repos with patches"`
|
||||
Sync *SyncCmd `arg:"subcommand:sync" help:"sync repos with upstream"`
|
||||
}
|
||||
|
||||
type ConfigAddCmd struct {
|
||||
Path string `arg:"--path" help:"absolute path of the git repo"`
|
||||
GoPath string `arg:"--gopath" help:"GO path of the git repo"`
|
||||
|
@ -85,12 +97,27 @@ type ConfigCmd struct {
|
|||
Register string `arg:"--register" help:"register your git URL (foo.com/mystuff) or (github.com/foo/bar)"`
|
||||
}
|
||||
|
||||
type DebugCmd struct {
|
||||
Config *EmptyCmd `arg:"subcommand:config" help:"used to debug protobuf Marshal() if things go wrong"`
|
||||
}
|
||||
|
||||
type CheckoutCmd struct {
|
||||
User *FindCmd `arg:"subcommand:user" help:"git checkout user"`
|
||||
Devel *FindCmd `arg:"subcommand:devel" help:"git checkout devel"`
|
||||
Master *FindCmd `arg:"subcommand:master" help:"git checkout master"`
|
||||
}
|
||||
|
||||
type MergeCmd struct {
|
||||
Devel *FindCmd `arg:"subcommand:devel" help:"merge user to devel"`
|
||||
Master *FindCmd `arg:"subcommand:master" help:"merge devel to master"`
|
||||
Publish *EmptyCmd `arg:"subcommand:publish" help:"increment versions and publish master branch"`
|
||||
}
|
||||
|
||||
type SyncCmd struct {
|
||||
Clean *EmptyCmd `arg:"subcommand:clean" help:"sync everything to upstream master"`
|
||||
User *EmptyCmd `arg:"subcommand:user" help:"sync everything to user"`
|
||||
}
|
||||
|
||||
type DirtyCmd struct {
|
||||
}
|
||||
|
||||
|
@ -101,6 +128,7 @@ type FindCmd struct {
|
|||
Private bool `arg:"--private" help:"your private repos from your .config/forge/"`
|
||||
Dirty bool `arg:"--dirty" help:"only use dirty git repos"`
|
||||
User bool `arg:"--user" help:"show repos on the user branch"`
|
||||
Full bool `arg:"--full" help:"show full repo names"`
|
||||
// ReadOnly bool `arg:"--readonly" help:"include read-only repos"`
|
||||
}
|
||||
|
||||
|
|
|
@ -34,23 +34,31 @@ func (args) doBashAuto() {
|
|||
case "commit":
|
||||
fmt.Println("--all")
|
||||
case "config":
|
||||
fmt.Println("add fix list")
|
||||
fmt.Println("add fix list debug")
|
||||
case "delete":
|
||||
deleteMatch()
|
||||
case "debug":
|
||||
fmt.Println("config")
|
||||
case "dirty":
|
||||
fmt.Println("")
|
||||
case "examine":
|
||||
fmt.Println("fix")
|
||||
case "list":
|
||||
fmt.Println("--all --mine --favorites --private")
|
||||
fmt.Println("--full")
|
||||
case "merge":
|
||||
fmt.Println("devel master")
|
||||
case "pull":
|
||||
fmt.Println("--force")
|
||||
fmt.Println("dirty clean list patches sync --force")
|
||||
case "--find":
|
||||
fmt.Println("foo bar")
|
||||
case "patch":
|
||||
fmt.Println("get list --submit show")
|
||||
case "user":
|
||||
fmt.Println("--force")
|
||||
case "devel":
|
||||
fmt.Println("--force")
|
||||
case "sync":
|
||||
fmt.Println("clean user --force")
|
||||
case "master":
|
||||
fmt.Println("")
|
||||
case "verify":
|
||||
|
@ -58,7 +66,7 @@ func (args) doBashAuto() {
|
|||
default:
|
||||
if argv.BashAuto[0] == ARGNAME {
|
||||
// list the subcommands here
|
||||
fmt.Println("--bash list checkout clean commit config dirty fetch patch pull")
|
||||
fmt.Println("--bash list checkout commit config dirty debug fetch merge patch pull")
|
||||
}
|
||||
}
|
||||
os.Exit(0)
|
||||
|
|
3
build
3
build
|
@ -3,3 +3,6 @@
|
|||
# include forgeConfig
|
||||
mkdir -p files/usr/bin/
|
||||
cp ../utils/wit-utils/forgeConfig/forgeConfig files/usr/bin/
|
||||
|
||||
mkdir -p files/usr/share/bash-completion/completions/
|
||||
forge --bash > files/usr/share/bash-completion/completions/forge
|
||||
|
|
113
doCheckout.go
113
doCheckout.go
|
@ -5,11 +5,11 @@ package main
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"go.wit.com/lib/gui/shell"
|
||||
"go.wit.com/lib/protobuf/forgepb"
|
||||
"go.wit.com/lib/protobuf/gitpb"
|
||||
"go.wit.com/log"
|
||||
)
|
||||
|
@ -80,7 +80,7 @@ func IsEverythingOnUser() (int, int, int, error) {
|
|||
}
|
||||
|
||||
func doGitReset() {
|
||||
all := me.found.SortByFullPath()
|
||||
all := me.forge.Repos.SortByFullPath()
|
||||
for all.Scan() {
|
||||
repo := all.Next()
|
||||
if me.forge.Config.IsReadOnly(repo.GetGoPath()) {
|
||||
|
@ -119,6 +119,14 @@ func rillCheckoutUser(repo *gitpb.Repo) error {
|
|||
// trys to figure out if there is still something to update
|
||||
func doAllCheckoutUser() error {
|
||||
now := time.Now()
|
||||
|
||||
if argv.Force {
|
||||
log.Info("going to force create user branches")
|
||||
if err := makeUserBranches(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
me.forge.RillFuncError(rillCheckoutUser)
|
||||
count := me.forge.RillReload()
|
||||
if count != 0 {
|
||||
|
@ -129,16 +137,16 @@ func doAllCheckoutUser() error {
|
|||
log.Printf("User branch check. %d total repos. (%d ok) (%d not on user branch) (%s)\n", total, count, nope, shell.FormatDuration(time.Since(now)))
|
||||
if err != nil {
|
||||
// display all repos not on user
|
||||
me.found = new(gitpb.Repos)
|
||||
found := new(gitpb.Repos)
|
||||
all := me.forge.Repos.SortByFullPath()
|
||||
for all.Scan() {
|
||||
repo := all.Next()
|
||||
if repo.GetCurrentBranchName() != repo.GetUserBranchName() {
|
||||
me.found.AppendByGoPath(repo)
|
||||
found.AppendByGoPath(repo)
|
||||
}
|
||||
}
|
||||
me.forge.PrintHumanTable(me.found)
|
||||
log.Printf("There are %d repos that are NOT on the user branch\n", me.found.Len())
|
||||
me.forge.PrintHumanTable(found)
|
||||
log.Printf("There are %d repos that are NOT on the user branch\n", found.Len())
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
|
@ -160,6 +168,10 @@ func rillCheckoutDevel(repo *gitpb.Repo) error {
|
|||
// is every repo on the devel branch?
|
||||
func doAllCheckoutDevel() error {
|
||||
now := time.Now()
|
||||
if argv.Force {
|
||||
log.Info("going to force create devel branches")
|
||||
makeDevelBranches()
|
||||
}
|
||||
log.Info("going to rill:")
|
||||
me.forge.RillFuncError(rillCheckoutDevel)
|
||||
count := me.forge.RillReload()
|
||||
|
@ -171,16 +183,16 @@ func doAllCheckoutDevel() error {
|
|||
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)))
|
||||
if err != nil {
|
||||
// display all repos not on user
|
||||
me.found = new(gitpb.Repos)
|
||||
found := new(gitpb.Repos)
|
||||
all := me.forge.Repos.SortByFullPath()
|
||||
for all.Scan() {
|
||||
repo := all.Next()
|
||||
if repo.GetCurrentBranchName() != repo.GetDevelBranchName() {
|
||||
me.found.AppendByGoPath(repo)
|
||||
found.AppendByGoPath(repo)
|
||||
}
|
||||
}
|
||||
me.forge.PrintHumanTable(me.found)
|
||||
log.Printf("There are %d repos that are NOT on the devel branch\n", me.found.Len())
|
||||
me.forge.PrintHumanTable(found)
|
||||
log.Printf("There are %d repos that are NOT on the devel branch\n", found.Len())
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
|
@ -191,12 +203,19 @@ func rillCheckoutMaster(repo *gitpb.Repo) error {
|
|||
// never do dirty repos
|
||||
return nil
|
||||
}
|
||||
if repo.GetCurrentBranchName() == repo.GetMasterBranchName() {
|
||||
// repo is already on master
|
||||
// 'giterr' means something is very wrong with this repo
|
||||
if repo.GetMasterVersion() == "giterr" {
|
||||
repo.CheckoutMaster()
|
||||
log.Info("master == giterr. BAD REPO", repo.GetFullPath())
|
||||
log.Info("master == giterr. BAD REPO", repo.GetFullPath())
|
||||
log.Info("master == giterr. BAD REPO", repo.GetFullPath())
|
||||
cmd := []string{"git", "checkout", "main"} // todo: figure out main
|
||||
repo.RunVerbose(cmd)
|
||||
os.Exit(-1)
|
||||
return nil
|
||||
}
|
||||
if repo.GetUserVersion() == "uerr" {
|
||||
repo.CheckoutMaster()
|
||||
if repo.GetCurrentBranchName() == repo.GetMasterBranchName() {
|
||||
// repo is already on master
|
||||
return nil
|
||||
}
|
||||
if me.forge.Config.IsReadOnly(repo.GetGoPath()) {
|
||||
|
@ -231,81 +250,43 @@ func doAllCheckoutMaster() error {
|
|||
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)))
|
||||
if err != nil {
|
||||
// display all repos not on master
|
||||
me.found = new(gitpb.Repos)
|
||||
found := new(gitpb.Repos)
|
||||
all := me.forge.Repos.SortByFullPath()
|
||||
for all.Scan() {
|
||||
repo := all.Next()
|
||||
if repo.GetCurrentBranchName() != repo.GetMasterBranchName() {
|
||||
me.found.AppendByGoPath(repo)
|
||||
found.AppendByGoPath(repo)
|
||||
}
|
||||
}
|
||||
me.forge.PrintHumanTable(me.found)
|
||||
log.Printf("There are %d repos that are NOT on the master branch\n", me.found.Len())
|
||||
me.forge.PrintHumanTable(found)
|
||||
log.Printf("There are %d repos that are NOT on the master branch\n", found.Len())
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// shared this with the GUI and the command line?
|
||||
func doCheckoutShared() error {
|
||||
if me.argvCheckoutUser {
|
||||
// log.Info("Starting git checkout user")
|
||||
if argv.Force {
|
||||
log.Info("going to force create user branches")
|
||||
if err := makeUserBranches(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
// this uses rill and is super fast
|
||||
doAllCheckoutUser()
|
||||
return nil
|
||||
}
|
||||
|
||||
if me.argvCheckoutDevel {
|
||||
// log.Info("Starting git checkout devel")
|
||||
if argv.Force {
|
||||
log.Info("going to force create devel branches")
|
||||
makeDevelBranches()
|
||||
}
|
||||
// this uses rill and is super fast
|
||||
doAllCheckoutDevel()
|
||||
return nil
|
||||
}
|
||||
|
||||
if me.argvCheckoutMaster {
|
||||
log.Info("Starting git checkout master")
|
||||
doAllCheckoutMaster()
|
||||
return nil
|
||||
}
|
||||
log.Info("Forge didn't know what branches to checkout")
|
||||
return nil
|
||||
}
|
||||
|
||||
// trys to figure out if there is still something to update
|
||||
// todo: redo this logic as it is terrible
|
||||
|
||||
func doCheckout() error {
|
||||
if argv.Checkout.User != nil {
|
||||
me.argvCheckoutUser = true
|
||||
me.forge.Config.Mode = forgepb.ForgeMode_USER
|
||||
me.forge.Config.ConfigSave()
|
||||
if err := doAllCheckoutUser(); err != nil {
|
||||
badExit(err)
|
||||
}
|
||||
}
|
||||
|
||||
if argv.Checkout.Devel != nil {
|
||||
me.argvCheckoutDevel = true
|
||||
me.forge.Config.Mode = forgepb.ForgeMode_DEVEL
|
||||
me.forge.Config.ConfigSave()
|
||||
if err := doAllCheckoutDevel(); err != nil {
|
||||
badExit(err)
|
||||
}
|
||||
}
|
||||
|
||||
if argv.Checkout.Master != nil {
|
||||
me.argvCheckoutMaster = true
|
||||
me.forge.Config.Mode = forgepb.ForgeMode_MASTER
|
||||
me.forge.Config.ConfigSave()
|
||||
if err := doAllCheckoutMaster(); err != nil {
|
||||
badExit(err)
|
||||
}
|
||||
}
|
||||
if err := doCheckoutShared(); err != nil {
|
||||
badExit(err)
|
||||
}
|
||||
okExit("")
|
||||
badExit(fmt.Errorf("did not specify what branch to checkout"))
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
13
doCommit.go
13
doCommit.go
|
@ -24,6 +24,9 @@ func doCommit() {
|
|||
}
|
||||
newpatches = true
|
||||
}
|
||||
if !argv.Commit.Submit {
|
||||
okExit("")
|
||||
}
|
||||
if newpatches {
|
||||
// if there are enw patches, autocommit them
|
||||
_, err := me.forge.SubmitDevelPatchSet("forge auto commit")
|
||||
|
@ -42,8 +45,9 @@ func doCommit() {
|
|||
}
|
||||
|
||||
if repo.GetCurrentBranchName() != repo.GetUserBranchName() {
|
||||
me.found.Append(repo)
|
||||
me.forge.PrintHumanTable(me.found)
|
||||
found := new(gitpb.Repos)
|
||||
found.Append(repo)
|
||||
me.forge.PrintHumanTable(found)
|
||||
log.Info("")
|
||||
log.Info("wrong branch. Can not commit on", repo.GetCurrentBranchName())
|
||||
log.Info("")
|
||||
|
@ -69,8 +73,9 @@ func doCommit() {
|
|||
|
||||
func doCommitRepo(repo *gitpb.Repo) error {
|
||||
if repo.GetCurrentBranchName() != repo.GetUserBranchName() {
|
||||
me.found.Append(repo)
|
||||
me.forge.PrintHumanTable(me.found)
|
||||
found := new(gitpb.Repos)
|
||||
found.Append(repo)
|
||||
me.forge.PrintHumanTable(found)
|
||||
log.Info("")
|
||||
log.Info("wrong branch. Can not commit on", repo.GetCurrentBranchName())
|
||||
log.Info("")
|
||||
|
|
|
@ -0,0 +1,168 @@
|
|||
// Copyright 2017-2025 WIT.COM Inc. All rights reserved.
|
||||
// Use of this source code is governed by the GPL 3.0
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"reflect"
|
||||
"unicode/utf8"
|
||||
|
||||
"go.wit.com/lib/protobuf/bugpb"
|
||||
"go.wit.com/lib/protobuf/forgepb"
|
||||
"golang.org/x/text/encoding/charmap"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
func doDebug() {
|
||||
me.forge = forgepb.InitPB()
|
||||
me.forge.ScanGoSrc()
|
||||
if err := me.forge.ConfigSave(); err != nil {
|
||||
if err := me.forge.Repos.ConfigSave(); err != nil {
|
||||
err := ValidateProtoUTF8(me.forge.Repos)
|
||||
if err != nil {
|
||||
log.Printf("Protobuf UTF-8 validation failed: %v\n", err)
|
||||
}
|
||||
if err := bugpb.SanitizeProtoUTF8(me.forge.Repos); err != nil {
|
||||
log.Fatalf("Sanitization failed: %v", err)
|
||||
}
|
||||
}
|
||||
// badExit(err)
|
||||
}
|
||||
me.forge.SetConfigSave(true)
|
||||
me.forge.Exit()
|
||||
okExit("this never runs")
|
||||
}
|
||||
|
||||
// ValidateProtoUTF8 checks all string fields in a proto.Message recursively.
|
||||
func ValidateProtoUTF8(msg proto.Message) error {
|
||||
return validateValue(reflect.ValueOf(msg), "")
|
||||
}
|
||||
|
||||
func validateValue(val reflect.Value, path string) error {
|
||||
if !val.IsValid() {
|
||||
return nil
|
||||
}
|
||||
|
||||
if val.Kind() == reflect.Ptr {
|
||||
if val.IsNil() {
|
||||
return nil
|
||||
}
|
||||
return validateValue(val.Elem(), path)
|
||||
}
|
||||
|
||||
switch val.Kind() {
|
||||
case reflect.Struct:
|
||||
for i := 0; i < val.NumField(); i++ {
|
||||
field := val.Field(i)
|
||||
fieldType := val.Type().Field(i)
|
||||
fieldPath := fmt.Sprintf("%s.%s", path, fieldType.Name)
|
||||
if err := validateValue(field, fieldPath); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
case reflect.String:
|
||||
s := val.String()
|
||||
if !utf8.ValidString(s) {
|
||||
return fmt.Errorf("invalid UTF-8 string at %s: %q", path, s)
|
||||
}
|
||||
|
||||
case reflect.Slice:
|
||||
if val.Type().Elem().Kind() == reflect.Uint8 {
|
||||
return nil // skip []byte
|
||||
}
|
||||
for i := 0; i < val.Len(); i++ {
|
||||
if err := validateValue(val.Index(i), fmt.Sprintf("%s[%d]", path, i)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
case reflect.Map:
|
||||
for _, key := range val.MapKeys() {
|
||||
valItem := val.MapIndex(key)
|
||||
if err := validateValue(valItem, fmt.Sprintf("%s[%v]", path, key)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// SanitizeProtoUTF8 fixes all invalid UTF-8 strings in a proto.Message recursively.
|
||||
func SanitizeProtoUTF8(msg proto.Message) error {
|
||||
return sanitizeValue(reflect.ValueOf(msg), "")
|
||||
}
|
||||
|
||||
func sanitizeValue(val reflect.Value, path string) error {
|
||||
if !val.IsValid() {
|
||||
return nil
|
||||
}
|
||||
|
||||
if val.Kind() == reflect.Ptr {
|
||||
if val.IsNil() {
|
||||
return nil
|
||||
}
|
||||
return sanitizeValue(val.Elem(), path)
|
||||
}
|
||||
|
||||
switch val.Kind() {
|
||||
case reflect.Struct:
|
||||
for i := 0; i < val.NumField(); i++ {
|
||||
field := val.Field(i)
|
||||
fieldType := val.Type().Field(i)
|
||||
if !field.CanSet() {
|
||||
continue
|
||||
}
|
||||
if err := sanitizeValue(field, fmt.Sprintf("%s.%s", path, fieldType.Name)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
case reflect.String:
|
||||
s := val.String()
|
||||
if !utf8.ValidString(s) {
|
||||
utf8Str, err := latin1ToUTF8(s)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to convert %s to UTF-8: %v", path, err)
|
||||
}
|
||||
val.SetString(utf8Str)
|
||||
}
|
||||
|
||||
case reflect.Slice:
|
||||
if val.Type().Elem().Kind() == reflect.Uint8 {
|
||||
return nil // skip []byte
|
||||
}
|
||||
for i := 0; i < val.Len(); i++ {
|
||||
if err := sanitizeValue(val.Index(i), fmt.Sprintf("%s[%d]", path, i)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
case reflect.Map:
|
||||
for _, key := range val.MapKeys() {
|
||||
valItem := val.MapIndex(key)
|
||||
newItem := reflect.New(valItem.Type()).Elem()
|
||||
newItem.Set(valItem)
|
||||
if err := sanitizeValue(newItem, fmt.Sprintf("%s[%v]", path, key)); err != nil {
|
||||
return err
|
||||
}
|
||||
val.SetMapIndex(key, newItem)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func latin1ToUTF8(input string) (string, error) {
|
||||
reader := charmap.ISO8859_1.NewDecoder().Reader(bytes.NewReader([]byte(input)))
|
||||
result, err := io.ReadAll(reader)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(result), nil
|
||||
}
|
|
@ -12,7 +12,6 @@ import (
|
|||
)
|
||||
|
||||
func doDirty() {
|
||||
findAll() // select all the repos
|
||||
doCheckDirtyAndConfigSave()
|
||||
found := findDirty()
|
||||
if argv.Verbose {
|
||||
|
@ -26,7 +25,7 @@ func straightCheckDirty() int {
|
|||
var count int
|
||||
// var total int
|
||||
// now := time.Now()
|
||||
for repo := range me.found.IterAll() {
|
||||
for repo := range me.forge.Repos.IterAll() {
|
||||
// total += 1
|
||||
if repo.IsDirty() {
|
||||
count += 1
|
||||
|
@ -52,7 +51,7 @@ func doCheckDirtyAndConfigSave() {
|
|||
now := time.Now()
|
||||
me.forge.RillFuncError(doCheckDirty)
|
||||
end := straightCheckDirty()
|
||||
log.Printf("dirty check (%d dirty repos) (%d total repos) took:%s\n", end, me.found.Len(), shell.FormatDuration(time.Since(now)))
|
||||
log.Printf("dirty check (%d dirty repos) (%d total repos) took:%s\n", end, me.forge.Repos.Len(), shell.FormatDuration(time.Since(now)))
|
||||
|
||||
if start != end {
|
||||
// todo: use internal forgepb configsave flag. should work?
|
||||
|
|
|
@ -8,36 +8,47 @@ import (
|
|||
)
|
||||
|
||||
// this populates a slice of protobuf records representing each git repo
|
||||
// var me.found []*gitpb.Repo
|
||||
// var found []*gitpb.Repo
|
||||
//
|
||||
// so, it makes a subset of repos that are then used performing actions on
|
||||
//
|
||||
// by default, it adds every repo
|
||||
|
||||
func doFind() *gitpb.Repos {
|
||||
if argv.List == nil {
|
||||
return findAll()
|
||||
}
|
||||
|
||||
if argv.List.Mine {
|
||||
return findMine()
|
||||
}
|
||||
|
||||
if argv.List.Dirty {
|
||||
return findDirty()
|
||||
}
|
||||
|
||||
return findAll()
|
||||
}
|
||||
|
||||
func (f *FindCmd) findRepos() *gitpb.Repos {
|
||||
if f == nil {
|
||||
findMine()
|
||||
return me.found
|
||||
return findMine()
|
||||
}
|
||||
|
||||
if f.All {
|
||||
findAll()
|
||||
return me.found
|
||||
return findAll()
|
||||
}
|
||||
|
||||
if f.Private {
|
||||
findPrivate()
|
||||
return me.found
|
||||
return findPrivate()
|
||||
}
|
||||
|
||||
if f.Mine {
|
||||
findMine()
|
||||
return me.found
|
||||
return findMine()
|
||||
}
|
||||
|
||||
if f.Favorites {
|
||||
findFavorites()
|
||||
return me.found
|
||||
return findFavorites()
|
||||
}
|
||||
|
||||
if f.Dirty {
|
||||
|
@ -45,47 +56,55 @@ func (f *FindCmd) findRepos() *gitpb.Repos {
|
|||
}
|
||||
|
||||
if f.User {
|
||||
findUser()
|
||||
return me.found
|
||||
return findUser()
|
||||
}
|
||||
|
||||
findAll()
|
||||
return me.found
|
||||
return findAll()
|
||||
}
|
||||
|
||||
func findPrivate() {
|
||||
func findPrivate() *gitpb.Repos {
|
||||
found := gitpb.NewRepos()
|
||||
for repo := range me.forge.Repos.IterByFullPath() {
|
||||
if me.forge.Config.IsPrivate(repo.GetGoPath()) {
|
||||
me.found.AppendByGoPath(repo)
|
||||
found.AppendByGoPath(repo)
|
||||
}
|
||||
}
|
||||
|
||||
return found
|
||||
}
|
||||
|
||||
// finds repos that are writable
|
||||
func findMine() {
|
||||
func findMine() *gitpb.Repos {
|
||||
found := gitpb.NewRepos()
|
||||
|
||||
// log.Printf("get mine %s\n", me.forge.GetGoSrc())
|
||||
for repo := range me.forge.Repos.IterByFullPath() {
|
||||
|
||||
if me.forge.Config.IsWritable(repo.GetGoPath()) {
|
||||
me.found.AppendByGoPath(repo)
|
||||
found.AppendByGoPath(repo)
|
||||
}
|
||||
}
|
||||
return found
|
||||
}
|
||||
|
||||
// finds repos the user has marked as favorites in the forge .config
|
||||
func findFavorites() {
|
||||
func findFavorites() *gitpb.Repos {
|
||||
found := gitpb.NewRepos()
|
||||
|
||||
// log.Printf("get favorites %s\n", me.forge.GetGoSrc())
|
||||
for repo := range me.forge.Repos.IterByFullPath() {
|
||||
|
||||
if me.forge.Config.IsFavorite(repo.GetGoPath()) {
|
||||
me.found.AppendByGoPath(repo)
|
||||
found.AppendByGoPath(repo)
|
||||
}
|
||||
}
|
||||
return found
|
||||
}
|
||||
|
||||
// finds repos that git is reporting as dirty
|
||||
func findDirty() *gitpb.Repos {
|
||||
found := gitpb.NewRepos()
|
||||
|
||||
for repo := range me.forge.Repos.IterByFullPath() {
|
||||
if repo.IsDirty() {
|
||||
found.AppendByGoPath(repo)
|
||||
|
@ -94,39 +113,62 @@ func findDirty() *gitpb.Repos {
|
|||
return found
|
||||
}
|
||||
|
||||
func findAll() {
|
||||
func findAll() *gitpb.Repos {
|
||||
found := gitpb.NewRepos()
|
||||
for repo := range me.forge.Repos.IterByFullPath() {
|
||||
me.found.AppendByGoPath(repo)
|
||||
found.AppendByGoPath(repo)
|
||||
}
|
||||
return found
|
||||
}
|
||||
|
||||
func findUser() {
|
||||
func find50() *gitpb.Repos {
|
||||
count := 0
|
||||
found := gitpb.NewRepos()
|
||||
for repo := range me.forge.Repos.IterByFullPath() {
|
||||
found.AppendByGoPath(repo)
|
||||
if count > 50 {
|
||||
return found
|
||||
}
|
||||
count += 1
|
||||
}
|
||||
return found
|
||||
}
|
||||
|
||||
func findUser() *gitpb.Repos {
|
||||
found := gitpb.NewRepos()
|
||||
|
||||
for repo := range me.forge.Repos.IterByFullPath() {
|
||||
if repo.GetCurrentBranchName() == repo.GetUserBranchName() {
|
||||
me.found.AppendByGoPath(repo)
|
||||
found.AppendByGoPath(repo)
|
||||
}
|
||||
}
|
||||
return found
|
||||
}
|
||||
|
||||
func findPublishable() {
|
||||
func findPublishable() *gitpb.Repos {
|
||||
found := gitpb.NewRepos()
|
||||
|
||||
for repo := range me.forge.Repos.IterByFullPath() {
|
||||
if repo.GetTargetVersion() == "" {
|
||||
continue
|
||||
}
|
||||
me.found.AppendByGoPath(repo)
|
||||
found.AppendByGoPath(repo)
|
||||
}
|
||||
return found
|
||||
}
|
||||
|
||||
func findReposWithPatches() {
|
||||
func findReposWithPatches() *gitpb.Repos {
|
||||
found := gitpb.NewRepos()
|
||||
|
||||
for repo := range me.forge.Repos.IterByFullPath() {
|
||||
if repo.GetTargetVersion() != "" {
|
||||
// add everything that has a target version set
|
||||
me.found.AppendByGoPath(repo)
|
||||
found.AppendByGoPath(repo)
|
||||
continue
|
||||
}
|
||||
if repo.IsDirty() {
|
||||
// always add dirty branches
|
||||
me.found.AppendByGoPath(repo)
|
||||
found.AppendByGoPath(repo)
|
||||
continue
|
||||
}
|
||||
if repo.GetUserVersion() == "" || repo.GetUserVersion() == "uerr" {
|
||||
|
@ -134,18 +176,27 @@ func findReposWithPatches() {
|
|||
continue
|
||||
}
|
||||
if repo.GetUserVersion() != repo.GetDevelVersion() {
|
||||
me.found.AppendByGoPath(repo)
|
||||
found.AppendByGoPath(repo)
|
||||
continue
|
||||
}
|
||||
|
||||
// ignore read-only repos for checks below here
|
||||
if me.forge.Config.IsReadOnly(repo.GetGoPath()) {
|
||||
continue
|
||||
}
|
||||
|
||||
// show anything that differs between 'devel' & 'master' branches
|
||||
if repo.GetDevelVersion() != repo.GetMasterVersion() {
|
||||
found.AppendByGoPath(repo)
|
||||
continue
|
||||
}
|
||||
|
||||
// this is an old test to see if the current 'last tag' is accurate and should be removed
|
||||
if me.forge.Config.IsReadOnly(repo.GetGoPath()) {
|
||||
continue
|
||||
}
|
||||
if repo.GetLastTag() != repo.GetMasterVersion() {
|
||||
me.found.AppendByGoPath(repo)
|
||||
found.AppendByGoPath(repo)
|
||||
repo.FindLastTag()
|
||||
continue
|
||||
}
|
||||
}
|
||||
return found
|
||||
}
|
172
doGui.go
172
doGui.go
|
@ -102,16 +102,9 @@ func doGui() {
|
|||
|
||||
func drawWindow(win *gadgets.GenericWindow) {
|
||||
grid := win.Group.RawGrid()
|
||||
me.goSrcPwd = gadgets.NewOneLiner(grid, "repo src home")
|
||||
me.goSrcPwd = gadgets.NewOneLiner(grid, "Working Directory")
|
||||
grid.NewLabel("")
|
||||
var howtoWin *gadgets.GenericWindow
|
||||
me.demoB = grid.NewButton("Howto", func() {
|
||||
if howtoWin != nil {
|
||||
howtoWin.Toggle()
|
||||
return
|
||||
}
|
||||
howtoWin = makeHowtoWin()
|
||||
})
|
||||
|
||||
grid.NextRow()
|
||||
|
||||
me.goSrcPwd.SetText(me.forge.GetGoSrc())
|
||||
|
@ -128,59 +121,12 @@ func drawWindow(win *gadgets.GenericWindow) {
|
|||
me.gitAuthor.SetText(author)
|
||||
}
|
||||
|
||||
group1 := win.Stack.NewGroup("Forge Mode")
|
||||
grid = group1.RawGrid()
|
||||
me.forgeMode = grid.NewLabel("")
|
||||
me.forgeMode.SetText(me.forge.GetMode())
|
||||
|
||||
me.newBranch = grid.NewDropdown()
|
||||
me.newBranch.AddText("master")
|
||||
me.newBranch.AddText("devel")
|
||||
me.newBranch.AddText(me.forge.Config.GetUsername())
|
||||
me.newBranch.Custom = func() {
|
||||
me.setBranchB.Disable()
|
||||
// toggle global values shared by the command line and the gui for doCheckout()
|
||||
switch me.newBranch.String() {
|
||||
case "master":
|
||||
if me.forge.Config.Mode != forgepb.ForgeMode_MASTER {
|
||||
me.setBranchB.Enable()
|
||||
}
|
||||
case "devel":
|
||||
if me.forge.Config.Mode != forgepb.ForgeMode_DEVEL {
|
||||
me.setBranchB.Enable()
|
||||
}
|
||||
default:
|
||||
if me.forge.Config.Mode != forgepb.ForgeMode_USER {
|
||||
me.setBranchB.Enable()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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
|
||||
me.setBranchB = grid.NewButton("Switch mode", func() {
|
||||
win.Disable()
|
||||
defer win.Enable()
|
||||
|
||||
switch me.newBranch.String() {
|
||||
case "master":
|
||||
forgeSwitchMode(forgepb.ForgeMode_MASTER)
|
||||
case "devel":
|
||||
forgeSwitchMode(forgepb.ForgeMode_DEVEL)
|
||||
default:
|
||||
forgeSwitchMode(forgepb.ForgeMode_USER)
|
||||
}
|
||||
|
||||
me.setBranchB.Disable()
|
||||
})
|
||||
me.setBranchB.Disable()
|
||||
|
||||
grid.NextRow()
|
||||
|
||||
groupM := win.Stack.NewGroup("Mode Windows")
|
||||
gridM := groupM.RawGrid()
|
||||
// groupM := hbox.NewGroup("Windows")
|
||||
// gridM := groupM.RawGrid()
|
||||
// hbox := win.Stack.Box().Horizontal()
|
||||
gridM := win.Stack.RawGrid()
|
||||
|
||||
var releaseWin *gadgets.GenericWindow
|
||||
gridM.NewButton("Release Window", func() {
|
||||
|
@ -202,18 +148,21 @@ func drawWindow(win *gadgets.GenericWindow) {
|
|||
patches = makePatchsetsWin()
|
||||
})
|
||||
|
||||
// the user mode "hack Window"
|
||||
var hackWin *gadgets.GenericWindow
|
||||
gridM.NewButton("Hack Window", func() {
|
||||
if hackWin != nil {
|
||||
hackWin.Toggle()
|
||||
var insertWin *gadgets.GenericWindow
|
||||
s := fmt.Sprintf("Repos (%d)", me.forge.Repos.Len())
|
||||
me.reposWinB = gridM.NewButton(s, func() {
|
||||
// if the window exists, just toggle it open or closed
|
||||
if insertWin != nil {
|
||||
insertWin.Toggle()
|
||||
return
|
||||
}
|
||||
hackWin = makeHackModeWindow()
|
||||
|
||||
insertWin = makeReposWinNew()
|
||||
})
|
||||
|
||||
var reposWin *gadgets.GenericWindow
|
||||
me.reposWinB = gridM.NewButton("Repos", func() {
|
||||
// var reposWin *gadgets.GenericWindow
|
||||
var reposWin *stdReposTableWin
|
||||
gridM.NewButton("Fix Repos", func() {
|
||||
if reposWin != nil {
|
||||
reposWin.Toggle()
|
||||
return
|
||||
|
@ -237,7 +186,7 @@ func drawWindow(win *gadgets.GenericWindow) {
|
|||
all := me.psets.All()
|
||||
for all.Scan() {
|
||||
pset := all.Next()
|
||||
AddNotDonePatches(notdone, pset)
|
||||
AddNotDonePatches(notdone, pset, false)
|
||||
}
|
||||
|
||||
for patch := range notdone.IterAll() {
|
||||
|
@ -248,64 +197,24 @@ func drawWindow(win *gadgets.GenericWindow) {
|
|||
patchesWin = makePatchesWin(notdone)
|
||||
})
|
||||
|
||||
// set the initial button state based on the last
|
||||
// forge mode the user saved in the config file
|
||||
switch me.forge.Config.Mode {
|
||||
case forgepb.ForgeMode_MASTER:
|
||||
me.newBranch.SetText("master")
|
||||
case forgepb.ForgeMode_DEVEL:
|
||||
me.newBranch.SetText("devel")
|
||||
case forgepb.ForgeMode_USER:
|
||||
me.newBranch.SetText(me.forge.Config.GetUsername())
|
||||
default:
|
||||
me.newBranch.SetText(me.forge.Config.GetUsername())
|
||||
}
|
||||
gridM.NextRow()
|
||||
var howtoWin *gadgets.GenericWindow
|
||||
gridM.NewButton("Tutorial", func() {
|
||||
if howtoWin != nil {
|
||||
howtoWin.Toggle()
|
||||
return
|
||||
}
|
||||
howtoWin = makeHowtoWin()
|
||||
})
|
||||
|
||||
forgeSwitchMode(me.forge.Config.Mode)
|
||||
}
|
||||
|
||||
// verify the GUI button disable/enable settings
|
||||
func forgeVerifyGuiState() {
|
||||
me.forgeMode.SetText(me.forge.GetMode())
|
||||
|
||||
me.argvCheckoutUser = false
|
||||
me.argvCheckoutDevel = false
|
||||
me.argvCheckoutMaster = false
|
||||
|
||||
switch me.forge.Config.Mode {
|
||||
case forgepb.ForgeMode_MASTER:
|
||||
me.argvCheckoutMaster = true
|
||||
me.newBranch.SetText("master")
|
||||
case forgepb.ForgeMode_DEVEL:
|
||||
me.argvCheckoutDevel = true
|
||||
me.newBranch.SetText("devel")
|
||||
case forgepb.ForgeMode_USER:
|
||||
me.newBranch.SetText(me.forge.Config.GetUsername())
|
||||
me.argvCheckoutUser = true
|
||||
default:
|
||||
me.newBranch.SetText(me.forge.Config.GetUsername())
|
||||
me.argvCheckoutUser = true
|
||||
}
|
||||
}
|
||||
|
||||
// sets the text in the labels in the window
|
||||
// and hides and shows the buttons
|
||||
func forgeSwitchMode(newMode forgepb.ForgeMode) {
|
||||
if newMode == me.forge.Config.Mode {
|
||||
log.Info("you are already on", newMode.String())
|
||||
forgeVerifyGuiState() // doing this here initializes the button state
|
||||
return
|
||||
}
|
||||
|
||||
me.forge.Config.Mode = newMode
|
||||
forgeVerifyGuiState() // update the button states
|
||||
|
||||
me.forge.Config.ConfigSave()
|
||||
gridM.NextRow()
|
||||
gridM.NewLabel("")
|
||||
}
|
||||
|
||||
// this is the magic that generates a window directly from the protocol buffer
|
||||
func makeStandardReposGrid(pb *gitpb.Repos) *gitpb.ReposTable {
|
||||
t := pb.NewTable("testDirty")
|
||||
t.NewUuid()
|
||||
sf := t.AddStringFunc("repo", func(r *gitpb.Repo) string {
|
||||
return r.GetGoPath()
|
||||
})
|
||||
|
@ -347,8 +256,7 @@ func findMergeToDevel() *gitpb.Repos {
|
|||
found := gitpb.NewRepos()
|
||||
|
||||
for repo := range me.forge.Repos.IterByFullPath() {
|
||||
|
||||
// this sees if user has patches for devel. If it does, add it to me.found
|
||||
// this sees if user has patches for devel. If it does, add it to found
|
||||
if repo.CountDiffObjects(repo.GetUserBranchName(), repo.GetDevelBranchName()) > 0 {
|
||||
found.AppendByGoPath(repo)
|
||||
}
|
||||
|
@ -365,8 +273,9 @@ func findMergeToDevel() *gitpb.Repos {
|
|||
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)))
|
||||
return found
|
||||
}
|
||||
func findMergeToMaster() {
|
||||
me.found = new(gitpb.Repos)
|
||||
|
||||
func findMergeToMaster() *gitpb.Repos {
|
||||
found := new(gitpb.Repos)
|
||||
|
||||
all := me.forge.Repos.SortByFullPath()
|
||||
for all.Scan() {
|
||||
|
@ -395,30 +304,31 @@ func findMergeToMaster() {
|
|||
|
||||
// this sees if devel has patches for master. If it does, add it to me.found
|
||||
if repo.CountDiffObjects(repo.GetDevelBranchName(), repo.GetMasterBranchName()) > 0 {
|
||||
me.found.AppendByGoPath(repo)
|
||||
found.AppendByGoPath(repo)
|
||||
}
|
||||
}
|
||||
now := time.Now()
|
||||
if me.found.Len() == 0 {
|
||||
if found.Len() == 0 {
|
||||
log.Info("nothing to merge with master")
|
||||
return
|
||||
return found
|
||||
}
|
||||
me.forge.PrintHumanTable(me.found)
|
||||
me.forge.PrintHumanTable(found)
|
||||
|
||||
// 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)))
|
||||
|
||||
return found
|
||||
}
|
||||
|
||||
func mergeDevelToMaster(doit bool) {
|
||||
findMergeToMaster()
|
||||
found := findMergeToMaster()
|
||||
|
||||
if !doit {
|
||||
return
|
||||
}
|
||||
|
||||
all := me.found.SortByFullPath()
|
||||
all := found.SortByFullPath()
|
||||
for all.Scan() {
|
||||
repo := all.Next()
|
||||
log.Info("repo:", repo.GetGoPath())
|
||||
|
|
|
@ -31,12 +31,12 @@ func doPatch() error {
|
|||
|
||||
// if no option is given to patch, list out the
|
||||
// repos that have patches ready in them
|
||||
findReposWithPatches()
|
||||
if me.found.Len() == 0 {
|
||||
found := findReposWithPatches()
|
||||
if found.Len() == 0 {
|
||||
log.Info("you currently have no patches in your user branches")
|
||||
return nil
|
||||
}
|
||||
me.forge.PrintHumanTable(me.found)
|
||||
me.forge.PrintHumanTable(found)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
155
doPull.go
155
doPull.go
|
@ -4,6 +4,7 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"go.wit.com/lib/gui/shell"
|
||||
|
@ -42,16 +43,87 @@ func rillPull(repo *gitpb.Repo) error {
|
|||
|
||||
// is every repo on the devel branch?
|
||||
|
||||
func doGitPullNew() {
|
||||
now := time.Now()
|
||||
pullcount := me.forge.RillFuncError(rillPull)
|
||||
count := me.forge.RillReload()
|
||||
if count != 0 {
|
||||
me.forge.ConfigSave()
|
||||
func doGitPullNew() error {
|
||||
if argv.Pull == nil {
|
||||
return fmt.Errorf("not really 'fetch pull'")
|
||||
}
|
||||
|
||||
total, count, nope, _ := IsEverythingOnMaster()
|
||||
log.Printf("Master branch check. %d total repos. (%d git pulled) (%d not on master branch) (%s) git pull total=%d\n", total, count, nope, shell.FormatDuration(time.Since(now)), pullcount)
|
||||
if argv.Force {
|
||||
now := time.Now()
|
||||
pullcount := me.forge.RillFuncError(rillPull)
|
||||
count := me.forge.RillReload()
|
||||
if count != 0 {
|
||||
me.forge.ConfigSave()
|
||||
}
|
||||
|
||||
total, count, nope, _ := IsEverythingOnMaster()
|
||||
log.Printf("Master branch check. %d total repos. (%d git pulled) (%d not on master branch) (%s) git pull total=%d\n", total, count, nope, shell.FormatDuration(time.Since(now)), pullcount)
|
||||
return nil
|
||||
}
|
||||
|
||||
check := gitpb.NewRepos()
|
||||
|
||||
if argv.Pull.Dirty != nil {
|
||||
check = findDirty()
|
||||
}
|
||||
|
||||
if argv.Pull.Patches != nil {
|
||||
check = findReposWithPatches()
|
||||
}
|
||||
|
||||
if check.Len() == 0 {
|
||||
// check = doFind()
|
||||
check = findAll()
|
||||
// check = find50()
|
||||
// check = findMine()
|
||||
}
|
||||
|
||||
me.forge.PrintHumanTableFull(check)
|
||||
found, err := me.forge.LookupPB(check)
|
||||
if err != nil {
|
||||
log.Info("LookupPB() failed", err, "len(check)=", check.Len())
|
||||
return err
|
||||
}
|
||||
// me.forge.PrintHumanTableFull(found)
|
||||
|
||||
// check to see if the repos need to be updated
|
||||
update := gitpb.NewRepos()
|
||||
|
||||
if found.Len() == 0 {
|
||||
return nil
|
||||
}
|
||||
log.Info("found.Len() ==", found.Len())
|
||||
|
||||
for repo := range found.IterAll() {
|
||||
masterb := repo.GetMasterBranchName()
|
||||
if masterb == "" {
|
||||
log.Info(repo.GetNamespace(), "master branch blank")
|
||||
continue
|
||||
}
|
||||
a := repo.GetLocalHash(masterb)
|
||||
ns := repo.GetNamespace()
|
||||
repo2 := me.forge.Repos.FindByNamespace(ns)
|
||||
if repo2 == nil {
|
||||
log.Info("repo namespace does not exist", a, repo.Namespace)
|
||||
continue
|
||||
}
|
||||
b := repo2.GetLocalHash(repo2.GetMasterBranchName())
|
||||
if b == a {
|
||||
continue
|
||||
}
|
||||
log.Info(a, "!=", b, repo.Namespace)
|
||||
update.AppendByNamespace(repo2)
|
||||
}
|
||||
if update.Len() == 0 {
|
||||
// nothing to update
|
||||
return nil
|
||||
}
|
||||
if _, err := me.forge.UpdatePB(update); err != nil {
|
||||
log.Info("UpdatePB() failed", err, "len(check)=", update.Len())
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -100,3 +172,70 @@ func doGitFetch() {
|
|||
me.forge.ConfigSave()
|
||||
}
|
||||
}
|
||||
|
||||
func doMergeDevel() (*gitpb.Repos, error) {
|
||||
var err error
|
||||
done := gitpb.NewRepos()
|
||||
found := findMergeToDevel()
|
||||
for repo := range found.IterAll() {
|
||||
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())
|
||||
err = fmt.Errorf("checkout devel failed")
|
||||
break
|
||||
}
|
||||
if _, err := repo.MergeToDevel(); err != nil {
|
||||
log.Info("merge from user failed", repo.GetGoPath(), err)
|
||||
err = fmt.Errorf("merge from user failed")
|
||||
// log.Info(strings.Join(r.Stdout, "\n"))
|
||||
// log.Info(strings.Join(r.Stderr, "\n"))
|
||||
break
|
||||
}
|
||||
done.Append(repo)
|
||||
/*
|
||||
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
|
||||
}
|
||||
*/
|
||||
}
|
||||
return done, err
|
||||
}
|
||||
|
||||
func doMergeMaster() (*gitpb.Repos, error) {
|
||||
var err error
|
||||
done := gitpb.NewRepos()
|
||||
found := findMergeToMaster()
|
||||
for repo := range found.IterAll() {
|
||||
if repo.CheckDirty() {
|
||||
log.Info("repo is dirty", repo.GetGoPath())
|
||||
continue
|
||||
}
|
||||
|
||||
log.Info("Starting merge on", repo.GetGoPath())
|
||||
if repo.CheckoutMaster() {
|
||||
log.Info("checkout devel failed", repo.GetGoPath())
|
||||
err = fmt.Errorf("checkout devel failed")
|
||||
break
|
||||
}
|
||||
|
||||
if _, err := repo.MergeToMaster(); err != nil {
|
||||
log.Info("merge from user failed", repo.GetGoPath(), err)
|
||||
err = fmt.Errorf("merge from user failed")
|
||||
// log.Info(strings.Join(r.Stdout, "\n"))
|
||||
// log.Info(strings.Join(r.Stderr, "\n"))
|
||||
break
|
||||
}
|
||||
|
||||
done.Append(repo)
|
||||
}
|
||||
return done, err
|
||||
}
|
||||
|
|
|
@ -0,0 +1,115 @@
|
|||
// 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"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"go.wit.com/lib/gui/shell"
|
||||
"go.wit.com/lib/protobuf/gitpb"
|
||||
"go.wit.com/log"
|
||||
)
|
||||
|
||||
// trys to figure out if there is still something to update
|
||||
|
||||
func doSync() error {
|
||||
if argv.Pull.Sync.Clean != nil {
|
||||
return doSyncClean()
|
||||
}
|
||||
if argv.Pull.Sync.User != nil {
|
||||
return doSyncUser()
|
||||
}
|
||||
|
||||
return fmt.Errorf("nothing to do")
|
||||
}
|
||||
|
||||
func doSyncClean() error {
|
||||
if err := doAllCheckoutMaster(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, _, _, err := IsEverythingOnMaster(); err != nil {
|
||||
log.Info("Not all repos are on the master branch")
|
||||
return err
|
||||
}
|
||||
|
||||
// force everything
|
||||
argv.Force = true
|
||||
|
||||
if err := doCleanUser(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := doCleanDevel(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
pullcount := me.forge.RillFuncError(rillPull)
|
||||
count := me.forge.RillReload()
|
||||
if count != 0 {
|
||||
me.forge.ConfigSave()
|
||||
}
|
||||
|
||||
total, count, nope, _ := IsEverythingOnMaster()
|
||||
log.Printf("doSyncClean() ok. %d total repos. (%d git pulled) (%d not on master branch) (%s) git pull total=%d\n", total, count, nope, shell.FormatDuration(time.Since(now)), pullcount)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func doSyncUser() error {
|
||||
if count, err := me.forge.RillRepo(10, 20, syncDevelBranch); err != nil {
|
||||
log.Info("RillFunc() failed", err)
|
||||
return err
|
||||
} else {
|
||||
log.Info("Rill syncDevelBranch() ok count =", count)
|
||||
}
|
||||
|
||||
argv.Force = true
|
||||
if err := doAllCheckoutUser(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func syncDevelBranch(repo *gitpb.Repo) error {
|
||||
branch := repo.GetDevelBranchName()
|
||||
if repo.Exists(filepath.Join(".git/refs/heads", branch)) {
|
||||
return nil
|
||||
}
|
||||
if repo.Exists(filepath.Join(".git/refs/remotes/origin", branch)) {
|
||||
cmd := []string{"git", "checkout", branch}
|
||||
err := repo.RunVerbose(cmd)
|
||||
return err
|
||||
}
|
||||
cmd := []string{"git", "branch", branch}
|
||||
repo.RunVerbose(cmd)
|
||||
cmd = []string{"git", "checkout", branch}
|
||||
err := repo.RunVerbose(cmd)
|
||||
return err
|
||||
}
|
||||
|
||||
func syncDevelBranches() error {
|
||||
all := me.forge.Repos.SortByFullPath()
|
||||
for all.Scan() {
|
||||
repo := all.Next()
|
||||
branch := repo.GetDevelBranchName()
|
||||
if repo.Exists(filepath.Join(".git/refs/heads", branch)) {
|
||||
continue
|
||||
}
|
||||
if repo.Exists(filepath.Join(".git/refs/remotes/origin", branch)) {
|
||||
cmd := []string{"git", "checkout", branch}
|
||||
repo.RunVerbose(cmd)
|
||||
continue
|
||||
}
|
||||
cmd := []string{"git", "branch", branch}
|
||||
repo.RunVerbose(cmd)
|
||||
cmd = []string{"git", "checkout", branch}
|
||||
repo.RunVerbose(cmd)
|
||||
}
|
||||
return nil
|
||||
}
|
45
main.go
45
main.go
|
@ -7,6 +7,7 @@ package main
|
|||
|
||||
import (
|
||||
"embed"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
|
@ -64,9 +65,14 @@ func main() {
|
|||
}
|
||||
me.urlbase = strings.Trim(me.urlbase, "/") // track down why trailing '/' makes http POST not work
|
||||
|
||||
// internally debugging can be triggered here before Init()
|
||||
if argv.Debug != nil {
|
||||
doDebug()
|
||||
okExit("")
|
||||
}
|
||||
|
||||
// load the ~/.config/forge/ config
|
||||
me.forge = forgepb.Init()
|
||||
me.found = new(gitpb.Repos)
|
||||
|
||||
// first find the repos or gopaths to operate on
|
||||
if argv.Config != nil {
|
||||
|
@ -112,7 +118,6 @@ func main() {
|
|||
}
|
||||
|
||||
if argv.Clean.GitReset != nil {
|
||||
findAll() // select all the repos
|
||||
doGitReset()
|
||||
okExit("reset")
|
||||
}
|
||||
|
@ -134,7 +139,31 @@ func main() {
|
|||
okExit("")
|
||||
}
|
||||
|
||||
if argv.GitPull != nil {
|
||||
if argv.Merge != nil {
|
||||
if argv.Merge.Devel != nil {
|
||||
if _, err := doMergeDevel(); err != nil {
|
||||
badExit(err)
|
||||
}
|
||||
okExit("devel merge ok")
|
||||
}
|
||||
|
||||
if argv.Merge.Master != nil {
|
||||
if _, err := doMergeMaster(); err != nil {
|
||||
badExit(err)
|
||||
}
|
||||
okExit("master merge ok")
|
||||
}
|
||||
badExit(fmt.Errorf("merge what?"))
|
||||
}
|
||||
|
||||
if argv.Pull != nil {
|
||||
if argv.Pull.Sync != nil {
|
||||
if err := doSync(); err != nil {
|
||||
badExit(err)
|
||||
}
|
||||
okExit("")
|
||||
}
|
||||
|
||||
doGitPullNew()
|
||||
okExit("")
|
||||
}
|
||||
|
@ -142,7 +171,11 @@ func main() {
|
|||
if argv.List != nil {
|
||||
found := argv.List.findRepos()
|
||||
// print out the repos
|
||||
me.forge.PrintHumanTable(found)
|
||||
if argv.List.Full {
|
||||
me.forge.PrintHumanTableFull(found)
|
||||
} else {
|
||||
me.forge.PrintHumanTable(found)
|
||||
}
|
||||
okExit("")
|
||||
}
|
||||
|
||||
|
@ -163,7 +196,8 @@ func main() {
|
|||
// nothing else was specified to be done,
|
||||
// then just list the table to stdout
|
||||
if gui.NoGui() {
|
||||
me.forge.PrintHumanTable(me.found)
|
||||
found := doFind()
|
||||
me.forge.PrintHumanTable(found)
|
||||
okExit("")
|
||||
}
|
||||
|
||||
|
@ -171,7 +205,6 @@ func main() {
|
|||
// basically, if you run just 'forge' it should open the GUI
|
||||
|
||||
// if opening the GUI, always check git for dirty repos
|
||||
findAll() // select all the repos
|
||||
doCheckDirtyAndConfigSave()
|
||||
doGui()
|
||||
okExit("")
|
||||
|
|
43
structs.go
43
structs.go
|
@ -8,7 +8,6 @@ import (
|
|||
"go.wit.com/gui"
|
||||
"go.wit.com/lib/gadgets"
|
||||
"go.wit.com/lib/protobuf/forgepb"
|
||||
"go.wit.com/lib/protobuf/gitpb"
|
||||
)
|
||||
|
||||
var me *mainType
|
||||
|
@ -26,53 +25,21 @@ type mainType struct {
|
|||
pp *arg.Parser // for parsing the command line args. Yay to alexf lint!
|
||||
forge *forgepb.Forge // for holding the forge protobuf files
|
||||
myGui *gui.Node // the gui toolkit handle
|
||||
found *gitpb.Repos // stores the list of repos to process things on
|
||||
psets *forgepb.Patchsets // the locally stored on disk patchsets
|
||||
foundPaths []string // stores gopaths to act on (when doing go-clone)
|
||||
configSave bool // if the config file should be saved after finishing
|
||||
urlbase string // base URL
|
||||
|
||||
// our view of the repositories
|
||||
// patchWin *patchesWindow
|
||||
|
||||
mainWindow *gadgets.BasicWindow
|
||||
mainbox *gui.Node // the main box. enable/disable this
|
||||
autoDryRun *gui.Node // checkbox for --dry-run
|
||||
goSrcPwd *gadgets.OneLiner // what is being used as primary directory for your work
|
||||
gitAuthor *gadgets.OneLiner // ENV GIT_AUTHOR NAME and EMAIL
|
||||
|
||||
// the main box. enable/disable this
|
||||
mainbox *gui.Node
|
||||
|
||||
// the window from the /lib/gui/gowit package
|
||||
// lw *gadgets.BasicWindow
|
||||
|
||||
// #### Sorting options for the repolist
|
||||
// autoHidePerfect *gui.Node
|
||||
// autoHideReadOnly *gui.Node
|
||||
|
||||
// checkbox for --dry-run
|
||||
autoDryRun *gui.Node
|
||||
|
||||
// checkbox to enable intermittent scanning
|
||||
// if checked, it will check all your repos for changes
|
||||
autoScanReposCB *gui.Node
|
||||
|
||||
goSrcPwd *gadgets.OneLiner // what is being used as primary directory for your work
|
||||
gitAuthor *gadgets.OneLiner // ENV GIT_AUTHOR NAME and EMAIL
|
||||
forgeMode *gui.Node // is the user in 'master', 'devel' or 'user' branches
|
||||
|
||||
// these hold the branches that the user can switch all
|
||||
// the repositories to them
|
||||
newBranch *gui.Node // deprecate?
|
||||
setBranchB *gui.Node // deprecate?
|
||||
// these hold the branches that the user can switch all the repositories to them
|
||||
reposWinB *gui.Node // button that opens the repos window
|
||||
repoAllB *gui.Node // "all" repos button
|
||||
repoDirtyB *gui.Node // "dirty" repos button
|
||||
repoDevelMergeB *gui.Node // "merge to devel" repos button
|
||||
repoWritableB *gui.Node // "what repos are writable" repos button
|
||||
demoB *gui.Node // opens the demo
|
||||
// modeReleaseW *gui.Node // opens the release window
|
||||
// modePatchW *gui.Node // opens the patch window
|
||||
// modeUserW *gui.Node // opens the user/hack window
|
||||
|
||||
argvCheckoutUser bool // shared between the GUI and the command line tools
|
||||
argvCheckoutDevel bool // shared between the GUI and the command line tools
|
||||
argvCheckoutMaster bool // shared between the GUI and the command line tools
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ type foundWindow struct {
|
|||
dirtyOL *gadgets.OneLiner
|
||||
readonlyOL *gadgets.OneLiner
|
||||
rw *gadgets.OneLiner
|
||||
// checkB *gui.Node
|
||||
found *gitpb.Repos
|
||||
}
|
||||
|
||||
func (r *foundWindow) Hidden() bool {
|
||||
|
@ -67,9 +67,8 @@ func (r *foundWindow) initWindow() {
|
|||
})
|
||||
group1.NewButton("all", func() {
|
||||
log.Info("find all here")
|
||||
me.found = new(gitpb.Repos)
|
||||
findAll()
|
||||
me.forge.PrintHumanTable(me.found)
|
||||
found := findAll()
|
||||
me.forge.PrintHumanTable(found)
|
||||
})
|
||||
|
||||
r.grid = r.stack.RawGrid()
|
||||
|
@ -80,7 +79,7 @@ func (r *foundWindow) initWindow() {
|
|||
}
|
||||
|
||||
func (r *foundWindow) listRepos() {
|
||||
for repo := range me.found.IterAll() {
|
||||
for repo := range r.found.IterAll() {
|
||||
r.addRepo(repo)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,115 +0,0 @@
|
|||
// 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 (
|
||||
"go.wit.com/lib/debugger"
|
||||
"go.wit.com/lib/gadgets"
|
||||
"go.wit.com/log"
|
||||
)
|
||||
|
||||
func makeHackModeWindow() *gadgets.GenericWindow {
|
||||
win := gadgets.NewGenericWindow("git user branch / Hack Mode Window", "This is a work in progress")
|
||||
grid := win.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.Stack.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.Stack.NewGroup("work in progress")
|
||||
grid = group3.RawGrid()
|
||||
|
||||
grid.NewButton("forge ConfigSave()", func() {
|
||||
me.forge.ConfigSave()
|
||||
})
|
||||
|
||||
grid.NewButton("debugger()", func() {
|
||||
debugger.DebugWindow()
|
||||
})
|
||||
return win
|
||||
}
|
|
@ -41,14 +41,15 @@ func makeHowtoWin() *gadgets.GenericWindow {
|
|||
grid.NewLabel("") // a stupid way to add padding
|
||||
grid.NextRow()
|
||||
|
||||
howtoWin.Group.NewLabel("Working dir: " + me.forge.GetGoSrc())
|
||||
// howtoWin.Group.NewLabel("Working dir: " + me.forge.GetGoSrc())
|
||||
|
||||
grid = howtoWin.Group.RawGrid()
|
||||
grid.NewButton("Download", func() {
|
||||
grid.NewButton("Download into "+me.forge.GetGoSrc(), func() {
|
||||
howtoWin.Disable()
|
||||
defer howtoWin.Enable()
|
||||
downloadForge()
|
||||
})
|
||||
grid.NewButton("Build", func() {
|
||||
grid.NewButton("Build forge & GUI GO plugins", func() {
|
||||
howtoWin.Disable()
|
||||
defer howtoWin.Enable()
|
||||
buildForge()
|
||||
|
|
|
@ -57,7 +57,24 @@ func makePatchesWin(patches *forgepb.Patches) *stdPatchTableWin {
|
|||
grid.NewLabel(fmt.Sprintf("total repos"))
|
||||
grid.NextRow()
|
||||
|
||||
grid.NewButton("reload", func() {
|
||||
grid.NewButton("show all", func() {
|
||||
if me.psets == nil {
|
||||
log.Info("No Patchsets loaded")
|
||||
return
|
||||
}
|
||||
notdone := new(forgepb.Patches)
|
||||
|
||||
all := me.psets.All()
|
||||
for all.Scan() {
|
||||
pset := all.Next()
|
||||
AddNotDonePatches(notdone, pset, true)
|
||||
}
|
||||
|
||||
for patch := range notdone.IterAll() {
|
||||
comment := cleanSubject(patch.Comment)
|
||||
log.Info("new patch:", patch.NewHash, "commithash:", patch.CommitHash, patch.RepoNamespace, comment)
|
||||
}
|
||||
dwin.doPatchesTable(notdone)
|
||||
})
|
||||
grid.NewButton("Apply All", func() {
|
||||
var count int
|
||||
|
@ -135,6 +152,11 @@ func AddPatchesPB(tbox *gui.Node, pb *forgepb.Patches) *forgepb.PatchesTable {
|
|||
t.SetParent(tbox)
|
||||
|
||||
gitam := t.AddButtonFunc("apply", func(p *forgepb.Patch) string {
|
||||
rn := p.RepoNamespace
|
||||
if repo := me.forge.FindByGoPath(rn); repo == nil {
|
||||
// log.Info("Could not figure out repo path", rn)
|
||||
return ""
|
||||
}
|
||||
return "git am"
|
||||
})
|
||||
gitam.Custom = func(p *forgepb.Patch) {
|
||||
|
|
|
@ -145,7 +145,7 @@ func makePatchsetsWin() *stdPatchsetTableWin {
|
|||
all := me.psets.All()
|
||||
for all.Scan() {
|
||||
pset := all.Next()
|
||||
AddNotDonePatches(notdone, pset)
|
||||
AddNotDonePatches(notdone, pset, false)
|
||||
}
|
||||
|
||||
for patch := range notdone.IterAll() {
|
||||
|
@ -266,7 +266,7 @@ func setPatchsetState(p *forgepb.Patchset) {
|
|||
// 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)
|
||||
log.Info("could not find repo", patch.RepoNamespace)
|
||||
bad = true
|
||||
continue
|
||||
}
|
||||
|
@ -332,7 +332,7 @@ func setNewCommitHash(p *forgepb.Patchset) bool {
|
|||
|
||||
repo := me.forge.FindByGoPath(patch.RepoNamespace)
|
||||
if repo == nil {
|
||||
log.Info("couldn't find repo", patch.RepoNamespace)
|
||||
log.Info("could not find repo", patch.RepoNamespace)
|
||||
continue
|
||||
}
|
||||
|
||||
|
@ -356,7 +356,7 @@ func setNewCommitHash(p *forgepb.Patchset) bool {
|
|||
return done
|
||||
}
|
||||
|
||||
func AddNotDonePatches(notdone *forgepb.Patches, pset *forgepb.Patchset) {
|
||||
func AddNotDonePatches(notdone *forgepb.Patches, pset *forgepb.Patchset, full bool) {
|
||||
for patch := range pset.Patches.IterAll() {
|
||||
comment := cleanSubject(patch.Comment)
|
||||
|
||||
|
@ -367,8 +367,10 @@ func AddNotDonePatches(notdone *forgepb.Patches, pset *forgepb.Patchset) {
|
|||
|
||||
repo := me.forge.FindByGoPath(patch.RepoNamespace)
|
||||
if repo == nil {
|
||||
log.Info("couldn't find repo", patch.RepoNamespace)
|
||||
notdone.Append(patch)
|
||||
log.Info("could not find repo", patch.RepoNamespace)
|
||||
if full {
|
||||
notdone.AppendByCommitHash(patch) // double check to ensure the commit hash isn't added twice
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
|
|
|
@ -10,160 +10,22 @@ import (
|
|||
"os"
|
||||
"time"
|
||||
|
||||
"go.wit.com/lib/debugger"
|
||||
"go.wit.com/lib/gadgets"
|
||||
"go.wit.com/lib/protobuf/gitpb"
|
||||
"go.wit.com/log"
|
||||
)
|
||||
|
||||
func makeReposWin() *gadgets.GenericWindow {
|
||||
win := gadgets.NewGenericWindow("git repos", "All about git repos")
|
||||
func makeReposWin() *stdReposTableWin {
|
||||
rwin := new(stdReposTableWin)
|
||||
win := gadgets.NewGenericWindow("find errors and try to fix them", "types of errors of some sort or another")
|
||||
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()
|
||||
})
|
||||
})
|
||||
// win.Top.NewGroup("misc (works in progress)")
|
||||
|
||||
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.Stack.NewGroup("misc (works in progress)")
|
||||
|
||||
grid = win.Stack.RawGrid()
|
||||
// grid = win.Top.RawGrid()
|
||||
grid = win.Group.RawGrid()
|
||||
var found *gitpb.Repos
|
||||
var txt string
|
||||
|
||||
|
@ -199,7 +61,7 @@ func makeReposWin() *gadgets.GenericWindow {
|
|||
hbox.NewButton("test", func() {
|
||||
})
|
||||
|
||||
t := makeStandardReposGrid(found)
|
||||
t := makeDevelBehindMaster(found)
|
||||
t.SetParent(box)
|
||||
t.ShowTable()
|
||||
})
|
||||
|
@ -248,9 +110,8 @@ func makeReposWin() *gadgets.GenericWindow {
|
|||
t.ShowTable()
|
||||
})
|
||||
|
||||
grid.NewButton("unknown branches", func() {
|
||||
log.Info("unknown branches not done yet")
|
||||
})
|
||||
rwin.boxTB = win.Bottom.Box()
|
||||
|
||||
grid.NextRow()
|
||||
|
||||
found = develRemoteProblem()
|
||||
|
@ -268,7 +129,146 @@ func makeReposWin() *gadgets.GenericWindow {
|
|||
})
|
||||
grid.NextRow()
|
||||
|
||||
return win
|
||||
makeHackModeWindow(rwin)
|
||||
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(stdwin *stdReposTableWin) {
|
||||
group := stdwin.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() {
|
||||
stdwin.win.Disable()
|
||||
defer stdwin.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 := stdwin.win.Top.NewGroup("Merge")
|
||||
grid = group2.RawGrid()
|
||||
|
||||
grid.NewButton("merge to devel", func() {
|
||||
stdwin.win.Disable()
|
||||
defer stdwin.win.Enable()
|
||||
|
||||
mergeUserToDevel(true)
|
||||
})
|
||||
|
||||
grid.NewButton("merge to master", func() {
|
||||
stdwin.win.Disable()
|
||||
defer stdwin.win.Enable()
|
||||
|
||||
mergeDevelToMaster(true)
|
||||
})
|
||||
|
||||
grid.NewButton("merge all", func() {
|
||||
stdwin.win.Disable()
|
||||
defer stdwin.win.Enable()
|
||||
|
||||
if err := doAllCheckoutDevel(); err != nil {
|
||||
log.Info("checkout error:", err)
|
||||
} else {
|
||||
log.Info("checkout was ok")
|
||||
}
|
||||
|
||||
mergeUserToDevel(true)
|
||||
|
||||
if err := doAllCheckoutMaster(); err != nil {
|
||||
log.Info("checkout error:", err)
|
||||
} else {
|
||||
log.Info("checkout was ok")
|
||||
}
|
||||
|
||||
mergeDevelToMaster(true)
|
||||
})
|
||||
|
||||
grid.NewButton("show dirty repos on win.Bottom", func() {
|
||||
log.Info("try to show dirty repos on bottom")
|
||||
found := findDirty()
|
||||
stdwin.doReposTable(found)
|
||||
})
|
||||
|
||||
group3 := stdwin.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 {
|
||||
|
@ -389,38 +389,3 @@ func makeWritableWindow(pb *gitpb.Repos) (*gadgets.GenericWindow, *gitpb.ReposTa
|
|||
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
|
||||
}
|
|
@ -0,0 +1,185 @@
|
|||
// 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 (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"go.wit.com/gui"
|
||||
"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 makeWindowForPB() *gadgets.GenericWindow {
|
||||
win := gadgets.NewGenericWindow("Forge Repos Protobuf View", "Display Git Repositories")
|
||||
|
||||
return win
|
||||
}
|
||||
|
||||
func makeReposWinNew() *gadgets.GenericWindow {
|
||||
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("to publish", func() {
|
||||
if t != nil {
|
||||
t.Delete()
|
||||
t = nil
|
||||
}
|
||||
found := findReposWithPatches()
|
||||
me.forge.PrintHumanTable(found)
|
||||
|
||||
// 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("favorites", 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.IsFavorite(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("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("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())
|
||||
})
|
||||
|
||||
return insertWin
|
||||
}
|
||||
|
||||
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()
|
||||
// hmm := t.AddMasterVersion()
|
||||
// hmm.SetTitle("Master")
|
||||
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
|
||||
}
|
Loading…
Reference in New Issue