diff --git a/common.go b/common.go index 4e52032..c6d8995 100644 --- a/common.go +++ b/common.go @@ -87,7 +87,7 @@ func (rs *RepoStatus) IsProtobuf() (bool, []string, error) { if found { // log.Info("found ok") } else { - log.Info("missing compiled proto file:", pname + "pb.go") + log.Info("missing compiled proto file:", pname+"pb.go") err = errors.New("compiled file " + pname + ".pb.go missing") } } @@ -155,7 +155,7 @@ func (rs *RepoStatus) IsGoLang() bool { return false } -// experiment to go package type +// experiment to determine the golang package type func (rs *RepoStatus) RepoType() string { if !rs.IsGoLang() { return "" @@ -164,14 +164,12 @@ func (rs *RepoStatus) RepoType() string { return "" } os.Setenv("GO111MODULE", "off") - err, output := rs.RunCmd([]string{"go", "list", "-f", "'{{if eq .Name \"main\"}}binary{{else}}library{{end}}'"}) - if err == nil { - output = strings.Trim(output, "'") - // log.Info("go package is:", output) - return output + r := rs.Run([]string{"go", "list", "-f", "'{{if eq .Name \"main\"}}binary{{else}}library{{end}}'"}) + output := strings.TrimSpace(strings.Join(r.Stdout, "\n")) + if r.Error != nil { + log.Info("go package error:", r.Error) } - // log.Info("package is: unknown", err) - return "" + return output } func (rs *RepoStatus) BinaryName() string { @@ -188,7 +186,7 @@ func (rs *RepoStatus) Build() bool { } name := rs.BinaryName() // removes the binary if it already exists - rs.RunCmd([]string{"rm", "-f", name}) + rs.Run([]string{"rm", "-f", name}) if rs.Exists(name) { log.Warn("file could not be removed filename =", name) return false diff --git a/git.go b/git.go index e712e4d..a921ef2 100644 --- a/git.go +++ b/git.go @@ -50,17 +50,18 @@ func (rs *RepoStatus) GitPull() (string, error) { } var cmd []string cmd = append(cmd, "git", "pull") - err, output := rs.RunCmd(cmd) - if err != nil { + r := rs.Run(cmd) + output := strings.Join(r.Stdout, "\n") + if r.Error != nil { output = "git error_,,,_a_,,,_b_,,,c" } - if err == nil { + if r.Error == nil { log.Log(REPOWARN, "git pull ran", rs.Path()) log.Log(REPOWARN, "git pull output", output) } else { - log.Log(REPOWARN, "git pull error", rs.Path(), err) + log.Log(REPOWARN, "git pull error", rs.Path(), r.Error) } - return output, err + return output, r.Error } /* @@ -94,13 +95,13 @@ func (rs *RepoStatus) gitDescribeByHash(hash string) (string, error) { if hash == "" { return "", errors.New("hash was blank") } - err, out := rs.RunCmd([]string{"git", "describe", "--tags", "--always", hash}) - if err != nil { - log.Warn("not in a git repo or bad hash?", err, rs.Path()) - return "", err + r := rs.Run([]string{"git", "describe", "--tags", "--always", hash}) + out := strings.Join(r.Stdout, "\n") + if r.Error != nil { + log.Warn("not in a git repo or bad hash?", r.Error, rs.Path()) + return out, r.Error } - out = strings.TrimSpace(out) - return out, err + return out, r.Error } func (rs *RepoStatus) gitDescribeByName(name string) (string, error) { @@ -108,28 +109,27 @@ func (rs *RepoStatus) gitDescribeByName(name string) (string, error) { if name == "" { // git will return the current tag - err, out := rs.RunCmd([]string{"git", "describe", "--tags", "--always"}) - if err != nil { - log.Warn("not in a git repo?", err, rs.Path()) - return "", err + r := rs.Run([]string{"git", "describe", "--tags", "--always"}) + output := strings.Join(r.Stdout, "\n") + if r.Error != nil { + log.Warn("gitDescribeByName() not in a git repo?", r.Error, rs.Path()) } - out = strings.TrimSpace(out) - return out, err + return strings.TrimSpace(output), r.Error } if !rs.LocalTagExists(name) { // tag does not exist - return "", errors.New("git fatal: Not a valid object name") + return "", errors.New("gitDescribeByName() git fatal: Not a valid object name") } cmd := []string{"git", "describe", "--tags", "--always", name} - err, out := rs.RunCmd(cmd) - if err != nil { + r := rs.Run(cmd) + output := strings.Join(r.Stdout, "\n") + if r.Error != nil { log.Warn("cmd =", cmd) - log.Warn("err =", err) + log.Warn("err =", r.Error) log.Warn("not in a git repo or bad tag?", rs.Path()) - return "", err } - out = strings.TrimSpace(out) - return out, err + + return strings.TrimSpace(output), r.Error } // todo: don't run git every time? @@ -211,15 +211,16 @@ func (rs *RepoStatus) DirtyList() []string { func (rs *RepoStatus) CheckDirty() bool { var start string = rs.dirtyLabel.String() cmd := []string{"git", "status", "--porcelain"} - err, out := rs.RunCmd(cmd) - if err != nil { + r := rs.Run(cmd) + out := strings.Join(r.Stdout, "\n") + if r.Error != nil { log.Warn("CheckDirty() status cmd =", cmd) log.Warn("CheckDirty() status out =", out) - log.Warn("CheckDirty() status err =", err) - log.Error(err, "CheckDirty() git status error") + log.Warn("CheckDirty() status err =", r.Error) + log.Error(r.Error, "CheckDirty() git status error") rs.dirtyLabel.SetValue("error") if start != "error" { - rs.NoteChange("git status is in error " + fmt.Sprint(err)) + rs.NoteChange("git status is in error " + fmt.Sprint(r.Error)) } return true } @@ -272,9 +273,9 @@ func (rs *RepoStatus) CheckoutBranch(bname string) bool { return true } cmd := []string{"git", "checkout", bname} - err, b, output := RunCmd(rs.realPath.String(), cmd) - if err != nil { - log.Log(REPO, err, b, output) + r := rs.Run(cmd) + if r.Error != nil { + log.Log(REPO, "git checkout error:", r.Error) return false } rs.checkCurrentBranchName() @@ -325,9 +326,9 @@ func (rs *RepoStatus) CheckoutUser() bool { return false } cmd := []string{"git", "checkout", bName} - err, b, output := RunCmd(rs.realPath.String(), cmd) - if err != nil { - log.Log(REPO, err, b, output) + r := rs.Run(cmd) + if r.Error != nil { + log.Log(REPO, "git checkout error:", r.Error) } realname := rs.GetCurrentBranchName() @@ -570,14 +571,14 @@ func (rs *RepoStatus) CheckBranches() bool { } var cmd []string cmd = append(cmd, "git", "show", "-s", "--format=%ci", hash) - err, output := rs.RunCmd(cmd) - if err != nil { - // log.Log(WARN, "cmd failed", cmd, "err =", err, "in", rs.String()) + r := rs.Run(cmd) + if r.Error != nil { + log.Log(WARN, "CheckBranches() git show error:", r.Error) } // git show -s --format=%ci will give you the time // log.Log(REPO, fullfile) if hash == hashCheck { - log.Log(REPO, hash, output, b) + log.Log(REPO, "notsure why this git show is here", hash) } else { // log.Log(WARN, rs.String(), hash, output, b) // log.Log(WARN, "UNKNOWN BRANCHES IN THIS REPO", cmd) diff --git a/gitConfig.go b/gitConfig.go index b2c2af9..029c473 100644 --- a/gitConfig.go +++ b/gitConfig.go @@ -11,6 +11,7 @@ import ( // GitConfig represents the parsed .git/config data // type GitConfig map[string]map[string]string +// TODO: switch to protobuf type remote struct { url string @@ -220,21 +221,16 @@ func (rs *RepoStatus) GitURL() string { } func (rs *RepoStatus) GitLsFiles() (bool, string) { - err, output := rs.RunCmd([]string{"git", "ls-files"}) - if err != nil { - log.Warn("git ls-files failed err =", err) + r := rs.Run([]string{"git", "ls-files"}) + output := strings.Join(r.Stdout, "\n") + if r.Error != nil { + log.Warn("git ls-files failed err =", r.Error) log.Warn("git ls-files failed output =", output) return false, output } return true, output } -/* -func (rs *RepoStatus) Writable() { - rs.readOnly.SetText("false") -} -*/ - func (rs *RepoStatus) ReadOnly() bool { if rs.readOnly.String() == "true" { return true diff --git a/goConfig.go b/goConfig.go index ffba25e..63562a2 100644 --- a/goConfig.go +++ b/goConfig.go @@ -106,13 +106,25 @@ func (rs *RepoStatus) GoConfig() map[string]string { return rs.goConfig } +// for now, even check cmd.Exit +func (rs *RepoStatus) strictRun(cmd []string) (bool, error) { + r := rs.Run(cmd) + if r.Error != nil { + log.Log(REPO, "go mod init failed err:", r.Error) + return false, r.Error + } + if r.Exit != 0 { + log.Log(REPO, "go mod init exit =", r.Exit) + return false, r.Error + } + return true, nil +} + // poor name perhaps. It's because in most of these // repos you can also type "make redomod" to do the same thing // since it's a Makefile task that is also useful to be able to run // from the command line func (rs *RepoStatus) MakeRedomod() (bool, error) { - var err error - var output string if rs.ReadOnly() { log.Log(REPO, "will not go mod redo read only repos", rs.String()) return false, errors.New(rs.GoPath() + " is read-only ") @@ -120,20 +132,17 @@ func (rs *RepoStatus) MakeRedomod() (bool, error) { // unset the go development ENV var to generate release files os.Unsetenv("GO111MODULE") - err, output = rs.RunCmd([]string{"rm", "-f", "go.mod", "go.sum"}) - if err != nil { - log.Log(REPO, "rm go.mod go.sum failed", err, output) - return false, err + if ok, err := rs.strictRun([]string{"rm", "-f", "go.mod", "go.sum"}); !ok { + log.Log(REPO, "rm go.mod go.sum failed", err) + return ok, err } - err, output = rs.RunCmd([]string{"go", "mod", "init", rs.GoPath()}) - if err != nil { - log.Log(REPO, "go mod init failed", err, output) - return false, err + if ok, err := rs.strictRun([]string{"go", "mod", "init", rs.GoPath()}); !ok { + log.Log(REPO, "go mod init failed", err) + return ok, err } - err, output = rs.RunCmd([]string{"go", "mod", "tidy"}) - if err != nil { - log.Log(REPO, "go mod tidy failed", err, output) - return false, err + if ok, err := rs.strictRun([]string{"go", "mod", "tidy"}); !ok { + log.Log(REPO, "go mod tidy failed", err) + return ok, err } log.Log(REPO, "MakeRedomod() worked", rs.GoPath()) @@ -156,7 +165,7 @@ func (rs *RepoStatus) MakeRedomod() (bool, error) { return true, nil } // this should never happen - return false, nil + return false, errors.New("MakeRedomod() logic failed") } func (rs *RepoStatus) IsReleased() bool { diff --git a/goList.go b/goList.go index 96ce6f5..bc30e78 100644 --- a/goList.go +++ b/goList.go @@ -2,6 +2,7 @@ package repostatus import ( "encoding/json" + "strings" "time" "go.wit.com/lib/gui/shell" @@ -88,11 +89,12 @@ func runGoList(url string) (string, error) { if err != nil { return "", err } - r := shell.Output("", []string{"go", "list", "-json", "-m", url + "@" + ver}) + r := shell.Run([]string{"go", "list", "-json", "-m", url + "@" + ver}) var modInfo Module - err = json.Unmarshal(r.Output, &modInfo) + out := strings.Join(r.Stdout, "\n") + err = json.Unmarshal([]byte(out), &modInfo) if err != nil { - log.Info("runGoList() r.Output =", string(r.Output)) + log.Info("runGoList() r.Output =", out) log.Info("runGoList() json.Unmarshal() error =", err) return "", err } @@ -101,11 +103,12 @@ func runGoList(url string) (string, error) { } func getLatestVersion(url string) (string, error) { - r := shell.Output("", []string{"go", "list", "-json", "-m", url + "@latest"}) + r := shell.Run([]string{"go", "list", "-json", "-m", url + "@latest"}) var modInfo Module - err := json.Unmarshal(r.Output, &modInfo) + out := strings.Join(r.Stdout, "\n") + err := json.Unmarshal([]byte(out), &modInfo) if err != nil { - log.Info("runGoList() r.Output =", string(r.Output)) + log.Info("runGoList() r.Output =", out) log.Info("runGoList() json.Unmarshal() error =", err) return "", err } diff --git a/merge.go b/merge.go index 04b4336..2a37c08 100644 --- a/merge.go +++ b/merge.go @@ -30,34 +30,35 @@ func (rs *RepoStatus) ResetBranches() bool { func (rs *RepoStatus) FetchMaster() (error, string) { // log.Log(REPOWARN, "FetchMaster() start", rs.Name()) master := rs.GetMasterBranchName() - return rs.fetchBranch(master) + return rs.fetchBranchByName(master) } func (rs *RepoStatus) FetchDevel() (error, string) { devel := rs.GetDevelBranchName() - return rs.fetchBranch(devel) + return rs.fetchBranchByName(devel) } -// fetch the branch 'apple' -func (rs *RepoStatus) fetchBranch(apple string) (error, string) { +// fetch the branch by name +func (rs *RepoStatus) fetchBranchByName(bname string) (error, string) { if rs.GetCurrentBranchName() != rs.GetUserBranchName() { return errors.New("not in user branch"), "" } if rs.gitConfig == nil { return errors.New("missing .git/config"), "" } - log.Log(REPO, rs.Name(), "looking for branch:", apple) + log.Log(REPO, rs.Name(), "looking for branch:", bname) for name, branch := range rs.gitConfig.branches { - if name == apple { + if name == bname { // found the branch! log.Log(REPO, " ", name, "remote:", branch.remote, "merge", branch.merge) - cmd := []string{"git", "fetch", branch.remote, apple + ":" + apple} + cmd := []string{"git", "fetch", branch.remote, bname + ":" + bname} log.Log(REPO, "running:", rs.Name(), cmd) - err, out := rs.RunCmd(cmd) - return err, out + r := rs.Run(cmd) + output := strings.Join(r.Stdout, "\n") + return r.Error, strings.TrimSpace(output) } } - return errors.New("branch " + apple + " not found"), "" + return errors.New("branch " + bname + " not found"), "" } func (rs *RepoStatus) MergeUserToDevel() bool { @@ -383,21 +384,25 @@ func (rs *RepoStatus) generateCmd() bool { } func (rs *RepoStatus) runGitCommands(verbose bool) bool { - for _, line := range rs.versionCmds { + var line []string + for _, line = range rs.versionCmds { s := strings.Join(line, " ") if verbose { log.Log(WARN, "RUNNING:", s) } rs.develMergeB.SetText(s) - err, b, output := runCmd(rs.realPath.String(), line) - if err != nil { + r := rs.Run(line) + output := strings.TrimSpace(strings.Join(r.Stdout, "\n")) + if r.Error != nil { log.Warn("ABEND EXECUTION") - log.Warn("error =", err) + log.Warn("error =", r.Error) log.Warn("output =", output) return false } - log.Log(INFO, "Returned with b =", b) - log.Log(INFO, "output was =", output) + if r.Exit != 0 { + log.Warn("Returned with exit =", r.Exit) + log.Warn("output was =", output) + } log.Log(INFO, "RUN DONE") } return true diff --git a/new.go b/new.go index a819a4a..fd1afef 100644 --- a/new.go +++ b/new.go @@ -154,7 +154,7 @@ func Clone(wdir string, path string) error { path = "go.googlesource.com/xerrors" } - shell.RunPath(fulldir, []string{"git", "clone", "http://" + path}) + shell.PathRun(fulldir, []string{"git", "clone", "http://" + path}) if IsDirectory(fullpath) { // clone worked return nil @@ -166,7 +166,7 @@ func Clone(wdir string, path string) error { return err } log.Info("URL:", url) - shell.RunPath(fulldir, []string{"git", "clone", url, base}) + shell.PathRun(fulldir, []string{"git", "clone", url, base}) if IsDirectory(fullpath) { // clone worked return nil diff --git a/tagWindow.go b/tagWindow.go index 5f7c7f7..4f0efbc 100644 --- a/tagWindow.go +++ b/tagWindow.go @@ -1,6 +1,7 @@ package repostatus import ( + "errors" "path/filepath" "regexp" "slices" @@ -44,10 +45,10 @@ type GitTagBox struct { tags []*Tag } -func (rs *RepoStatus) makeTagBox(box *gui.Node) { +func (rs *RepoStatus) makeTagBox(box *gui.Node) error { if rs.Tags != nil { log.Log(WARN, "already scanned tags") - return + return errors.New("already scanned tags") } tagB := new(GitTagBox) rs.Tags = tagB @@ -98,12 +99,13 @@ func (rs *RepoStatus) makeTagBox(box *gui.Node) { format := strings.Join(tags, "_,,,_") cmd := []string{"git", "for-each-ref", "--sort=taggerdate", "--format", format} // log.Info("RUNNING:", strings.Join(cmd, " ")) - err, output := rs.RunCmd(cmd) - if err != nil { - output = "git error_,,,_a_,,,_b_,,,c" + r := rs.Run(cmd) + if r.Error != nil { + log.Warn("git for-each-ref error:", r.Error) + return r.Error } - lines := strings.Split(output, "\n") + lines := r.Stdout // reverse the git order slices.Reverse(lines) tagB.tags = make([]*Tag, 0) @@ -146,6 +148,7 @@ func (rs *RepoStatus) makeTagBox(box *gui.Node) { } // reverse the git order // slices.Reverse(rtags.tags) + return nil } func (rtags *GitTagBox) ListAll() []*Tag { @@ -246,18 +249,20 @@ func (rtags *GitTagBox) PruneSmart() { func (rs *RepoStatus) DeleteTag(rt *Tag) { cmd := []string{"git", "push", "--delete", "origin", rt.tag.String()} log.Info("RUN:", cmd) - err, output := rs.RunCmd(cmd) - if err != nil { - log.Info("cmd failed", err) + r := rs.Run(cmd) + output := strings.Join(r.Stdout, "\n") + if r.Error != nil { + log.Info("cmd failed", r.Error) log.Info("output:", output) } log.Info("output:", output) cmd = []string{"git", "tag", "--delete", rt.tag.String()} log.Info("RUN:", cmd) - err, output = rs.RunCmd(cmd) - if err != nil { - log.Info("cmd failed", err) + r = rs.Run(cmd) + output = strings.Join(r.Stdout, "\n") + if r.Error != nil { + log.Info("cmd failed", r.Error) log.Info("output:", output) } log.Info("output:", output) diff --git a/unix.go b/unix.go index 19872a6..97f560e 100644 --- a/unix.go +++ b/unix.go @@ -1,7 +1,6 @@ package repostatus import ( - "errors" "fmt" "io/ioutil" "os" @@ -12,6 +11,7 @@ import ( "strings" "time" + "github.com/go-cmd/cmd" "go.wit.com/lib/gui/shell" "go.wit.com/log" ) @@ -117,88 +117,16 @@ func splitVersion(version string) (a, b, c string) { } } -func (rs *RepoStatus) RunCmdEcho(parts []string) (error, string) { - log.Info("RunCmdEcho()", parts) - return rs.RunCmd(parts) -} - -func (rs *RepoStatus) RunCmd(parts []string) (error, string) { +func (rs *RepoStatus) Run(cmd []string) cmd.Status { path := rs.realPath.String() - err, _, output := shell.RunCmd(path, parts) - if err != nil { - log.Log(WARN, "cmd:", parts) + r := shell.PathRun(path, cmd) + output := strings.Join(r.Stdout, "\n") + if r.Error != nil { + log.Log(WARN, "cmd:", cmd) log.Log(WARN, "ouptput:", output) - log.Log(WARN, "failed with error:", err) + log.Log(WARN, "failed with error:", r.Error) } - return err, output -} - -// temp hack. fix this -func runCmd(path string, parts []string) (error, bool, string) { - return shell.RunCmd(path, parts) -} - -func RunCmd(workingpath string, parts []string) (error, bool, string) { - if len(parts) == 0 { - log.Warn("command line was empty") - return errors.New("empty"), false, "" - } - if parts[0] == "" { - log.Warn("command line was empty") - return errors.New("empty"), false, "" - } - thing := parts[0] - parts = parts[1:] - log.Log(INFO, "working path =", workingpath, "thing =", thing, "cmdline =", parts) - - // Create the command - cmd := exec.Command(thing, parts...) - - // Set the working directory - cmd.Dir = workingpath - - // Execute the command - output, err := cmd.CombinedOutput() - if err != nil { - if thing == "git" { - log.Log(INFO, "git ERROR. maybe okay", workingpath, "thing =", thing, "cmdline =", parts) - log.Log(INFO, "git ERROR. maybe okay err =", err) - if err.Error() == "exit status 1" { - log.Log(INFO, "git ERROR. normal exit status 1") - if parts[0] == "diff-index" { - log.Log(INFO, "git normal diff-index when repo dirty") - return nil, false, "git diff-index exit status 1" - } - } - } - - log.Log(WARN, "ERROR working path =", workingpath, "thing =", thing, "cmdline =", parts) - log.Log(WARN, "ERROR working path =", workingpath, "thing =", thing, "cmdline =", parts) - log.Log(WARN, "ERROR working path =", workingpath, "thing =", thing, "cmdline =", parts) - log.Error(err) - log.Warn("output was", string(output)) - log.Warn("cmd exited with error", err) - // panic("fucknuts") - return err, false, string(output) - - /* todo: see if there is a way to get the exit value - // The command failed (non-zero exit status) - if exitErr, ok := err.(*exec.ExitError); ok { - // Assert that it is an exec.ExitError and get the exit code - if status, ok := exitErr.Sys().(syscall.WaitStatus); ok { - log.Warn("Exit Status: %d\n", status.ExitStatus()) - } - } else { - log.Warn("cmd.Run() failed with %s\n", err) - } - */ - } - - tmp := string(output) - tmp = strings.TrimSpace(tmp) - - // Print the output - return nil, true, tmp + return r } // Set the path to the package @@ -438,10 +366,10 @@ func (rs *RepoStatus) XtermBash(args []string) { func (rs *RepoStatus) DoAll(all [][]string) bool { for _, cmd := range all { log.Log(WARN, "doAll() RUNNING: cmd =", cmd) - err, out := rs.RunCmd(cmd) - if err != nil { - log.Log(WARN, "doAll() err =", err) - log.Log(WARN, "doAll() out =", out) + r := rs.Run(cmd) + if r.Error != nil { + log.Log(WARN, "doAll() err =", r.Error) + log.Log(WARN, "doAll() out =", r.Stdout) return false } } diff --git a/update.go b/update.go index 99b17cb..81a604e 100644 --- a/update.go +++ b/update.go @@ -3,28 +3,21 @@ package repostatus import ( "errors" "fmt" - "strings" "time" "go.wit.com/log" ) func (rs *RepoStatus) gitBranchAll() { - err, out := rs.RunCmd([]string{"git", "branch", "--all"}) - log.Log(WARN, "git branch failed string =", rs.String()) - log.Log(WARN, "git branch failed realpath =", rs.realPath.String()) - if err != nil { + r := rs.Run([]string{"git", "branch", "--all"}) + if r.Error != nil { log.Log(WARN, "git branch failed string =", rs.String()) log.Log(WARN, "git branch failed realpath =", rs.realPath.String()) return } - all := strings.Split(out, "\n") - for _, s := range all { - // log.Log(WARN, "found branch", i, s) + for _, s := range r.Stdout { rs.targetBranch.AddText(s) } - // i := len(all) - // log.Log(WARN, "branch count =", i) } func (rs *RepoStatus) updateNew() {