Compare commits

..

No commits in common. "master" and "v0.22.19" have entirely different histories.

18 changed files with 1003 additions and 955 deletions

View File

@ -1,10 +1,9 @@
VERSION = $(shell git describe --tags) VERSION = $(shell git describe --tags)
BUILDTIME = $(shell date +%Y.%m.%d) BUILDTIME = $(shell date +%Y.%m.%d)
all: install all: build
goimports: goimports:
reset
goimports -w *.go goimports -w *.go
# // to globally reset paths: # // to globally reset paths:
# // gofmt -w -r "go.wit.com/gui -> go.wit.com/gui/gui" . # // gofmt -w -r "go.wit.com/gui -> go.wit.com/gui/gui" .
@ -14,33 +13,34 @@ vet:
build: build:
echo "build it!" echo "build it!"
touch resources/blank.so
-rm resources/*.so -rm resources/*.so
-mkdir resources/ cp -a ~/go/src/go.wit.com/toolkits/*.so resources/
-cp -a ~/go/src/go.wit.com/toolkits/*/*.so resources/
touch resources/blank.so
GO111MODULE=off go build \ GO111MODULE=off go build \
-ldflags "-X main.VERSION=${VERSION} -X main.BUILDTIME=${BUILDTIME} -X gui.GUIVERSION=${VERSION}" -ldflags "-X main.VERSION=${VERSION} -X main.BUILDTIME=${BUILDTIME} -X gui.GUIVERSION=${VERSION}"
clean: install:
rm -f go.*
-rm resources/*.so -rm resources/*.so
touch resources/blank.so cp -a ~/go/src/go.wit.com/toolkits/*.so resources/
install: goimports
touch resources/blank.so
-rm resources/*.so
# -cp -a ~/go/src/go.wit.com/toolkits/*/*.so resources/
touch resources/blank.so
GO111MODULE=off go install \ GO111MODULE=off go install \
-ldflags "-X main.VERSION=${VERSION} -X main.BUILDTIME=${BUILDTIME} -X gui.GUIVERSION=${VERSION}" -ldflags "-X main.VERSION=${VERSION} -X main.BUILDTIME=${BUILDTIME} -X gui.GUIVERSION=${VERSION}"
test: build
GUIRELEASE_REASON='test build' ./guireleaser
check-git-clean: check-git-clean:
@git diff-index --quiet HEAD -- || (echo "Git repository is dirty, please commit your changes first"; exit 1) @git diff-index --quiet HEAD -- || (echo "Git repository is dirty, please commit your changes first"; exit 1)
redomod:
rm -f go.*
GO111MODULE= go mod init
GO111MODULE= go mod tidy
curl-help: curl-help:
curl --silent http://localhost:9419/help curl --silent http://localhost:9419/help
tempWin:
curl --silent http://localhost:9419/tempWin
curl-rescan-All: curl-rescan-All:
curl --silent http://localhost:9419/rescanAll curl --silent http://localhost:9419/rescanAll
@ -60,6 +60,7 @@ showNext:
doRelease: doRelease:
reset reset
make curl-list-changed
make showNext make showNext
sleep 10 sleep 10
curl --silent http://localhost:9419/doRelease curl --silent http://localhost:9419/doRelease
@ -67,17 +68,9 @@ doRelease:
curl-setCurrent-go-wit-com-gui: curl-setCurrent-go-wit-com-gui:
curl --silent http://localhost:9419/setCurrentRepo?repo=go.wit.com/gui curl --silent http://localhost:9419/setCurrentRepo?repo=go.wit.com/gui
curl-setCurrent-go-clone:
curl --silent http://localhost:9419/setCurrentRepo?repo=go.wit.com/apps/go-clone
make showNext
curl-setTargetVersion-virtigo-v0.1.1: curl-setTargetVersion-virtigo-v0.1.1:
curl --silent http://localhost:9419/setTargetVersion?version=v0.1.1 curl --silent http://localhost:9419/setTargetVersion?version=v0.1.1
# CAN NOT HAVE v0.6 -- MUST BE v0.6.0
curl-setTargetVersion-go-clone-v0.6.0:
curl --silent "http://localhost:9419/setTargetVersion?repo=go-clone&version=v0.6.0"
curl-incrementAllTargetVersions: curl-incrementAllTargetVersions:
curl --silent http://localhost:9419/setAllTargetVersions curl --silent http://localhost:9419/setAllTargetVersions
@ -85,41 +78,14 @@ curl-incrementAllTargetVersions:
list-release-notdone: list-release-notdone:
curl --silent http://localhost:9419/releaseList?readonly=true curl --silent http://localhost:9419/releaseList?readonly=true
safe-build: install # only show repos that need to be merged to the master branch
# forge list --private curl-list-changed:
wit-test install --verbose curl --silent http://localhost:9419/list?perfect=false
# cd ~/go/src/go.wit.com/lib/xgb/ && time GUIRELEASE_REASON="safe-build" guireleaser --gui gocui --gui-verbose --gui-file ../../toolkits/gocui/gocui.so >/tmp/forge.log 2>&1
rm -f go.* ; git checkout go.mod ; cd ~/go/src/go.wit.com/lib/xgb/ && time GUIRELEASE_REASON="safe-build" guireleaser --gui andlabs
build-quick: install # include repos that you probably can't git push commits
wit-test install --verbose curl-list-everything:
# rm -f go.* ; git checkout go.mod ;cd ~/go/src/go.wit.com/lib/xgb/ && time GUIRELEASE_REASON="safe-build" guireleaser --gui andlabs quick curl --silent http://localhost:9419/list?readonly=true
sudo "wit update"
autocomplete: curl-file-for-go.wit.com:
guireleaser --bash > ~/.local/share/bash-completion/completions/guireleaser curl --silent http://localhost:9419/goweblist?readonly=true
curl --silent http://localhost:9419/goweblist?readonly=true |sort > ~/go.wit.com.versions
test-build-force:
GUIRELEASE_REASON="safe-build" guireleaser --gui andlabs --force
# time GUIRELEASE_REASON="safe-build" make test-build
test-build:
wit-test install --verbose
rm ~/go/bin/forged
cd ~/go/src/go.wit.com/lib/xgb/ && rm -f go.*
cd ~/go/src/go.wit.com/lib/xgb/ && git checkout go.mod
cd ~/go/src/go.wit.com/lib/xgb/ && time guireleaser --gui andlabs
cd ~/go/src/go.wit.com/apps/guireleaser
wit-test debian --verbose
do-aptly
# time GUIRELEASE_REASON="safe-build" make test-build-quick
test-build-quick:
wit-test install --verbose
rm ~/go/bin/forged
cd ~/go/src/go.wit.com/lib/xgb/ && rm -f go.*
cd ~/go/src/go.wit.com/lib/xgb/ && git checkout go.mod
cd ~/go/src/go.wit.com/lib/xgb/ && time guireleaser --gui andlabs quick
cd ~/go/src/go.wit.com/apps/guireleaser
wit-test debian --verbose
do-aptly

8
TODO
View File

@ -1,8 +0,0 @@
notes on what to fix next
go-args make patches for alexflint
go-mod-clean --restore *.pb.go files
go-mod-clean set ctime on files
guireleaser change "title small" to the package being updated"

75
argv.go
View File

@ -1,41 +1,22 @@
package main package main
import (
"fmt"
"os"
"os/user"
)
/* /*
this parses the command line arguements this parses the command line arguements
this enables command line options from other packages like 'gui' and 'log' this enables command line options from other packages like 'gui' and 'log'
*/ */
type args struct { type argv struct {
Quick *QuickCmd `arg:"subcommand:quick" help:"only do repos with patches"` // Repo string `arg:"positional" help:"go import path"`
DryRun bool `arg:"--dry-run,env:DRYRUN" help:"don't actually do the release"` // Increment bool `arg:"--increment" help:"auto increment"`
Minor bool `arg:"--minor" help:"increment minor verion numbers"` // Release bool `arg:"--release" help:"do a release an exit"`
Protobuf bool `arg:"--protobuf" help:"increment protobuf repos"` DryRun bool `arg:"--dry-run,env:DRYRUN" help:"don't actually do the release"`
Verbose bool `arg:"--verbose" help:"talk alot"` Reason string `arg:"--reason" help:"tag message"`
Full bool `arg:"--full" help:"build every package"` DumpVersions bool `arg:"--dump-versions" help:"dump the versions file for go.wit.com"`
Reason string `arg:"--reason" help:"tag message"` Port int `arg:"--port" default:"9419" help:"do fun stuff with curl"`
Force bool `arg:"--force" help:"try harder than normal"`
Port int `arg:"--port" default:"9419" help:"do fun stuff with curl"`
Bash bool `arg:"--bash" help:"generate bash completion"`
BashAuto []string `arg:"--auto-complete" help:"does the actual autocompletion"`
} }
type QuickCmd struct { func (a argv) Description() string {
List *EmptyCmd `arg:"subcommand:list" help:"list available patches"`
Show *EmptyCmd `arg:"subcommand:show" help:"show a specific patch"`
NoLibs *EmptyCmd `arg:"subcommand:show" help:"skip libraries that aren't changed"`
}
type EmptyCmd struct {
}
func (a args) Description() string {
return ` return `
Example usage: Example usage:
guireleaser go.wit.com/apps/go-clone --increment --release --dry-run --reason "blerg" guireleaser go.wit.com/apps/go-clone --increment --release --dry-run --reason "blerg"
@ -44,42 +25,6 @@ This will pull down the go sources and
the repositories in the go.sum file using git clone` the repositories in the go.sum file using git clone`
} }
func (args) Version() string { func (argv) Version() string {
return "guireleaser " + VERSION return "guireleaser " + VERSION
} }
/*
handles shell autocomplete
*/
func (a args) DoAutoComplete(argv []string) {
switch argv[0] {
case "checkout":
usr, _ := user.Current()
fmt.Println("user devel master " + usr.Username)
case "commit":
fmt.Println("--all")
case "config":
fmt.Println("add fix list delete")
case "list":
fmt.Println("--all --mine --favorites --private")
case "pull":
fmt.Println("--all --mine --favorites --private")
case "patch":
fmt.Println("--list --submit --show")
case "dirty":
fmt.Println("--show-files")
case "user":
fmt.Println("--force")
case "devel":
fmt.Println("--force")
case "master":
fmt.Println("--force")
default:
if argv[0] == ARGNAME {
// list the subcommands here
fmt.Println("--bash quick")
}
}
os.Exit(0)
}

View File

@ -2,154 +2,71 @@
package main package main
import ( import (
"errors"
"fmt"
"os" "os"
"path/filepath"
"strings" "strings"
"time"
"github.com/go-cmd/cmd"
"go.wit.com/lib/gui/repolist"
"go.wit.com/lib/gui/shell" "go.wit.com/lib/gui/shell"
"go.wit.com/log" "go.wit.com/log"
) )
func doRelease() error { func doRelease() bool {
check := me.current log.Info("doRelease() on", me.current.Name())
log.Info("doRelease() on", me.current.GetGoPath())
if !findOk {
log.Info("doRelease() immediately end something went wrong last time. findOk == false")
return fmt.Errorf("findOK = false %s", check.GetGoPath())
}
// double check release version logic // double check release version logic
if me.release.releaseVersionB.String() != "release version "+me.release.version.String() { if me.release.releaseVersionB.String() != "release version "+me.release.version.String() {
log.Warn("something went wrong with the release.version:", me.release.version.String()) log.Warn("something went wrong with the release.version:", me.release.version.String())
return fmt.Errorf("GUI lied %s", check.GetGoPath()) return false
} }
if strings.HasPrefix(me.release.version.String(), "v") { if strings.HasPrefix(me.release.version.String(), "v") {
log.Warn("everything is ok. version starts with v.", me.release.version.String()) log.Warn("everything is ok. version starts with v.", me.release.version.String())
} else { } else {
log.Warn("version does not start with v.", me.release.version.String()) log.Warn("version does not start with v.", me.release.version.String())
return fmt.Errorf("release does not start with a v %s", check.GetGoPath()) return false
} }
if shell.Exists("go.mod") { if shell.Exists("go.mod") {
log.Info("go.mod exists ok") log.Info("go.mod exists ok")
} else { } else {
pwd, _ := os.Getwd() pwd, _ := os.Getwd()
log.Info("go.mod missing in working dir", pwd) log.Info("go.mod disappeared. need to run go mod init and go mod tidy here:", pwd)
return fmt.Errorf("go.mod missing %s", check.GetGoPath()) return false
} }
curName := me.current.GetCurrentBranchName() curName := me.current.Status.GetCurrentBranchName()
mName := me.current.GetMasterBranchName() mName := me.current.Status.GetMasterBranchName()
if curName != mName { if curName != mName {
log.Info("\trepo is not working from main branch", curName, "!=", mName) log.Info("\trepo is not working from main branch", curName, "!=", mName)
return fmt.Errorf("not on main branch %s", check.GetGoPath()) return false
} }
if alreadyDone(check) { if !checkValidGoSum(me.current) {
// means it was already published return false
// protects against logic errors that might result
// in an infinite loop
log.Info("doRelease() WARNING. should have never gotten here. return true. already done", check.GetGoPath())
log.Info("doRelease() WARNING. should have never gotten here. return true. already done", check.GetGoPath())
log.Info("doRelease() WARNING. should have never gotten here. return true. already done", check.GetGoPath())
check.ReloadCheck()
return fmt.Errorf("already released %s", check.GetGoPath())
}
// check if the git tag already exists somehow
testtag := me.release.version.String()
if check.LocalTagExists(testtag) {
log.Info("TAG ALREADY EXISTS", testtag)
return log.Errorf("%s TAG ALREADY EXISTS %s", check.FullPath, testtag)
} else {
log.Info("TAG IS NEW", testtag)
}
if me.forge.Config.IsPrivate(me.current.GetGoPath()) {
// do not self update private repos
log.Info("This is a private repo.")
var retag [][]string
retag = append(retag, []string{"git", "tag", "-m", me.releaseReasonS, me.release.version.String()})
retag = append(retag, []string{"git", "push", "origin", me.release.version.String()})
if !me.current.RunAll(retag) {
log.Info("retag failed")
findOk = false
return fmt.Errorf("RETAG FAILED %s", check.GetGoPath())
}
return skipToNext()
}
me.done = append(me.done, me.current.GetGoPath())
if err := me.forge.FinalGoDepsCheckOk(check, true); err != nil {
msg := fmt.Sprint("the go.mod file is wrong. fix it here?", check.GetGoPath())
badExit(errors.New(msg))
return fmt.Errorf("FinalGoDeps %s err %v", check.GetGoPath(), err)
}
if check.GetGoPath() == me.startRepo.GetGoPath() {
log.Info("CAN NOT SELF UPDATE.", check.GetGoPath(), "is the same as os.Getwd()")
log.Info("go get must be run from somewhere else other than startRepo")
log.Info("chdir to autotypist if it exists")
msg := fmt.Sprint("CAN NOT SELF UPDATE.", check.GetGoPath(), "is the same as os.Getwd()")
badExit(errors.New(msg))
}
if !me.startRepo.Exists("go.mod") {
log.Info("go.sum missing in", me.startRepo.GetGoPath())
log.Info("pick a different repo here")
log.Info("todo: error out earlier knowing this will upgrade")
log.Info("versions", me.startRepo.GetTargetVersion(), me.startRepo.GetMasterVersion())
panic("redo go.sum")
} }
log.Info("\ttag and push", curName, me.release.version.String(), me.releaseReasonS) log.Info("\ttag and push", curName, me.release.version.String(), me.releaseReasonS)
if err := check.ValidGoSum(); err != nil {
log.Info("ValidGoSum() error", check.GetGoPath(), err)
msg := fmt.Sprint("ValidGoSum() error", check.GetGoPath(), err)
badExit(errors.New(msg))
}
// this is the final check. even here, just to be a total asshole
// I rerun go mod init and go mod tidy
// the re-parse all the results
// this is the last and final check.
// believe it or not, I've seen this fail. It's not worth being careful here
// or liberal about it. if it doesn't work, yep, you are stuck here you bastard
// (bastard being me. I designed this to be so annoying that if it makes it
// past this point it always works. that is the whole point of this code. NEVER
// EVER FAIL PAST THIS POINT
// )
// so let's do it: let's run go-mod-clean strict
// then reparse everything
_, err := check.RunVerboseOnError([]string{"go-mod-clean", "strict"})
if err != nil {
badExit(err)
}
var all [][]string var all [][]string
var autogen []string
all = append(all, []string{"git", "add", "-f", "go.mod"}) all = append(all, []string{"git", "add", "-f", "go.mod"})
autogen = append(autogen, "go.mod") if me.current.Status.IsPrimitive() {
if check.GoInfo.GoPrimitive {
// don't add go.sum here. TODO: check for go.sum file and fail // don't add go.sum here. TODO: check for go.sum file and fail
} else { } else {
all = append(all, []string{"git", "add", "-f", "go.sum"}) all = append(all, []string{"git", "add", "-f", "go.sum"})
autogen = append(autogen, "go.sum")
} }
if ok, compiled, err := me.current.IsProtobuf(); ok { if ok, compiled, err := me.current.Status.IsProtobuf(); ok {
log.Info("\tIsProtobuf() == true") log.Info("\tIsProtobuf() == true")
if err != nil { if err != nil {
log.Info("\tERROR: There are protobuf files, but they are not compiled") log.Info("\tERROR: There are protobuf files, but they are not compiled")
log.Info("\tERROR: can not continue") log.Info("\tERROR: can not continue")
msg := fmt.Sprint("ERROR: There are protobuf files, but they are not compiled") os.Exit(-1)
badExit(errors.New(msg))
} }
log.Info("\tshould add the protobuf files here") log.Info("\tshould add the protobuf files here")
log.Info("\tcompiled files found:", compiled) log.Info("\tcompiled files found:", compiled)
for _, s := range compiled { for _, s := range compiled {
log.Info("\tcompiled file found:", s) log.Info("\tcompiled file found:", s)
all = append(all, []string{"git", "add", "-f", s}) all = append(all, []string{"git", "add", "-f", s})
autogen = append(autogen, s)
} }
} else { } else {
log.Info("\tIsProtobuf() == false") log.Info("\tIsProtobuf() == false")
@ -159,30 +76,16 @@ func doRelease() error {
all = append(all, []string{"git", "tag", "-m", me.releaseReasonS, me.release.version.String()}) all = append(all, []string{"git", "tag", "-m", me.releaseReasonS, me.release.version.String()})
all = append(all, []string{"git", "push", "origin", me.release.version.String()}) all = append(all, []string{"git", "push", "origin", me.release.version.String()})
// save the autogenerated files in git metadata (aka: notes) if !me.current.Status.DoAll(all) {
cname := check.GetCurrentBranchName()
if err := check.AutogenSave(autogen, cname, true); err != nil {
log.Info("AutogenSave() error", err)
msg := fmt.Sprint("AutogenSave() error", err)
badExit(errors.New(msg))
}
if !me.current.RunAll(all) {
log.Info("failed to make new release", me.release.version.String()) log.Info("failed to make new release", me.release.version.String())
findOk = false return false
return fmt.Errorf("setting findOK = false %s", check.GetGoPath())
} }
log.Info("RELEASE OK") log.Info("RELEASE OK")
// 'publish' the version to the golang package versioning system // 'publish' the version to the golang package versioning system
if !doPublishVersion() { if !doPublishVersion() {
time.Sleep(3 * time.Second) log.Info("PUBLISH FAILED")
// this can fail to update, try it again after sleep(3s) return false
if !doPublishVersion() {
log.Info("PUBLISH FAILED gopath=%s", check.GetGoPath())
findOk = false
return fmt.Errorf("PUBLISH FAILED gopath=%s", check.GetGoPath())
}
} }
log.Info("PUBLISH OK") log.Info("PUBLISH OK")
@ -190,10 +93,9 @@ func doRelease() error {
// unwind and re-tag. Now that the go.mod and go.sum are published, revert // unwind and re-tag. Now that the go.mod and go.sum are published, revert
// to the development branch // to the development branch
if !me.current.RevertMasterToDevel() { if !me.current.Status.RevertMasterToDevel() {
log.Info("Revert Failed") log.Info("Revert Failed")
findOk = false return false
return fmt.Errorf("REVERT FAILED %s", check.GetGoPath())
} }
// update tag // update tag
@ -203,42 +105,94 @@ func doRelease() error {
retag = append(retag, []string{"git", "tag", "-m", me.releaseReasonS, me.release.version.String()}) retag = append(retag, []string{"git", "tag", "-m", me.releaseReasonS, me.release.version.String()})
retag = append(retag, []string{"git", "push", "origin", me.release.version.String()}) retag = append(retag, []string{"git", "push", "origin", me.release.version.String()})
if !me.current.RunAll(retag) { if !me.current.Status.DoAll(retag) {
log.Info("retag failed") log.Info("retag failed")
findOk = false return false
return fmt.Errorf("RETAG FAILED %s", check.GetGoPath())
} }
log.Info("EVERYTHING OK. RERELEASED", me.current.GetGoPath()) log.Info("EVERYTHING OK. RERELEASED", me.current.Name())
return nil // update the values in the GUI
me.current.NewScan()
// attempt to find another repo to release
if !doReleaseFindNext() {
log.Info("doReleaseFindNext() could not find a new")
log.Info("THIS PROBABLY MEANS THAT ACTUALLY WE ARE TOTALLY DONE?")
os.Setenv("FindNextDone", "true")
return false
}
log.Info("GOOD TO RUN ANOTHER DAY ON:", me.current.Name())
return true
}
func checkValidGoSum(repo *repolist.RepoRow) bool {
ok, err := me.repos.View.CheckValidGoSum(repo)
if err != nil {
log.Info("go mod tidy not ok", err)
return false
}
if ok {
log.Info("repo has go.sum requirements that are clean")
// me.current.setGoSumStatus("CLEAN")
me.release.status.SetValue("GOOD")
me.release.notes.SetValue("CheckValidGoSum() does not seem to lie")
return true
}
me.release.notes.SetValue("CheckValidGoSum() failed")
return false
}
// try to figure out if there is another package to update
func doReleaseFindNext() bool {
// scan for new repo
if findNext() {
log.Info("findNext() found something")
} else {
log.Info("findNext() could not find anything")
return false
}
if checkValidGoSum(me.current) {
return true
}
return false
} }
// this pulls the new tag from the golang package repository // this pulls the new tag from the golang package repository
// to insert the new version // to insert the new version
func doPublishVersion() bool { func doPublishVersion() bool {
gopath := me.current.GetGoPath() gopath := me.current.GoPath()
docmd := []string{"go", "get", "-v", gopath + "@" + me.release.version.String()} docmd := []string{"go", "get", "-v", gopath + "@" + me.release.version.String()}
log.Info("SHOULD RUN cmd HERE:", docmd) log.Info("SHOULD RUN cmd HERE:", docmd)
if me.forge.Config.IsPrivate(me.current.GetGoPath()) { // right now, you can't publish this because the go.* files in this project are screwed up
if me.release.guireleaser == nil {
log.Info("CAN NOT SELF UPDATE HERE. cmd =", docmd)
return false
}
homeDir, _ := os.UserHomeDir()
gosum := filepath.Join(homeDir, "go/src/go.wit.com/apps/guireleaser/go.sum")
if !shell.Exists(gosum) {
log.Info("go.sum must exist here")
me.release.guireleaser.Status.MakeRedomod()
}
if me.current.Status.IsPrivate() {
// do not self update private repos // do not self update private repos
log.Info("This is a private repo and can not be self checked") log.Info("This is a private repo and can not be self checked")
return true return true
} }
// try to pull from google // try to pull from google
if gopath == me.startRepo.GetGoPath() { var result cmd.Status
if gopath == "go.wit.com/apps/guireleaser" {
log.Info("CAN NOT SELF UPDATE. cmd =", docmd) log.Info("CAN NOT SELF UPDATE. cmd =", docmd)
log.Info("go get must be run from somewhere else other than startRepo") log.Info("go get must be run from somewhere else other than guireleaser")
log.Info("chdir to autotypist if it exists") result = shell.PathRun("/home/jcarr/go/src/go.wit.com/apps/autotypist", docmd)
msg := fmt.Sprint("CAN NOT SELF UPDATE. cmd =", docmd) } else {
badExit(errors.New(msg)) // publish go.mod & go.sum for use with go
os.Unsetenv("GO111MODULE")
log.Info("TRYING TO SELF UPDATE HERE. cmd =", docmd)
result = me.release.guireleaser.Status.Run(docmd)
} }
// publish go.mod & go.sum for use with go
os.Unsetenv("GO111MODULE")
log.Info("TRYING TO SELF UPDATE HERE. cmd =", docmd)
result := me.startRepo.Run(docmd)
if result.Error != nil { if result.Error != nil {
log.Info("SELF UPDATE FAILED. error =", result.Error) log.Info("SELF UPDATE FAILED. error =", result.Error)
log.Info("SELF UPDATE FAILED. exit =", result.Exit) log.Info("SELF UPDATE FAILED. exit =", result.Exit)
@ -253,7 +207,7 @@ func doPublishVersion() bool {
log.Info("SELF UPDATE FAILED") log.Info("SELF UPDATE FAILED")
return false return false
} }
log.Info("SELF UPDATE OK. out =", strings.Join(result.Stdout, "\n")) log.Info("SELF UPDATE OK. out =", result.Stdout)
log.Info("SELF UPDATE WORKED") log.Info("SELF UPDATE WORKED")
return true return true
} }

19
exit.go
View File

@ -1,19 +0,0 @@
package main
import (
"os"
"go.wit.com/log"
)
func okExit(thing string) {
log.Info(thing, "ok")
// log.Info("Finished go-clean on", check.GetNamespace(), "ok")
me.forge.Exit()
os.Exit(0)
}
func badExit(err error) {
log.Info("forge failed: ", err, me.forge.Config.ReposDir)
os.Exit(-1)
}

View File

@ -1,167 +0,0 @@
package main
import (
"errors"
"fmt"
"os"
"path/filepath"
"go.wit.com/log"
"go.wit.com/lib/protobuf/gitpb"
)
var findCounter int
var findFix bool = false
var findOk bool = true
func checkDeps(repo *gitpb.Repo) error {
if repo.GoDeps == nil {
return fmt.Errorf("%s has GoDeps == nil", repo.GetNamespace())
}
for dep := range repo.GoDeps.IterAll() {
// log.Info(repo.GetNamespace(), dep.GoPath, dep.Version)
// check if the package in question is waiting for another package to publish
found := me.forge.FindByGoPath(dep.GoPath)
if found == nil {
return fmt.Errorf("%s has dep == nil", repo.GetNamespace(), dep.GoPath)
}
// loop through all the repos that need to be published with new go versions
all := me.found.SortByFullPath()
for all.Scan() {
check := all.Next()
if found.GetNamespace() == check.GetNamespace() {
// this package is waiting on other packages to publish
return fmt.Errorf("%s is waiting on %s", repo.GetNamespace(), found.GetNamespace())
}
}
// found package isn't being published. is the version correct?
// never check this? we are done?
/*
if found.GetLastTag() == dep.Version {
// everything is normal
} else {
return fmt.Errorf("%s version mismatch on %s (%s vs %s)", repo.GetNamespace(), found.GetNamespace(), found.GetLastTag(), dep.Version)
}
*/
}
// everything might be cool?
return nil
}
// trys to figure out if there is still something to update
// todo: redo this logic as it is terrible
// rename this findNext()
func findNext() bool {
findCounter = 0
all := me.found.SortByFullPath()
for all.Scan() {
check := all.Next()
if check.GetMasterBranchName() != check.GetCurrentBranchName() {
log.Info("YOU MUST BE ON THE MASTER BRANCH", check.GetNamespace())
continue
}
if check.IsDirty() {
log.Info("CAN NOT RELEASE DIRTY REPO", check.GetNamespace())
continue
}
if alreadyDone(check) {
log.Info("findNext() alreadyDone. WHY IS THIS STILL CHECKING?", check.GetNamespace())
continue
}
log.Info("CHECKING START:", check.GetNamespace())
if me.forge.Config.IsPrivate(check.GetNamespace()) {
log.Info("GOOD TO GO ON PRIVATE REPO", check.GetNamespace())
setCurrentRepo(check, "should be good to release", "pretty sure")
return true
}
godepsNew, err := check.GoSumFromRepo()
if err != nil {
log.Info("CHECKING go deps from repo failed", err)
continue
}
if godepsNew == nil {
// don't check godepsNew, but check to make sure go mod tidy actually ran without error
os.Unsetenv("GO111MODULE")
cmd := []string{"go", "mod", "tidy"}
err := check.RunVerbose(cmd)
if err != nil {
log.Info("go mod tidy failed. this go package needs to be examined by hand as it doesn't appear to be primitive")
os.Exit(-1)
}
// if godepsNew == nil, then this go package is a primitive and there is no go.sum file
} else {
if err := testGoDepsCheckOk(godepsNew, argv.Verbose); err != nil {
log.Info("CHECKING current repo deps failed", err)
continue
}
}
if err := me.forge.FinalGoDepsCheckOk(check, argv.Verbose); err != nil {
// if err := me.forge.FinalGoDepsCheckOk(check, false); err != nil {
log.Info("FinalGoDepsCheckOk() repo=", check.GetNamespace(), "err:", err)
log.Info("CHECKING END:", check.GetNamespace())
log.Info("")
continue
}
log.Info("GOOD TO GO ON", check.GetNamespace())
setCurrentRepo(check, "should be good to release", "pretty sure")
return true
}
if findCounter == 0 {
log.Info("NOTHING TO UPDATE. findCounter =", findCounter, "found len =", me.found.Len())
if me.found.Len() == 0 {
printDone()
okExit("")
}
} else {
log.Info("me.current is nil findCounter =", findCounter, "so set findFix =", findFix)
}
log.Info("tried to findNext() but not sure what to do next counter =", findCounter, "findFix =", findFix)
setCurrentRepo(nil, "findNext found nothing", "crap")
me.release.status.SetText("ALL DONE?")
return false
}
func setCurrentRepo(check *gitpb.Repo, s string, note string) bool {
me.current = check
if check == nil {
me.release.repo.SetText("")
me.release.version.SetText("")
me.release.releaseVersionB.SetText("nope")
me.release.version.SetText("badver")
} else {
me.release.repo.SetText(check.GetNamespace())
me.release.version.SetText(check.GetTargetVersion())
me.release.releaseVersionB.SetText("release version " + check.GetTargetVersion())
me.release.version.SetText(check.GetTargetVersion())
}
me.release.status.SetText(s)
me.release.notes.SetText(note)
// me.release.openrepo.Enable()
return true
}
func testGoDepsCheckOk(godeps *gitpb.GoDeps, verbose bool) error {
if godeps == nil {
return errors.New("testGoDepsCheckOk() godeps == nil")
}
all := godeps.SortByGoPath()
for all.Scan() {
depRepo := all.Next()
fullpath := filepath.Join(me.forge.Config.ReposDir, depRepo.GoPath)
found := me.found.FindByFullPath(fullpath)
if found == nil {
continue
}
return fmt.Errorf("dep is being upgraded %s", depRepo.GoPath)
}
return nil
}

View File

@ -4,6 +4,7 @@ import (
"go.wit.com/gui" "go.wit.com/gui"
"go.wit.com/lib/debugger" "go.wit.com/lib/debugger"
"go.wit.com/lib/gui/logsettings" "go.wit.com/lib/gui/logsettings"
"go.wit.com/log"
) )
func globalDisplayOptions(box *gui.Node) { func globalDisplayOptions(box *gui.Node) {
@ -11,24 +12,46 @@ func globalDisplayOptions(box *gui.Node) {
group1 := vbox.NewGroup("Global Display Options") group1 := vbox.NewGroup("Global Display Options")
/* hidegrid := group1.NewGrid("hidecfg", 0, 0)
hidegrid := group1.NewGrid("hidecfg", 0, 0)
hidegrid.NewButton("Show Repository Window", func() { hidegrid.NewButton("Show Repository Window", func() {
if me.repos.Hidden() { if me.repos.Hidden() {
me.repos.Show() me.repos.Show()
} else { } else {
me.repos.Hide() me.repos.Hide()
} }
log.Info("showing reposwin") log.Info("showing reposwin")
}) })
hidegrid.NextRow() hidegrid.NextRow()
*/
group1 = vbox.NewGroup("prep for release") group1 = vbox.NewGroup("prep for release")
grid := group1.RawGrid() grid := group1.RawGrid()
grid.NewButton("make prepare-release", func() { grid.NewButton("make prepare-release", func() {
rePrepareRelease() me.Disable()
me.release.box.Disable()
defer me.Enable()
loop := me.repos.View.ReposSortByName()
for loop.Scan() {
repo := loop.Repo()
master := repo.Status.GetMasterVersion()
lastTag := repo.Status.LastTag()
if master == lastTag {
repo.Status.SetTargetVersion(master)
} else {
repo.Status.IncrementRevisionVersion("Nov 2024 test")
}
}
findNext()
if setAllBranchesToMaster() {
// if it succeeds, disable this button
me.setBranchesToMasterB.Disable()
me.release.box.Enable()
me.repos.View.PrintReleaseReport("", "")
} else {
log.Info("setAllBranchesToMaster() failed")
}
}) })
grid.NextRow() grid.NextRow()

42
hideFunction.go Normal file
View File

@ -0,0 +1,42 @@
package main
import (
"os"
"go.wit.com/lib/gui/repolist"
)
// like tcl/tk, use ENV variables to set display preferences
func hideFunction(r *repolist.RepoRow) {
// always show dirty repos
if r.Status.IsDirty() {
r.Show()
return
}
// hide read-only repos
if os.Getenv("AUTOTYPIST_READONLY") == "hide" {
if r.Status.ReadOnly() {
// log.Info(r.Name(), "hiding read-only repo")
r.Hide()
return
} else {
// log.Info(r.Name(), "not hiding read-only repo")
}
}
// show repos with mismatched mode
// this means, if you are in "devel" mode, show all the repos that
// might be stuck on the wrong branch, like 'master' or '<username>'
if os.Getenv("AUTOTYPIST_MODE") != "" {
if !r.Status.IsCorrectMode(os.Getenv("AUTOTYPIST_MODE")) {
r.Show()
return
}
}
// show everything else. often this will be "unconforming" repos
// if you what those repos ignored, add these to the config file
// as read-only=true
r.Show()
}

200
http.go
View File

@ -4,10 +4,9 @@ import (
"fmt" "fmt"
"net/http" "net/http"
"os" "os"
"path/filepath"
"strings" "strings"
"go.wit.com/lib/protobuf/gitpb" "go.wit.com/lib/gui/repolist"
"go.wit.com/log" "go.wit.com/log"
) )
@ -27,6 +26,10 @@ func okHandler(w http.ResponseWriter, r *http.Request) {
repoName := r.URL.Query().Get("repo") repoName := r.URL.Query().Get("repo")
version := r.URL.Query().Get("version") version := r.URL.Query().Get("version")
comment := r.URL.Query().Get("comment") comment := r.URL.Query().Get("comment")
readonly := r.URL.Query().Get("readonly")
onlydirty := r.URL.Query().Get("onlydirty")
perfect := r.URL.Query().Get("perfect")
whitelist := r.URL.Query().Get("whitelist")
switch route { switch route {
case "/help": case "/help":
@ -44,9 +47,18 @@ func okHandler(w http.ResponseWriter, r *http.Request) {
log.Info("") log.Info("")
log.Info("setVersion?repo=go.wit.com/gui?target=0.2 attempts to set the target version to 0.2") log.Info("setVersion?repo=go.wit.com/gui?target=0.2 attempts to set the target version to 0.2")
log.Info("") log.Info("")
case "/tempWin":
tempWin := makeTempView()
loop := me.repos.View.UnmergedRepos()
for loop.Scan() {
repo := loop.Repo()
tempWin.View.ShowRepo(repo)
log.Info("UnmergedRepo: " + repo.Name())
}
case "/doRelease": case "/doRelease":
buttonDisable() buttonDisable()
if err := doRelease(); err == nil { if doRelease() {
buttonEnable() buttonEnable()
log.Info("doRelease() worked") log.Info("doRelease() worked")
} else { } else {
@ -70,59 +82,185 @@ func okHandler(w http.ResponseWriter, r *http.Request) {
return return
} }
// log.Info(me.current.StandardHeader()) log.Info(me.current.StandardHeader())
log.Info(me.forge.StandardReleaseHeader(me.current, "todoing")) log.Info(me.current.StandardReleaseHeader())
case "/rescanAll":
me.repos.View.ScanRepositories()
case "/setCurrentRepo": case "/setCurrentRepo":
log.Info("repo: " + repoName) log.Info("repo: " + repoName)
log.Info("version: " + version) log.Info("version: " + version)
log.Info("comment: " + comment) log.Info("comment: " + comment)
repo := me.forge.FindByGoPath(repoName) repo := me.repos.View.FindRepoByName(repoName)
if repo == nil { if repo == nil {
log.Info("FindRepoByName() returned nil") log.Info("FindRepoByName() returned nil")
return return
} }
setCurrentRepo(repo, "HTTP", "doRelease() ?") setCurrentRepo(repo, "HTTP", "doRelease() ?")
case "/IncrementRevisonVersion":
log.Info("repo: " + repoName)
log.Info("version: " + version)
me.current.Status.IncrementRevisionVersion(comment)
case "/IncrementMinorVersion":
log.Info("repo: " + repoName)
log.Info("version: " + version)
me.current.Status.IncrementMinorVersion("trying minor")
case "/setAllBranchesToMaster":
log.Info("set all branches to master")
me.Disable()
defer me.Enable()
if setAllBranchesToMaster() {
// if it succeeds, disable this button
me.setBranchesToMasterB.Disable()
}
return return
case "/showNext": case "/setTargetVersion":
check := me.forge.FindByGoPath(me.current.GetGoPath()) log.Info("repo: " + repoName)
if check == nil { log.Info("version: " + version)
log.Info("boo, current is missing", me.current.GetGoPath()) if me.current == nil {
log.Info("me.current == nil")
return return
} }
testGoRepo(check) me.current.Status.SetTargetVersion(version)
me.forge.HumanPrintRepo(check) case "/setAllTargetVersions":
log.Info("upgrade reason:", me.reason[check]) log.Info("version: " + version)
return
loop := me.repos.View.ReposSortByName()
for loop.Scan() {
repo := loop.Repo()
master := repo.Status.GetMasterVersion()
lastTag := repo.Status.LastTag()
if master == lastTag {
repo.Status.SetTargetVersion(master)
} else {
repo.Status.IncrementRevisionVersion("Nov 2024 test")
}
}
case "/whitelist":
repo := me.repos.View.FindRepoByName(repoName)
if repo == nil {
log.Info("FindRepoByName() returned nil")
return
}
log.Info("whitelisted " + repo.Name())
if whitelist == "false" {
repo.Status.Whitelist = false
} else {
repo.Status.Whitelist = true
}
case "/showNext":
log.Info("gui repo: " + me.release.repo.String())
log.Info("gui name: " + me.release.version.String())
log.Info("gui notes: " + me.release.notes.String())
log.Info("gui status: " + me.release.status.String())
log.Info("")
if me.current == nil {
log.Info("me.current == nil")
return
}
if checkValidGoSum(me.current) {
log.Info("checkValidGoSum() == true")
} else {
log.Info("checkValidGoSum() == false SHOULD NOT RELEASE THIS")
}
if me.current.Status.IsReleased() {
log.Info("IsReleased() == true SHOULD NOT RELEASE THIS")
} else {
log.Info("IsReleased() == false")
}
if me.current.Status.CheckDirty() {
log.Info("CheckDirty() == true. SHOULD NOT RELEASE THIS")
} else {
log.Info("CheckDirty() == false")
}
if me.current.Status.IsPrimitive() {
log.Info("IsPrimitive() == true")
} else {
log.Info("IsPrimitive() == false")
}
if me.current.Status.IsPrivate() {
log.Info("IsPrivate() == true")
} else {
log.Info("IsPrivate() == false")
}
if ok, compiled, err := me.current.Status.IsProtobuf(); ok {
log.Info(log.Sprint("IsProtobuf() == true compiled protobuf files = ", compiled))
if err != nil {
log.Info(log.Sprint("IsProtobuf() == err", err))
os.Exit(-1)
}
for _, s := range compiled {
log.Info("\tcompiled file found:", s)
}
} else {
log.Info("IsProtobuf() == false")
if err != nil {
log.Info(log.Sprint("IsProtobuf() == err", err))
}
}
if me.current.Status.Whitelist {
log.Info("Whitelist == true SHOULD NOT RELEASE THIS")
} else {
log.Info("Whitelist == false")
}
log.Info("")
log.Info(repolist.ReportHeader())
log.Info(me.current.StandardHeader())
log.Info("")
log.Info(repolist.ReleaseReportHeader())
log.Info(me.current.StandardReleaseHeader())
case "/list": case "/list":
me.forge.PrintHumanTable(me.found) me.repos.View.PrintReport(readonly, onlydirty, perfect)
return
case "/releaseList": case "/releaseList":
me.forge.PrintHumanTable(me.found) me.repos.View.PrintReleaseReport(readonly, perfect)
return case "/quit":
log.Info("Got URL /quit")
os.Exit(0)
case "/goweblist":
loop := me.repos.View.ReposAll()
for loop.Scan() {
repo := loop.Repo()
lastTag := repo.LastTag()
tag := repo.Status.NewestTag()
gitAge, err := tag.GetDate()
if err != nil {
log.Info(fmt.Sprintf("tag date error", repo.Name()))
}
// if lastTag == "" {
// lastTag = tag.Name()
// }
if repo.ReadOnly() {
if readonly == "true" {
continue
}
}
// dur := time.Since(gitAge)
// log.Info(fmt.Sprintf("%-60s %s %s %s", repo.Name(), lastTag, shell.FormatDuration(dur), lastTag, tag.Name()))
log.Info(fmt.Sprintf("%s %d %s", repo.Name(), gitAge.Unix(), lastTag))
/*
for _, tag := range repo.Tags.ListAll() {
log.Info(fmt.Sprintf("%-60s %s", "", tag.Name()))
}
*/
}
default: default:
log.Info("BAD URL = " + route) log.Info("BAD URL = " + route)
} }
} }
func testGoRepo(check *gitpb.Repo) {
data, _ := os.ReadFile(filepath.Join(check.FullPath, "go.mod"))
log.Info(string(data))
if err := me.forge.FinalGoDepsCheckOk(check, true); err == nil {
log.Info("forge.FinalGoDepsCheck(check) worked!")
} else {
log.Info("forge.FinalGoDepsCheck(check) failed. boo.")
}
}
// starts and sits waiting for HTTP requests // starts and sits waiting for HTTP requests
func startHTTP() { func startHTTP() {
http.HandleFunc("/", okHandler) http.HandleFunc("/", okHandler)
p := fmt.Sprintf(":%d", argv.Port) p := fmt.Sprintf(":%d", myargs.Port)
log.Println("Running on port", p) log.Println("Running on port", p)
err := http.ListenAndServe(p, nil) err := http.ListenAndServe(p, nil)

35
initRepoList.go Normal file
View File

@ -0,0 +1,35 @@
package main
// this initializes the repos
import (
"strings"
"go.wit.com/lib/gui/repostatus"
"go.wit.com/log"
)
func (r *repoWindow) initRepoList() {
r.View.InitRepoList(".config/guireleaser")
log.Info("scanning everything in ~/go/src")
for i, path := range repostatus.ListGitDirectories() {
// log.Info("addRepo()", i, path)
path = strings.TrimPrefix(path, me.goSrcPwd.String())
path = strings.Trim(path, "/")
log.Info("addRepo()", i, path)
r.View.NewRepo(path)
}
}
func (r *repoWindow) tmpRepoList() {
log.Info("scanning everything in ~/go/src")
for i, path := range repostatus.ListGitDirectories() {
// log.Info("addRepo()", i, path)
path = strings.TrimPrefix(path, me.goSrcPwd.String())
path = strings.Trim(path, "/")
log.Info("addRepo()", i, path)
r.View.NewRepo(path)
}
}

189
main.go
View File

@ -2,49 +2,47 @@ package main
import ( import (
"embed" "embed"
"errors"
"fmt"
"os" "os"
"path/filepath" "path/filepath"
"go.wit.com/dev/alexflint/arg" "go.wit.com/dev/alexflint/arg"
"go.wit.com/lib/fhelp" "go.wit.com/gui"
"go.wit.com/lib/gadgets" "go.wit.com/lib/gui/gowit"
"go.wit.com/lib/gui/prep"
"go.wit.com/lib/gui/shell" "go.wit.com/lib/gui/shell"
"go.wit.com/lib/protobuf/forgepb"
"go.wit.com/lib/protobuf/gitpb"
"go.wit.com/log" "go.wit.com/log"
) )
var VERSION string var VERSION string
var ARGNAME string = "guireleaser"
//go:embed resources/* //go:embed resources/*
var resources embed.FS var resources embed.FS
var argv args var myargs argv
func main() { func main() {
me = new(autoType) me = new(autoType)
prep.Bash(ARGNAME, argv.DoAutoComplete) // this line should be: prep.Bash(argv)
me.myGui = prep.Gui() // prepares the GUI package for go-args
me.pp = arg.MustParse(&argv)
me.forge = forgepb.Init() // load the ~/.config/forge/ config
me.forge.ScanRepoDir() // looks for new dirs, checks existing repos for changes if err := me.forge.ConfigLoad(); err != nil {
me.found = new(gitpb.Repos) log.Warn("forgepb.ConfigLoad() failed", err)
os.Exit(-1)
}
fhelp.CheckGoModCleanExit() // load the ~/.config/forge/ machine file from zoopb
if err := me.machine.ConfigLoad(); err != nil {
log.Warn("zoopb.ConfigLoad() failed", err)
os.Exit(-1)
}
// me.forge.ConfigPrintTable() // parse the command line
os.Setenv("REPO_WORK_PATH", me.forge.Config.ReposDir) arg.MustParse(&myargs)
// save the ENV var here // save the ENV var here
me.releaseReasonS = os.Getenv("GUIRELEASE_REASON") me.releaseReasonS = os.Getenv("GUIRELEASE_REASON")
if me.releaseReasonS == "" { if me.releaseReasonS == "" {
badExit(errors.New("shell ENV GUIRELEASE_REASON not set")) log.Info("shell ENV GUIRELEASE_REASON not set")
os.Exit(0)
} }
// unset the go development ENV var to generate release files // unset the go development ENV var to generate release files
@ -52,20 +50,16 @@ func main() {
// user drops to a shell or xterm, then they shouldn't be set there either // user drops to a shell or xterm, then they shouldn't be set there either
os.Unsetenv("GO111MODULE") os.Unsetenv("GO111MODULE")
me.myGui.Start() // loads the GUI toolkit me.myGui = gui.New()
me.myGui.InitEmbed(resources)
me.myGui.Default()
// our main window // our main window
me.mainWindow = gadgets.RawBasicWindow("GUI release manager " + VERSION) me.mainWindow = me.myGui.NewWindow("GUI release manager " + VERSION)
me.mainWindow.Custom = func() { me.mainBox = me.mainWindow.NewBox("bw hbox", true)
log.Warn("Window closed. forge configsave")
// sets the hidden flag to false so Toggle() works
me.forge.ConfigSave()
okExit("")
}
me.mainWindow.Make()
me.mainWindow.Show()
me.mainBox = me.mainWindow.Box() // start the http server for polling status
go startHTTP()
// sanity check of things that might be around that mess // sanity check of things that might be around that mess
// up things later // up things later
@ -74,58 +68,133 @@ func main() {
homeDir, _ := os.UserHomeDir() homeDir, _ := os.UserHomeDir()
gowork := filepath.Join(homeDir, "go/src/go.work") gowork := filepath.Join(homeDir, "go/src/go.work")
if shell.Exists(gowork) { if shell.Exists(gowork) {
badExit(errors.New("go.work must be deleted")) log.Info("go.work must be deleted")
os.Exit(0)
} }
/*
// sanity check of things that might be around that mess
// up things later
// check to make sure we have a go.sum here
gosum := filepath.Join(homeDir, "go/src/go.wit.com/apps/guireleaser/go.sum")
if !shell.Exists(gosum) {
log.Info("go.sum must exist here")
os.Exit(0)
}
*/
log.Info("Creating the Release Window") log.Info("Creating the Release Window")
// initialize the repo list window
// which should be all the git repositories in ~/go/src & the .config file
me.repos = makeRepoView()
if myargs.DumpVersions {
gowit.DumpVersions(me.repos.View)
os.Exit(0)
}
// the left side of the window options // the left side of the window options
globalDisplayOptions(me.mainBox) globalDisplayOptions(me.mainBox)
// create the right side of the main window // create the right side of the main window
createReleaseBox(me.mainBox) createReleaseBox(me.mainBox)
// disable the open repo button. this isn't really important
// but does indicates the app (and toolkit) is working
// this can be removed later, but in these early days, I'm using this
// tool to release the code for this app, the gui and the gui toolkits
// and sometimes they lie, don't display stuff, don't even disable things
// so I can't trust even what I see. It's complicated right now still.
me.release.openrepo.Disable()
// disable the gui until the repos are scanned // disable the gui until the repos are scanned
me.release.box.Disable() me.release.box.Disable()
me.Disable() me.Disable()
// todo: add this to forgepb // parse config file and scan for .git repos
me.startRepo = me.forge.FindWorkingDirRepo() me.repos.initRepoList()
// setTargetVersion()
if _, count, _, err := me.forge.IsEverythingOnMaster(); err != nil { // register a Show/Hide function for the repo list table
log.Info("not everything is on the master branch (", count, "repos)") me.repos.View.RegisterHideFunction(hideFunction)
if argv.Quick != nil {
// quick also means ignore the master branch check // scan in the State of all the repos
argv.Force = true // TODO: should not really be necessary directly after init()
me.repos.View.ScanRepositories()
loop := me.repos.View.ReposSortByName()
for loop.Scan() {
repo := loop.Repo()
if me.forge.IsReadOnly(repo.GoPath()) {
repo.Status.SetReadOnly(true)
} else {
repo.Status.SetReadOnly(false)
} }
if !argv.Force { if me.forge.IsPrivate(repo.GoPath()) {
os.Exit(-1) repo.Status.SetPrivate(true)
} else {
repo.Status.SetPrivate(false)
} }
} }
if me.startRepo == nil { // the repo from the command line
pwd, _ := os.Getwd() // var myrepo *repolist.RepoRow
msg := fmt.Sprint("Can not run if pwd is not a repo", pwd)
badExit(errors.New(msg)) // find myself. the guireleaser directory is used as a working scratchpad
// for running go commands that can mess up the go.* files
loop = me.repos.View.ReposSortByName()
for loop.Scan() {
repo := loop.Repo()
if repo.GoPath() == "go.wit.com/apps/guireleaser" {
if me.release.guireleaser == nil {
me.release.guireleaser = repo
}
}
/*
if repo.GoPath() == myargs.Repo {
myrepo = repo
}
*/
} }
me.forge.RillFuncError(rillPurge) if me.release.guireleaser == nil {
log.Info("Can not release if guireleaser was not found")
// run this each time something gets published successfully os.Exit(0)
rePrepareRelease()
if findNext() {
log.Info("prepare release findNext() returned true")
} else {
// check if nothing is found an exit?
if me.found.Len() == 0 {
log.Info("nothing found to publish")
okExit("found nothing")
}
} }
me.Enable() me.Enable()
me.release.box.Enable()
// start the http server for polling status // intermittently scans the status indefinitly
startHTTP() me.repos.View.Watchdog(func() {
log.Info("In main()")
// processing is done. update the repo summary box
// me.summary.Update()
})
}
// start the initail scan and make sure each repo is set
// to the master branch
func setAllBranchesToMaster() bool {
var worked bool = true
loop := me.repos.View.ReposSortByName()
for loop.Scan() {
repo := loop.Repo()
if repo.ReadOnly() {
continue
}
if repo.IsDirty() {
continue
}
if repo.Status.Whitelist {
continue
}
if repo.Status.CheckoutMaster() {
log.Warn("git checkout master branch worked", repo.Name())
} else {
log.Warn("git checkout master branch failed", repo.Name())
worked = false
}
// repo.NewScan()
}
return worked
} }

View File

@ -1,297 +0,0 @@
package main
import (
"errors"
"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"
)
func forceReleaseVersion(repo *gitpb.Repo) {
if argv.Minor {
// if v1.2.3 change to v.1.3.0
repo.IncrementTargetMinor()
} else {
// if v1.2.3 change to v.1.2.4
repo.IncrementTargetRevision()
}
}
func checkpkgcache(repo *gitpb.Repo) error {
homedir, err := os.UserHomeDir()
if err != nil {
return err
}
rver := repo.GetLastTag()
if rver == "" {
return errors.New("could not get master version")
}
moddir := filepath.Join(homedir, "go/pkg/mod", repo.GetGoPath()+"@"+rver)
if shell.IsDir(moddir) {
return nil
}
getpath := repo.GetGoPath() + "@" + repo.GetLastTag()
log.Infof("~/go/pkg/mod/ IS MISSING %s so I'm running go get here.", getpath)
_, err = me.startRepo.RunVerboseOnError([]string{"go", "get", getpath})
return err
}
var rillcount int
func rillPurge(repo *gitpb.Repo) error {
if me.forge.Config.IsReadOnly(repo.GetGoPath()) {
return nil
}
if me.forge.Config.IsPrivate(repo.GetGoPath()) {
return nil
}
_, err := repo.RunQuiet([]string{"go-mod-clean", "purge"})
rillcount += 1
if err != nil {
log.Info("go-mod-clean purge failed", repo.GetGoPath(), err)
return err
}
return nil
}
func rillRestore(repo *gitpb.Repo) error {
if me.forge.Config.IsReadOnly(repo.GetGoPath()) {
return nil
}
if me.forge.Config.IsPrivate(repo.GetGoPath()) {
return nil
}
var err error
if argv.Verbose {
log.Info("go-mod-clean lax START", repo.GetGoPath())
result := repo.RunRealtime([]string{"go-mod-clean", "lax"})
log.Info("go-mod-clean lax END", repo.GetGoPath())
if result.Exit != 0 {
err = fmt.Errorf("repo %s failed %d", repo.GetGoPath(), result.Exit)
}
} else {
_, err = repo.RunQuiet([]string{"go-mod-clean", "lax"})
}
rillcount += 1
if err != nil {
log.Info("go-mod-clean lax failed", repo.GetGoPath(), err)
return err
}
return nil
}
func rePrepareRelease() {
me.forge.ScanRepoDir() // looks for new dirs, checks existing repos for changes
me.found = new(gitpb.Repos)
me.reason = make(map[*gitpb.Repo]string) // stores the reason repos need to be versioned & released
log.Printf("rePrepareRelease() START rill go-mod-clean lax (11 seconds?)")
rillcount = 0
forgepb.RillX = 2
forgepb.RillY = 2
now := time.Now()
me.forge.RillFuncError(rillRestore)
log.Printf("showRestore() (%d total repos) took:%s\n", rillcount, shell.FormatDuration(time.Since(now)))
log.Sleep(1)
all2 := me.forge.Repos.SortByFullPath()
for all2.Scan() {
check := all2.Next()
if me.forge.Config.IsReadOnly(check.GetGoPath()) {
continue
}
if me.forge.Config.IsPrivate(check.GetGoPath()) {
continue
}
// this should be rare? nonexistant?
if err := checkpkgcache(check); err != nil {
log.Info("go get checks failed here.", err, check.GetGoPath())
}
}
all := me.forge.Repos.SortByFullPath()
for all.Scan() {
check := all.Next()
if alreadyDone(check) {
// means it was already published
// protects against logic errors that might result
// in an infinite loop
log.Info("WARNING alreadyDone rePrepareRelease()", check.GetGoPath())
continue
}
if me.forge.Config.IsReadOnly(check.GetGoPath()) {
// can't release readonly repos
continue
}
master := check.GetMasterVersion()
lastTag := check.GetLastTag()
if argv.Quick != nil {
// if argv has 'quick' don't do anything
// that doesn't actually have a patch
if master == lastTag {
continue
}
}
log.Info("LAST TAG", check.FullPath, master, lastTag)
// this is detailed. It makes sure the go.* files are absolutely perfect
if !me.forge.Config.IsPrivate(check.GetGoPath()) {
if err := checkPublishedGodeps(check); err != nil {
// this means the published godeps are no longer up to date
forceReleaseVersion(check)
me.found.AppendByFullPath(check)
log.Info("checkPublishedGodeps failed with err", check.GetGoPath(), err)
continue
} else {
// log.Info("checkPublishedGodeps is ok", check.GetGoPath())
}
}
// if master != lastTag, always increment
if master != lastTag {
newmhash := check.GetTagHash(master)
oldlhash := check.GetTagHash(lastTag)
if newmhash == oldlhash {
// they are actually equal
continue
}
b1 := check.CountDiffObjects(oldlhash, newmhash)
b2 := check.CountDiffObjects(newmhash, oldlhash)
if b1 != 0 {
log.Printf("HASH ERROR %-50s tag %s < %s\n", check.GetGoPath(), newmhash, oldlhash)
log.Info("old vs new count", b1, b2, "git merge", oldlhash)
}
if b1 == 0 && b2 == 0 {
log.Info("got to identical repo", check.GetGoPath(), b1, b2)
log.Info("got to identical repo", check.GetGoPath(), oldlhash, newmhash)
// actually identical. do nothing
continue
}
if gitpb.IsGoTagVersionGreater(lastTag, master) {
// this function is not right really. the hash error above should catch it correctly
// log.Printf("PROBABLY NOT NEE %-50s tag %s < %s\n", check.GetGoPath(), lastTag, master)
}
log.Printf("NEED RELEASE FOR %-50s tag %s != %s\n", check.GetGoPath(), master, lastTag)
forceReleaseVersion(check)
me.found.AppendByFullPath(check)
me.reason[check] = "master != lastTag"
continue
}
if me.forge.Config.IsPrivate(check.GetGoPath()) {
// only checks after this are GO dep related which don't matter for private repos
continue
}
if argv.Protobuf && check.GetRepoType() == "protobuf" {
log.Printf("NEED RELEASE FOR %s err: %v\n", check.GetGoPath(), "because --protobuf")
// if --protobuf, this will force upgrade each one
forceReleaseVersion(check)
me.found.AppendByFullPath(check)
me.reason[check] = "protobuf repo deps changed"
continue
}
// if the repo is a go binary or plugin for a new release for
// any library version change
// if check.GetRepoType() == "binary" || check.GetRepoType() == "plugin" {
// check if the package dependancies changed, if so, re-publish
if err := me.forge.FinalGoDepsCheckOk(check, false); err == nil {
// log.Printf("go.sum is perfect! %s\n", check.GetGoPath())
continue
} else {
log.Printf("NEED RELEASE FOR %-50s err: %v\n", check.GetGoPath(), err)
forceReleaseVersion(check)
me.found.AppendByFullPath(check)
me.reason[check] = "FinalGoDepsCheckOk() failed even though master tag == last tag"
}
}
me.forge.PrintHumanTable(me.found)
// todo: verify each found repo is on the master branch
for repo := range me.found.IterAll() {
if repo.CurrentBranchName != repo.MasterBranchName {
log.Info("repo not on master branch", repo.FullPath)
if !argv.Force {
os.Exit(-1)
}
}
}
}
func printDone() {
for _, gopath := range me.done {
log.Info("printDone() THESE WERE PUBLISHED", gopath)
}
log.Info("printDone() total finished so far:", len(me.done))
time.Sleep(time.Second)
}
func alreadyDone(repo *gitpb.Repo) bool {
for _, gopath := range me.done {
// log.Info("WARNING already done", gopath, repo.GetGoPath())
// log.Info("WARNING already done", gopath, repo.GetGoPath())
// log.Info("WARNING already done", gopath, repo.GetGoPath())
if repo.GetGoPath() == gopath {
log.Info("FOUND. RETURN TRUE. already done", gopath, repo.GetGoPath())
return true
}
}
return false
}
/*
func upgradeReason(repo *gitpb.Repo) string {
for _, gopath := range me.reason {
// log.Info("WARNING already done", gopath, repo.GetGoPath())
// log.Info("WARNING already done", gopath, repo.GetGoPath())
// log.Info("WARNING already done", gopath, repo.GetGoPath())
if repo.GetGoPath() == gopath {
log.Info("FOUND. RETURN TRUE. already done", gopath, repo.GetGoPath())
return true
}
}
return false
}
*/
func checkPublishedGodeps(repo *gitpb.Repo) error {
godepsOld, err := repo.GoSumFromPkgDir()
if err != nil {
return err
}
if godepsOld != nil {
if err := me.forge.TestGoDepsCheckOk(godepsOld, argv.Verbose); err != nil {
return err
}
}
godepsNew, err := repo.GoSumFromRepo()
if err != nil {
return err
}
if godepsOld == nil {
if godepsNew == nil {
log.Printf("%s published godeps == nil && real == nil\n", repo.GetGoPath())
return nil
} else {
return fmt.Errorf("published godeps == nil vs real != nil")
}
}
if err := me.forge.TestGoDepsCheckOk(godepsNew, argv.Verbose); err != nil {
return err
}
return nil
}

View File

@ -3,14 +3,16 @@ package main
import ( import (
"fmt" "fmt"
"time" "os"
"path/filepath"
"strings"
"go.wit.com/gui" "go.wit.com/gui"
"go.wit.com/log" "go.wit.com/log"
"go.wit.com/lib/gadgets" "go.wit.com/lib/gadgets"
"go.wit.com/lib/gui/repolist"
"go.wit.com/lib/gui/shell" "go.wit.com/lib/gui/shell"
"go.wit.com/lib/protobuf/gitpb"
) )
type releaseStruct struct { type releaseStruct struct {
@ -25,14 +27,19 @@ type releaseStruct struct {
releaseVersionB *gui.Node releaseVersionB *gui.Node
reason *gadgets.BasicEntry reason *gadgets.BasicEntry
// openrepo *gui.Node openrepo *gui.Node
goGetB *gui.Node goGetB *gui.Node
checkGoSumB *gui.Node checkGoSumB *gui.Node
checkDirtyB *gui.Node checkDirtyB *gui.Node
makeRedomodB *gui.Node
sendVersionB *gui.Node sendVersionB *gui.Node
checkSafeB *gui.Node checkSafeB *gui.Node
// whitelist map[string]*repolist.RepoRow whitelist map[string]*repolist.RepoRow
// store myself here. use myself to
// do garbage go get tests and other potential junk
guireleaser *repolist.RepoRow
} }
func (w *autoType) Disable() { func (w *autoType) Disable() {
@ -51,20 +58,14 @@ func createReleaseBox(box *gui.Node) {
me.release.releaseVersionB = me.release.grid.NewButton("release version", func() { me.release.releaseVersionB = me.release.grid.NewButton("release version", func() {
buttonDisable() buttonDisable()
fpath := me.current.FullPath if doRelease() {
if err := doRelease(); err == nil {
buttonEnable() buttonEnable()
log.Info("doRelease() worked", fpath) log.Info("doRelease() worked")
} else { } else {
log.Info("doRelease() failed", err, fpath) log.Info("doRelease() failed")
log.Info("doRelease() FAILED", err, fpath)
log.Info("doRelease() FAILED", err, fpath)
log.Info("doRelease() FAILED", err, fpath)
} }
skipToNext()
me.forge.PrintHumanTable(me.found)
}) })
me.release.grid.NewButton("Find Next", func() { me.release.grid.NewButton("Find Next Releasable", func() {
me.Disable() me.Disable()
defer me.Enable() defer me.Enable()
if findNext() { if findNext() {
@ -72,18 +73,13 @@ func createReleaseBox(box *gui.Node) {
return return
} }
}) })
me.release.grid.NewButton("Show Next", func() {
check := me.current
if check == nil {
log.Info("boo, current is missing", me.current.GetGoPath())
return
}
testGoRepo(check)
me.forge.HumanPrintRepo(check)
})
me.release.grid.NextRow() me.release.grid.NextRow()
me.release.repo = gadgets.NewOneLiner(me.release.grid, "repo") me.release.repo = gadgets.NewOneLiner(me.release.grid, "repo")
me.release.openrepo = me.release.grid.NewButton("Configure", func() {
me.current.Status.Toggle()
})
me.release.openrepo.Disable()
me.release.grid.NextRow() me.release.grid.NextRow()
me.release.status = gadgets.NewOneLiner(me.release.grid, "status") me.release.status = gadgets.NewOneLiner(me.release.grid, "status")
me.release.grid.NextRow() me.release.grid.NextRow()
@ -101,79 +97,227 @@ func createReleaseBox(box *gui.Node) {
me.autoWorkingPwd = gadgets.NewOneLiner(me.release.grid, "working directory (pwd)") me.autoWorkingPwd = gadgets.NewOneLiner(me.release.grid, "working directory (pwd)")
me.release.grid.NextRow() me.release.grid.NextRow()
me.userHomePwd = gadgets.NewOneLiner(me.release.grid, "user home")
me.release.grid.NextRow()
me.goSrcPwd = gadgets.NewOneLiner(me.release.grid, "go src home") me.goSrcPwd = gadgets.NewOneLiner(me.release.grid, "go src home")
me.release.grid.NextRow() me.release.grid.NextRow()
// me.userHomePwd.SetText(homeDir) homeDir, err := os.UserHomeDir()
me.goSrcPwd.SetText(me.forge.Config.ReposDir) if err != nil {
log.Warn("Error getting home directory:", err)
homeDir = "/home/autotypist"
}
me.userHomePwd.SetText(homeDir)
srcDir := filepath.Join(homeDir, "go/src")
me.goSrcPwd.SetText(srcDir)
testf := filepath.Join(srcDir, "go.wit.com/apps/guireleaser", "go.sum")
if !shell.Exists(testf) {
log.Info("go.sum missing", testf)
panic("redo go.sum")
}
group := me.release.box.NewGroup("Run on Current Repo") group := me.release.box.NewGroup("Run on Current Repo")
grid := group.NewGrid("buildOptions", 0, 0) grid := group.NewGrid("buildOptions", 0, 0)
grid.NewButton("whitelist", func() {
// tmp := me.current.GoState()
log.Info("trying to whitelist repo", me.current.GoPath())
me.current.Status.Whitelist = true
findNext()
})
me.release.checkGoSumB = grid.NewButton("checkValidGoSum()", func() {
buttonDisable()
checkValidGoSum(me.current)
buttonEnable()
})
grid.NextRow() grid.NextRow()
group = me.release.box.NewGroup("Publish until done") group = me.release.box.NewGroup("Process against all repos")
grid = group.NewGrid("buildOptions", 0, 0) grid = group.NewGrid("buildOptions", 0, 0)
grid.NewButton("doRelease() all", func() { grid.NewButton("doRelease() all", func() {
var worked bool = true
buttonDisable() buttonDisable()
doReleaseAll() // rather than loop forever, at least limit this to the number of repos
// incase something, somewhere, goes wrong
duration := repolist.TimeFunction(func() {
loop := me.repos.View.ReposSortByName()
for loop.Scan() {
loop.Repo()
if doRelease() {
log.Info("doRelease() worked")
} else {
if os.Getenv("FindNextDone") == "true" {
log.Info("findNext says it was done")
log.Info("findNext says it was done")
log.Info("we can os.Exit here")
}
if me.release.status.String() == "ALL DONE?" {
log.Info("maybe ALL DONE?")
buttonEnable()
worked = true
os.Exit(0)
}
log.Info("doRelease() failed")
worked = false
break
}
}
})
s := fmt.Sprint(duration)
log.Info("release returned", worked, "and ran for", s)
buttonEnable() buttonEnable()
}) })
grid.NextRow() grid.NextRow()
group = me.release.box.NewGroup("experimental and potentially dangerous stuff")
grid = group.NewGrid("buildOptions", 0, 0)
me.setBranchesToMasterB = grid.NewButton("set all branches to master", func() {
me.Disable()
defer me.Enable()
if setAllBranchesToMaster() {
// if it succeeds, disable this button
me.setBranchesToMasterB.Disable()
}
})
grid.NextRow()
grid.NewButton("git ls-files |grep go.mod", func() {
loop := me.repos.View.ReposSortByName()
for loop.Scan() {
repo := loop.Repo()
log.Info("repo:", repo.Name())
if repo.Status.ReadOnly() {
continue
}
if repo.Status.Whitelist {
log.Warn("skipping whitelist", repo.GoPath())
continue
}
good, files := repo.Status.GitLsFiles()
if !good {
log.Warn("Something went wrong", repo.GoPath())
continue
}
for _, filename := range strings.Split(files, "\n") {
log.Info("\tfile", filename)
if filename == "go.mod" {
log.Info("Found go.mod. does version match release version?")
log.Info(repo.Status.GetLastTagVersion(), "vs", repo.Status.GetTargetVersion())
if repo.Status.GetLastTagVersion() != repo.Status.GetTargetVersion() {
log.Info(repo.Status.GetLastTagVersion(), "vs", repo.Status.GetTargetVersion())
log.Info("Found go.sum. version mismatch")
setCurrentRepo(repo, "VERY BROKEN", "rewind go.mod commit")
return
}
}
if filename == "go.sum" {
log.Info("Found go.sum. does version match release version?")
log.Info(repo.Status.GetLastTagVersion(), "vs", repo.Status.GetTargetVersion())
if repo.Status.GetLastTagVersion() != repo.Status.GetTargetVersion() {
log.Info(repo.Status.GetLastTagVersion(), "vs", repo.Status.GetTargetVersion())
log.Info("Found go.sum. version mismatch")
setCurrentRepo(repo, "VERY BROKEN", "rewind go.mod commit")
return
}
}
}
}
log.Info("All repos seem okay")
})
grid.NextRow()
var longB *gui.Node
longB = grid.NewButton("generate go.sum files", func() {
me.Disable()
var worked bool = true
loop := me.repos.View.ReposSortByName()
for loop.Scan() {
repo := loop.Repo()
if repo.Status.Whitelist {
continue
}
ok, err := me.repos.View.CheckValidGoSum(repo)
if !ok {
log.Info("redo go.sum failed on", repo.GoPath(), err)
worked = false
}
}
log.Info("redo go.sum finished with", worked)
me.Enable()
longB.SetLabel("go.sum files created")
if worked {
longB.Disable()
}
})
grid.NextRow()
} }
func doReleaseAll() {
count := 0
for {
log.Info("START doRelease() LOOP count =", count, "len me.done =", len(me.done))
if err := doRelease(); err != nil {
break
}
if err := skipToNext(); err != nil {
break
}
count += 1
if count > me.forge.Repos.Len() {
// never allow a loop longer than all the known repos
// this probably doesn't matter, but often this code is wrong
// so this is a safety check. never remove this check.
break
}
}
}
func skipToNext() error {
shell.RunVerbose([]string{"forge", "dirty"})
log.Info("Sleeping for 2 seconds for no reason.")
time.Sleep(1)
me.forge.ScanRepoDir() // looks for new dirs, checks existing repos for changes
me.found = new(gitpb.Repos)
me.current.ReloadCheck()
me.forge.SetConfigSave(true)
me.forge.ConfigSave()
log.Info("sleep 2")
time.Sleep(2 * time.Second)
printDone()
rePrepareRelease()
findNext()
if me.current == nil {
log.Info("NOT GOOD TO RUN ANOTHER DAY")
log.Info("took out all the loop code")
setCurrentRepo(nil, "loop by hand motherfucker", "fucknuts")
return fmt.Errorf("findNext returned next repo == nil")
}
log.Info("GOOD TO RUN ANOTHER DAY ON:", me.current.GetGoPath())
return nil
}
func buttonDisable() { func buttonDisable() {
me.Disable() me.Disable()
me.release.box.Disable()
} }
func buttonEnable() { func buttonEnable() {
me.Enable() me.Enable()
me.release.box.Enable() }
func setCurrentRepo(newcur *repolist.RepoRow, s string, note string) bool {
if newcur.ReadOnly() {
return false
}
me.release.repo.SetText(newcur.GoPath())
me.release.status.SetText(s)
me.release.notes.SetText(note)
me.current = newcur
me.release.version.SetText(me.current.Status.GetTargetVersion())
me.release.releaseVersionB.SetText("release version " + me.current.Status.GetTargetVersion())
me.release.openrepo.Enable()
return true
}
// trys to figure out if there is still something to update
// todo: redo this logic as it is terrible
// rename this findNext()
func findNext() bool {
loop := me.repos.View.ReposSortByName()
for loop.Scan() {
repo := loop.Repo()
if repo.Status.IsReleased() {
continue
}
if repo.Status.Whitelist {
continue
}
if repo.ReadOnly() {
// log.Info("findNext() skipping readonly")
continue
}
if repo.CheckDirty() {
log.Info("findNext() skipping dirty")
continue
}
// do makeredomod here
// if ! repo.Status.Exists("go.sum") {
// }
if repo.Status.IsPrimitive() {
log.Info("findNext()", repo.GoPath())
if setCurrentRepo(repo, "PRIMATIVE", "release new version") {
return true
}
continue
}
log.Info("findNext()", repo.GoPath(), "is not a primative repo")
if checkValidGoSum(repo) {
setCurrentRepo(repo, "should be good to release", "pretty sure")
return true
}
}
log.Info("tried to findNext() but not sure what to do next")
me.release.status.SetText("ALL DONE?")
return false
} }

72
repoview.go Normal file
View File

@ -0,0 +1,72 @@
package main
import (
"go.wit.com/lib/gadgets"
"go.wit.com/lib/gui/gowit"
"go.wit.com/lib/gui/repolist"
"go.wit.com/log"
"go.wit.com/gui"
)
type repoWindow struct {
win *gadgets.BasicWindow
box *gui.Node
View *repolist.RepoList
}
func (r *repoWindow) Hidden() bool {
return r.win.Hidden()
}
func (r *repoWindow) Show() {
r.win.Show()
}
func (r *repoWindow) Hide() {
r.win.Hide()
}
func (r *repoWindow) Disable() {
r.box.Disable()
}
func (r *repoWindow) Enable() {
r.box.Enable()
}
// you can only have one of these
func makeRepoView() *repoWindow {
if me.repos != nil {
return me.repos
}
r := new(repoWindow)
r.win = gadgets.RawBasicWindow("GUI repositories in ~/go/src/")
r.win.Make()
r.box = r.win.Box().NewBox("bw vbox", false)
r.win.Custom = func() {
log.Warn("GOT HERE: main() gadgets.NewBasicWindow() close")
log.Warn("Should I do something special here?")
}
// reposbox.SetExpand(false)
group1 := r.box.NewGroup("Run on all repos:")
hbox := group1.Box()
// hbox.Horizontal()
hbox.Vertical()
box2 := hbox.Box().Vertical()
box2.NewButton("Dump version file", func() {
gowit.DumpVersions(me.repos.View)
})
r.View = repolist.GuireleaserView(r.box)
showncount := r.View.MirrorShownCount()
box2.Append(showncount)
duration := r.View.MirrorScanDuration()
box2.Append(duration)
return r
}

View File

@ -1 +0,0 @@
* you can put toolkit .so binaries here

78
setTargetVersion.go Normal file
View File

@ -0,0 +1,78 @@
package main
import (
"os"
"strings"
"go.wit.com/log"
)
func setTargetVersion() {
// go through and set the target versions for each repo
// todo: add sanity checking in repolist to verify these and/or autocompute them
// for now, just don't be stupid when you set your ENV vars
// widget I versioned early before I knew what the hell this would mean and can
// not be down versioned because that's not how GO versioning works. Once you
// set the version for a path, it's set in stone forever. (smart system!)
// we could rename go.wit.com/widget to go.wit.com/newwidget and restart the versioning
// system, but that's rediculous and this servers to always remind me to never make this mistake again
var count int
loop := me.repos.View.ReposSortByName()
for loop.Scan() {
repo := loop.Repo()
if repo == nil {
log.Info("initial scan repo = nil")
continue
}
if repo.Status == nil {
log.Info("repo.status == nil", repo.Name())
continue
}
if repo.GoPath() == "go.wit.com/widget" {
repo.Status.SetTargetVersion("v" + os.Getenv("GUIRELEASE_WIDGET"))
} else {
prefix := "v" + os.Getenv("GUIRELEASE_VERSION")
lasttag := repo.Status.LastTag()
if strings.HasPrefix(lasttag, prefix) {
repo.Status.SetTargetVersion(lasttag)
} else {
repo.Status.SetTargetVersion(prefix)
}
}
if strings.HasPrefix(repo.GoPath(), "go.wit.com/dev/") {
lasttag := repo.Status.GetLastTagVersion()
repo.Status.SetTargetVersion(lasttag)
}
// repo.NewScan()
count += 1
}
log.Info("target versions set for", count, "repos")
}
// trys to figure out if the version needs to be incremented
func incrementTargetVersion() bool {
var count int
loop := me.repos.View.ReposSortByName()
for loop.Scan() {
repo := loop.Repo()
if repo.ReadOnly() {
continue
}
lasttag := repo.Status.GetLastTagVersion()
master := repo.Status.GetMasterVersion()
if lasttag != master {
log.Info("increment target version", repo.GoPath(), lasttag, master)
count += 1
} else {
// check go dependancies for target version changes
}
}
log.Info("need to update target versions for", count, "repos")
if count == 0 {
return true
}
return false
}

View File

@ -2,39 +2,58 @@
package main package main
import ( import (
"go.wit.com/dev/alexflint/arg"
"go.wit.com/gui" "go.wit.com/gui"
"go.wit.com/lib/gadgets" "go.wit.com/lib/gadgets"
"go.wit.com/lib/gui/prep" "go.wit.com/lib/gui/repolist"
"go.wit.com/lib/protobuf/forgepb" "go.wit.com/lib/protobuf/forgepb"
"go.wit.com/lib/protobuf/gitpb" "go.wit.com/lib/protobuf/zoopb"
) )
var me *autoType var me *autoType
type autoType struct { type autoType struct {
pp *arg.Parser // for parsing the command line args. Yay to alexf lint! myGui *gui.Node
myGui *prep.GuiPrep // the gui handle itself
releaseReasonS string // = "gocui dropdown select"
release releaseStruct // notsure
reposbox *gui.Node // notsure
reposgrid *gui.Node // notsure
reposgroup *gui.Node // notsure
current *gitpb.Repo // tracks the next repo to publish
found *gitpb.Repos // stores the list of repos to process things on
done []string // gopaths for repos already published
reason map[*gitpb.Repo]string // the reason this package is going to be updated
// this is the repo we are starting in releaseReasonS string // = "gocui dropdown select"
// make sure it never changes so go.mod and go.sum are always there release releaseStruct
// 'go get' is called from here reposbox *gui.Node
startRepo *gitpb.Repo reposgrid *gui.Node
reposgroup *gui.Node
current *repolist.RepoRow
// guireleaser window // guireleaser window
mainWindow *gadgets.BasicWindow mainWindow *gui.Node
mainBox *gui.Node mainBox *gui.Node
forge *forgepb.Forge // your customized repo preferences and settings // our view of the repositories
repos *repoWindow
// your customized repo preferences and settings
forge forgepb.Repos
// use zookeeper to get the list of installed packages
machine zoopb.Machine
// #### autotypist Global Build Options
// what to change all the branches to
// so, as a developer, you can move all the repos
// to the 'devel' branch and then test a devel branch build
// then switch back to your 'username' branch and do a build there
// toMoveToBranch string
// displays the preferred names used for the repo tree state
// mainBranch *gadgets.BasicCombobox
// develBranch *gadgets.BasicCombobox
// userBranch *gadgets.BasicCombobox
// this button will regenerate everyones go.mod & go.sum
rerunGoMod *gui.Node
// if checked, will stop trying to os.Exec() things after failure
stopOnErrors *gui.Node
// button to attempt to autorebuild
autoRebuildButton *gui.Node
// checkbox for --dry-run // checkbox for --dry-run
autoDryRun *gui.Node autoDryRun *gui.Node
@ -45,6 +64,9 @@ type autoType struct {
// The current working directory // The current working directory
autoWorkingPwd *gadgets.OneLiner autoWorkingPwd *gadgets.OneLiner
// shows what is being used as your home dir
userHomePwd *gadgets.OneLiner
// shows what directory being used as ~/go/src // shows what directory being used as ~/go/src
goSrcPwd *gadgets.OneLiner goSrcPwd *gadgets.OneLiner
@ -60,3 +82,9 @@ type autoType struct {
// show the time it took to do a scan // show the time it took to do a scan
duration *gui.Node duration *gui.Node
} }
/*
func (my *autoType) GoSrcPath() string {
return my.goSrcPwd.String()
}
*/

46
tempView.go Normal file
View File

@ -0,0 +1,46 @@
package main
import (
"go.wit.com/lib/gadgets"
"go.wit.com/lib/gui/repolist"
"go.wit.com/log"
)
func makeTempView() *repoWindow {
r := new(repoWindow)
r.win = gadgets.RawBasicWindow("unmerged repositories")
r.win.Make()
r.box = r.win.Box().NewBox("bw vbox", false)
r.win.Custom = func() {
log.Warn("GOT HERE: makeTempView() close")
log.Warn("GOT HERE: makeTempView() close")
log.Warn("Should I do something special here?")
}
// reposbox.SetExpand(false)
group1 := r.box.NewGroup("Run on all repos:")
hbox := group1.Box()
// hbox.Horizontal()
hbox.Vertical()
box2 := hbox.Box().Vertical()
box2.NewButton("merge user to devel", func() {
log.Warn("todo")
})
box2.NewButton("merge devel to master", func() {
log.Warn("todo")
})
box2.NewButton("rescan values", func() {
log.Warn("figure this out")
r.View.ListRows()
// for _, repo := range r.View.AllRepos() {
// log.Warn("repo:", repo.Name())
// }
})
r.View = repolist.TempWindowView(r.box)
r.Show()
return r
}