argv logic handling was bungled

Signed-off-by: Jeff Carr <jcarr@wit.com>
This commit is contained in:
Jeff Carr 2024-11-15 13:25:52 -06:00
parent 28bf6a27f9
commit 2d84244036
3 changed files with 93 additions and 56 deletions

View File

@ -8,10 +8,16 @@ this tool was written. gohack has a good justification for this kind of tool.
## go-glone itself ## go-glone itself
This will make a work directory and download everything needs to compile go-clone. This will download the sources for go-clone:
go-clone go.wit.com/apps/go-clone go-clone go.wit.com/apps/go-clone
go-clone works in ~/go/src unless it finds a go.work file in a parent dir
If you are using a go.work file, this will autocreate one. The old
one is saved as go.work.last
go-clone --auto-work go.wit.com/apps/go-clone
Or to recursively clone all the build dependancies: Or to recursively clone all the build dependancies:
go-clone --recursive go.wit.com/apps/go-clone go-clone --recursive go.wit.com/apps/go-clone
@ -25,7 +31,7 @@ Or to recursively clone all the build dependancies:
* use protobuf * use protobuf
* move edge case mappings to a config file * move edge case mappings to a config file
## Gohack: mutable checkouts of Go module dependencies ## these are notes from Gohack: mutable checkouts of Go module dependencies
The new Go module system is awesome. It ensures repeatable, deterministic The new Go module system is awesome. It ensures repeatable, deterministic
builds of Go code. External module code is cached locally in a read-only builds of Go code. External module code is cached locally in a read-only

14
argv.go
View File

@ -11,22 +11,26 @@ var argv args
type args struct { type args struct {
Repo string `arg:"positional" help:"go import path"` Repo string `arg:"positional" help:"go import path"`
AutoWork bool `arg:"--auto-work" default:"false" help:"auto recreate the go.work file"` AutoWork bool `arg:"--auto-work" default:"false" help:"auto recreate the go.work file"`
GoSrc bool `arg:"--go-src" default:"true" help:"only work in ~/go/src"`
DryRun bool `arg:"--dry-run" help:"show what would be run"` DryRun bool `arg:"--dry-run" help:"show what would be run"`
Recursive bool `arg:"--recursive" default:"false" help:"resursively clone all dependencies"` 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"` Pull bool `arg:"--git-pull" default:"false" help:"run 'git pull' on all your repos"`
RedoGoMod bool `arg:"--go-reset" default:"false" help:"remake all the go.sum and go.mod files"`
// Fetch bool `arg:"--git-fetch" default:"false" help:"run 'git fetch' on all your repos"` // Fetch bool `arg:"--git-fetch" default:"false" help:"run 'git fetch' on all your repos"`
} }
func (a args) Description() string { func (a args) Description() string {
return ` return `
By default, go-clone will find your go.work file and work from there. go-clone does git clone on go package repositories.
Otherwise, it will create a work/ directory. It uses ~/go/src unless it finds a go.work file in a parent directory.
This will clone the sources into ~/go/src/ for go-clone: This will clone the sources for go-clone:
go-clone go.wit.com/apps/go-clone go-clone go.wit.com/apps/go-clone
This will recursively clone the app and all the build requirements: If a go.work file is found, this will auto generate a new go.work file.
The old work file is saved as go.work.last
go-clone --auto-work go.wit.com/apps/go-clone
This will recursively clone a package and all the build requirements:
go-clone --recursive go.wit.com/apps/go-clone go-clone --recursive go.wit.com/apps/go-clone
` `
} }

113
main.go
View File

@ -29,7 +29,7 @@ func main() {
os.Exit(0) os.Exit(0)
} }
// figures out where you're go.work file is // use ~/go/src unless we find a go.work file in a parent directory
wdir, err := findWorkFile() wdir, err := findWorkFile()
if err != nil { if err != nil {
log.Info(err) log.Info(err)
@ -40,22 +40,70 @@ func main() {
} }
if argv.Repo == "" {
// if there isn't anything else, just exit here
// if --git-pull, continue
if argv.Pull || argv.RedoGoMod {
// there is more to do
log.Info("onward and upward")
} else {
// user needs to pick something to do
pp.WriteHelp(os.Stdout)
log.Info("give me something to do!")
os.Exit(0)
}
} else {
// the user specified a repo, check if it's already cloned
fullgitdir := filepath.Join(wdir, argv.Repo, ".git") fullgitdir := filepath.Join(wdir, argv.Repo, ".git")
if shell.IsDir(fullgitdir) { if shell.IsDir(fullgitdir) {
if ! argv.Recursive { // if --recursive, continue
// if --git-pull, continue
if argv.Recursive || argv.Pull || argv.RedoGoMod {
log.Info("repo already cloned", filepath.Join(wdir, argv.Repo))
// there is more to do
log.Info("onward and upward")
} else {
log.Info("repo already cloned", filepath.Join(wdir, argv.Repo)) log.Info("repo already cloned", filepath.Join(wdir, argv.Repo))
os.Exit(0) os.Exit(0)
} }
} else {
// need to download this new repo!
log.Info("repo is new. going to clone it to:", filepath.Join(wdir, argv.Repo))
}
} }
// readControlFile() // sets up gui stuff. not working yet
b := gui.RawBox() b := gui.RawBox()
rv = repolist.AutotypistView(b) rv = repolist.AutotypistView(b)
// if the user defined a repo, attempt to download it now
if argv.Repo != "" {
os.Setenv("REPO_AUTO_CLONE", "true")
newr, err := rv.NewRepo(argv.Repo)
if err != nil {
log.Info("could not download:", err)
os.Exit(-1)
}
// update go.sum and go.mod
// todo: only do this if they don't exist?
// todo: make these git commit metadata
newr.Status.MakeRedomod()
// double check it actually downloaded
fullgitdir := filepath.Join(wdir, argv.Repo, ".git")
if !shell.IsDir(fullgitdir) {
log.Info("repo cloned failed", filepath.Join(wdir, argv.Repo))
os.Exit(-1)
}
}
// look recursively in your working directory for git repos
totalcount := scanForRepos(wdir)
// if --git-pull, run git pull on everything here
if argv.Pull { if argv.Pull {
count := scanForRepos(wdir) log.Info("Total repositories:", totalcount)
log.Info("Total repositories:", count)
log.Info("Going to run git pull in each one") log.Info("Going to run git pull in each one")
log.Sleep(1) log.Sleep(1)
pull := []string{"git", "pull"} pull := []string{"git", "pull"}
@ -75,64 +123,40 @@ func main() {
} }
} }
} }
log.Info("Total repositories:", count, "Total attempted:", trycount, "Errors:", errcount) log.Info("Total repositories:", totalcount, "Total attempted:", trycount, "Errors:", errcount)
os.Exit(0) os.Exit(0)
} }
// if the user didn't provide a repo, stop here unless --git-pull // this is experiemental but works for me
if argv.Repo == "" || argv.Pull {
pp.WriteHelp(os.Stdout)
os.Exit(0)
}
os.Setenv("REPO_AUTO_CLONE", "true")
newr, err := rv.NewRepo(argv.Repo)
if err != nil {
log.Info("could not download:", err)
os.Exit(-1)
}
newr.Status.MakeRedomod()
fullgitdir = filepath.Join(wdir, argv.Repo, ".git")
if ! shell.IsDir(fullgitdir) {
log.Info("repo cloned failed", filepath.Join(wdir, argv.Repo))
os.Exit(-1)
}
log.Info("scanning for repo in:", filepath.Join(wdir, argv.Repo))
// rv.NewRepo("go.wit.com/apps/helloworld")
for _, path := range repostatus.ScanGitDirectories(wdir) {
gopath := strings.TrimPrefix(path, wdir)
gopath = strings.Trim(gopath, "/")
// log.Info("Also should add:", gopath)
rv.NewRepo(gopath)
}
godep := newr.Status.GetGoDeps()
if argv.Recursive { if argv.Recursive {
newr := rv.FindRepoByName(argv.Repo)
if newr == nil {
log.Info("how did this repo still not exist?", argv.Repo)
os.Exit(-1)
}
godep := newr.Status.GetGoDeps()
for gopath, version := range godep { for gopath, version := range godep {
repo, err := rv.NewRepo(gopath) repo, err := rv.NewRepo(gopath)
if err != nil { if err != nil {
log.Info("git clone failed for", gopath, version) log.Info("git clone failed for", gopath, version)
continue continue
} }
// always do this for now. probably always forever
repo.Status.MakeRedomod() repo.Status.MakeRedomod()
} }
} }
var count int // remake all the go.sum & go.mod in every repo
// todo: make go.sum and go.mod git commit metadata
if argv.RedoGoMod {
loop := rv.ReposSortByName() loop := rv.ReposSortByName()
for loop.Scan() { for loop.Scan() {
repo := loop.Repo() repo := loop.Repo()
count += 1
if !repo.Status.Exists("go.mod") {
repo.Status.MakeRedomod() repo.Status.MakeRedomod()
} }
} }
log.Info("Total repositories:", count) // remake the go.work file
log.Info("Finished go-clone for", argv.Repo)
if argv.AutoWork { if argv.AutoWork {
log.Info("About to re-create", wdir+"/go.work") log.Info("About to re-create", wdir+"/go.work")
log.Info("Sleep 3. original go.work saved as go.work.last (hit ctrl-c to cancel)") log.Info("Sleep 3. original go.work saved as go.work.last (hit ctrl-c to cancel)")
@ -144,6 +168,9 @@ func main() {
log.Info("original go.work file saved as go.work.last") log.Info("original go.work file saved as go.work.last")
log.Info("") log.Info("")
} }
log.Info("Total repositories:", totalcount)
log.Info("Finished go-clone for", argv.Repo)
} }
// look for a go.work file // look for a go.work file