all sorts of updates. it didn't work before!

This commit is contained in:
Jeff Carr 2024-12-15 08:31:42 -06:00
parent 5f1f19d9ca
commit 7cade75da8
4 changed files with 178 additions and 174 deletions

View File

@ -1,7 +1,7 @@
VERSION = $(shell git describe --tags)
BUILDTIME = $(shell date +%Y.%m.%d_%H%M)
run: goimports build
run: build
./go-clone --version
vet:
@ -22,7 +22,7 @@ build-windows:
GOOS=windows GOARCH=amd64 GO111MODULE=off go build -v go-clone.exe \
-ldflags "-X main.VERSION=${VERSION} -X main.BUILDTIME=${BUILDTIME} -X gui.GUIVERSION=${VERSION}"
install:
install: goimports
GO111MODULE=off go install \
-ldflags "-X main.VERSION=${VERSION} -X main.BUILDTIME=${BUILDTIME} -X gui.GUIVERSION=${VERSION}"

View File

@ -13,10 +13,9 @@ type args struct {
AutoWork bool `arg:"--work" default:"false" help:"recreate the go.work file"`
DryRun bool `arg:"--dry-run" help:"show what would be run"`
Recursive bool `arg:"--recursive" default:"false" help:"resursively clone all dependencies"`
Pull bool `arg:"--git-pull" default:"false" help:"run 'git pull' on all your repos"`
Build bool `arg:"--build" default:"true" help:"also try to build it"`
Install bool `arg:"--install" default:"false" help:"try to install every binary package"`
RedoGoMod bool `arg:"--go-reset" default:"false" help:"remake all the go.sum and go.mod files"`
Pull bool `arg:"--git-pull" default:"false" help:"run 'git pull'"`
Build bool `arg:"--build" default:"true" help:"try to build it after clone"`
Install bool `arg:"--install" default:"false" help:"try to install it after clone"`
// Fetch bool `arg:"--git-fetch" default:"false" help:"run 'git fetch' on all your repos"`
}

124
clone.go Normal file
View File

@ -0,0 +1,124 @@
package main
import (
"errors"
"os"
"path/filepath"
"go.wit.com/lib/gui/shell"
"go.wit.com/lib/protobuf/gitpb"
"go.wit.com/log"
)
func clone(gopath string) (*gitpb.Repo, error) {
// if the user defined a repo, attempt to download it now
if gopath == "" {
// nothing to clone
// user probably wants to --recursive on current working dir
return nil, errors.New("gopath was blank")
}
os.Setenv("REPO_AUTO_CLONE", "true")
// pb, _ := forge.NewGoPath(gopath)
check := forge.Repos.FindByGoPath(gopath)
if check != nil {
if check.IsValid() {
// repo already exists and is valid
return check, nil
}
}
pb, err := forge.Clone(gopath)
if err != nil {
log.Info("clone() could not download err:", err)
return nil, err
}
// first try to generate go.mod & go.sum with go-mod-clean
if err := pb.ValidGoSum(); err != nil {
// update go.sum and go.mod
if err := pb.RunStrict([]string{"go-mod-clean"}); err != nil {
log.Info("")
log.Info("Do you have go-mod-clean? Otherwise:")
log.Info(" go install go.wit.com/apps/go-mod-clean@latest")
log.Info("")
}
}
// if this fails, just use go mod
if err := pb.ValidGoSum(); err != nil {
if err := pb.RunStrict([]string{"go", "mod", "init", pb.GoPath}); err != nil {
log.Info("go mod init failed", err)
}
if err := pb.RunStrict([]string{"go", "mod", "tidy"}); err != nil {
log.Info("go mod tidy failed", err)
}
}
if err := pb.ValidGoSum(); err != nil {
// have to give up. can't recursive clone without go.mod file
log.Info("could not generate valid go.sum file")
return nil, err
}
pb.ParseGoSum()
// double check it actually downloaded
fullgitdir := filepath.Join(forge.GetGoSrc(), gopath, ".git")
if !shell.IsDir(fullgitdir) {
log.Info("repo cloned failed", filepath.Join(forge.GetGoSrc(), gopath))
return nil, errors.New(fullgitdir + " was not created")
}
log.Info("onward and upward")
return pb, nil
}
// really only does go.sum things
// so not 'really' recursive
// but that is because go.sum is supposed
// to have everything required in it
func recursiveClone(check *gitpb.Repo) error {
var good int
var bad int
if check == nil {
return errors.New("repo was nil")
}
log.Info("STARTING RECURSIVE CLONE", check.GoPath)
log.Info("STARTING RECURSIVE CLONE", check.GoPath)
if check.GoPrimitive {
log.Info("repo is a primitive", check.GoPath)
// go primitive repos are "pure"
return nil
}
// if just cloned, parse the go.sum file for deps
check.ParseGoSum()
if check.GoDeps == nil {
log.Info("repo godeps == nil", check.GoPath)
return errors.New("go.sum is missing?")
}
// probably this should never be 0 because GoPrimitive should have been true otherwise
if check.GoDeps.Len() == 0 {
log.Info("repo len(godeps) == 0", check.GoPath)
return errors.New("go.sum never parsed?")
}
log.Info("deps for", check.GoPath, "len()", check.GoDeps.Len())
deps := check.GoDeps.SortByGoPath()
for deps.Scan() {
depRepo := deps.Next()
log.Info("download:", depRepo.GoPath)
_, err := clone(depRepo.GoPath)
if err != nil {
log.Info("recursiveClone() could not download", depRepo.GoPath)
log.Info("err:", err)
bad += 1
} else {
log.Info("downloaded", depRepo.GoPath)
good += 1
}
}
log.Info("got", good, "repos", "failed on", bad, "repos")
if bad != 0 {
return errors.New("clone failed on some repos")
}
return nil
}

217
main.go
View File

@ -1,9 +1,7 @@
package main
import (
"errors"
"os"
"path/filepath"
"go.wit.com/dev/alexflint/arg"
"go.wit.com/lib/gui/shell"
@ -18,7 +16,8 @@ var BUILDTIME string
var pp *arg.Parser
var forge *forgepb.Forge
var argvRepo *gitpb.Repo
var workingRepo *gitpb.Repo
func main() {
log.Info("go-clone version", VERSION, "built on", BUILDTIME)
@ -34,73 +33,51 @@ func main() {
os.Exit(0)
}
// load the ~/.config/forge/ config
// this lets you configure repos you have read/write access too
// this package helps scan git repos
forge = forgepb.Init()
argvRepo = forge.Repos.FindByGoPath(argv.Repo)
if argvRepo == nil {
log.Info("yep, need to clone", argv.Repo)
} else {
log.Info("already have", argv.Repo)
if argv.Recursive {
clone()
recursiveClone()
}
autoWork()
build()
okExit(argv.Repo)
var err error
// attempt to clone, returns *gitpb.Repo
workingRepo, err = clone(argv.Repo)
if err != nil {
badExit(err)
}
// gui is in testing
// myGui := gui.New()
// myGui.Default()
// run 'git pull' if argv --git-pull
if argv.Pull {
gitPull()
okExit("git pull")
}
// remake all the go.sum & go.mod in every repo
// todo: make go.sum and go.mod git commit metadata
if argv.RedoGoMod {
// redoGoModAll()
}
// this works sometimes
if argv.Recursive {
clone()
recursiveClone()
autoWork()
build()
okExit("--recursive")
log.Info("STARTING RECURSIVE CLONE", workingRepo.GoPath)
if err := recursiveClone(workingRepo); err != nil {
badExit(err)
}
}
autoWork()
if argv.Build {
if err := build(); err != nil {
badExit(err)
}
}
if argv.Install {
// can only install binary or plugin go packages
if workingRepo.RepoType() == "binary" || workingRepo.RepoType() == "plugin" {
log.Info("install will probably fail", workingRepo.GoPath, "is", workingRepo.RepoType())
}
if err := forge.Install(workingRepo, nil); err != nil {
log.Warn("INSTALL FAILED", workingRepo.GoPath, err)
badExit(err)
}
}
clone()
autoWork()
if argv.Install {
if err := forge.Install(argvRepo, nil); err == nil {
okExit("install worked")
} else {
badExit(err)
}
if argv.Pull {
// run 'git pull' if argv --git-pull
gitPull()
}
if argv.Build {
if err := forge.Build(argvRepo, nil); err == nil {
okExit("build worked")
argvRepo.RunEcho([]string{"ls", "-l"})
} else {
argvRepo.RunEcho([]string{"ls", "-l"})
badExit(err)
}
}
okExit("skipping build of " + argv.Repo)
okExit("")
}
func okExit(thing string) {
log.Info(thing, "ok")
log.Info("Finished clone on", argvRepo.GetGoPath(), "ok")
if thing != "" {
log.Info(thing, "ok")
}
log.Info("Finished clone on", workingRepo.GetGoPath(), "ok")
forge.ConfigSave()
os.Exit(0)
}
@ -110,56 +87,9 @@ func badExit(err error) {
os.Exit(-1)
}
func clone() {
// if the user defined a repo, attempt to download it now
if argv.Repo != "" {
os.Setenv("REPO_AUTO_CLONE", "true")
// pb, _ := forge.NewGoPath(argv.Repo)
check := forge.Repos.FindByGoPath(argv.Repo)
if check != nil {
return
}
pb, err := forge.Clone(argv.Repo)
if err != nil {
log.Info("clone() could not download err:", err)
badExit(err)
}
if err := pb.ValidGoSum(); err != nil {
// update go.sum and go.mod
if err := pb.RunStrict([]string{"go-mod-clean"}); err != nil {
log.Info("")
log.Info("Do you have go-mod-clean? Otherwise:")
log.Info(" go install go.wit.com/apps/go-mod-clean@latest")
log.Info("")
badExit(err)
}
}
if err := pb.ValidGoSum(); err != nil {
log.Info("could not generate valid go.sum file")
badExit(err)
}
// double check it actually downloaded
fullgitdir := filepath.Join(forge.GetGoSrc(), argv.Repo, ".git")
if !shell.IsDir(fullgitdir) {
log.Info("repo cloned failed", filepath.Join(forge.GetGoSrc(), argv.Repo))
badExit(errors.New(fullgitdir + " was not created"))
}
build()
// exit unless other --argv options are set
if !(argv.Recursive || argv.Pull || argv.RedoGoMod) {
log.Info("repo cloned worked to", filepath.Join(forge.GetGoSrc(), argv.Repo))
okExit(argv.Repo)
}
log.Info("onward and upward")
}
}
func gitPull() {
log.Info("Total repositories:", forge.Repos.Len())
log.Info("Going to run git pull in each one. TODO: use rill here")
log.Sleep(1)
pull := []string{"git", "pull"}
var trycount, errcount int
@ -181,75 +111,26 @@ func gitPull() {
log.Info("Total repositories:", forge.Repos.Len(), "Total attempted:", trycount, "Errors:", errcount)
}
// really only does go.sum things
// so not 'really' recursive
// but that is because go.sum is supposed
// to have everything required in it
func recursiveClone() {
var good int
var bad int
// this works sometimes
if argv.Recursive {
check := forge.Repos.FindByGoPath(argv.Repo)
log.Info("download deps for:", check.GoPath)
deps := check.GoDeps.SortByGoPath()
for deps.Scan() {
depRepo := deps.Next()
log.Info("download:", depRepo.GoPath)
_, err := forge.Clone(depRepo.GoPath)
if err != nil {
log.Info("recursiveClone() could not download", depRepo.GoPath)
log.Info("err:", err)
bad += 1
} else {
log.Info("downloaded", depRepo.GoPath)
good += 1
}
}
}
log.Info("got", good, "repos", "failed on", bad, "repos")
}
func build() error {
forge.RillRedoGoMod()
repos := forge.Repos.SortByGoPath()
for repos.Scan() {
repo := repos.Next()
log.Info("go.work repo (hopefully):", repo.GoPath, repo.FullPath, repo.RepoType())
err := forge.Build(workingRepo, nil)
pwd, _ := os.Getwd()
if err == nil {
log.Info("this totally worked", pwd)
shell.RunEcho([]string{"ls", "-l"})
log.Info("ran ls")
} else {
log.Info("this totally did not work", pwd)
shell.RunEcho([]string{"ls", "-l"})
log.Info("ran ls")
badExit(err)
}
if argv.Install {
if err := forge.Install(argvRepo, nil); err == nil {
okExit("install worked")
} else {
badExit(err)
}
}
if argv.Build {
err := forge.Build(argvRepo, nil)
pwd, _ := os.Getwd()
if err == nil {
log.Info("this totally worked", pwd)
shell.RunEcho([]string{"ls", "-l"})
log.Info("ran ls")
} else {
log.Info("this totally did not work", pwd)
shell.RunEcho([]string{"ls", "-l"})
log.Info("ran ls")
}
return err
}
log.Info("skipping build")
return nil
return err
}
func autoWork() {
// remake the go.work file
if argv.AutoWork {
log.Info("About to re-create", forge.GetGoSrc()+"/go.work")
log.Info("Sleep 3. original go.work saved as go.work.last (hit ctrl-c to cancel)")
log.Sleep(3)
shell.PathRun(forge.GetGoSrc(), []string{"mv", "go.work", "go.work.last"})
forge.MakeGoWork()
shell.PathRun(forge.GetGoSrc(), []string{"go", "work", "use"})