use go-cmd/cmd

This commit is contained in:
Jeff Carr 2024-11-08 06:43:33 -06:00
parent 29545d3f04
commit 55acea0bd7
10 changed files with 141 additions and 203 deletions

View File

@ -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

79
git.go
View File

@ -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 <hash> 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)

View File

@ -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

View File

@ -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 {

View File

@ -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
}

View File

@ -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

4
new.go
View File

@ -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

View File

@ -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)

96
unix.go
View File

@ -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
}
}

View File

@ -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() {