diff --git a/README.md b/README.md index a32d26d..4c168ff 100644 --- a/README.md +++ b/README.md @@ -8,10 +8,16 @@ this tool was written. gohack has a good justification for this kind of tool. ## 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 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: go-clone --recursive go.wit.com/apps/go-clone @@ -25,7 +31,7 @@ Or to recursively clone all the build dependancies: * use protobuf * 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 builds of Go code. External module code is cached locally in a read-only diff --git a/argv.go b/argv.go index 4c2aad3..8336d32 100644 --- a/argv.go +++ b/argv.go @@ -11,22 +11,26 @@ var argv args type args struct { Repo string `arg:"positional" help:"go import path"` 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"` 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"` + 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"` } func (a args) Description() string { return ` -By default, go-clone will find your go.work file and work from there. -Otherwise, it will create a work/ directory. +go-clone does git clone on go package repositories. +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 -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 ` } diff --git a/main.go b/main.go index 4329e0f..a3460dc 100644 --- a/main.go +++ b/main.go @@ -29,7 +29,7 @@ func main() { 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() if err != nil { log.Info(err) @@ -40,22 +40,70 @@ func main() { } - fullgitdir := filepath.Join(wdir, argv.Repo, ".git") - if shell.IsDir(fullgitdir) { - if ! argv.Recursive { - log.Info("repo already cloned", filepath.Join(wdir, argv.Repo)) + 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") + if shell.IsDir(fullgitdir) { + // 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)) + 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() 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 { - count := scanForRepos(wdir) - log.Info("Total repositories:", count) + log.Info("Total repositories:", totalcount) log.Info("Going to run git pull in each one") log.Sleep(1) 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) } - // if the user didn't provide a repo, stop here unless --git-pull - 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() + // this is experiemental but works for me 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 { repo, err := rv.NewRepo(gopath) if err != nil { log.Info("git clone failed for", gopath, version) continue } + // always do this for now. probably always forever repo.Status.MakeRedomod() } } - var count int - loop := rv.ReposSortByName() - for loop.Scan() { - repo := loop.Repo() - count += 1 - if !repo.Status.Exists("go.mod") { + // 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() + for loop.Scan() { + repo := loop.Repo() repo.Status.MakeRedomod() } } - log.Info("Total repositories:", count) - log.Info("Finished go-clone for", argv.Repo) + // remake the go.work file if argv.AutoWork { 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)") @@ -144,6 +168,9 @@ func main() { log.Info("original go.work file saved as go.work.last") log.Info("") } + + log.Info("Total repositories:", totalcount) + log.Info("Finished go-clone for", argv.Repo) } // look for a go.work file