summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Carr <[email protected]>2024-11-08 04:07:53 -0600
committerJeff Carr <[email protected]>2024-11-08 04:07:53 -0600
commit54b9acef69d2165d7692a85d6b5684240b915c85 (patch)
tree86e6d5a93a9b5c40b3fddf39886046d9782f90a1
parent38e55b2609031459ebdfc42ba03307bca4ff0263 (diff)
switch to using go-cmd/cmd
Signed-off-by: Jeff Carr <[email protected]>
-rw-r--r--Makefile34
-rw-r--r--buildPackage.go30
-rw-r--r--cmd.go184
-rw-r--r--main.go6
4 files changed, 207 insertions, 47 deletions
diff --git a/Makefile b/Makefile
index 979763e..1e7f3b0 100644
--- a/Makefile
+++ b/Makefile
@@ -54,38 +54,8 @@ build-test-failure: build
build-test-keep-files: build
./go-deb --no-gui --keep-files --repo go.wit.com/apps/go-deb
-build-all:
- go-deb --no-gui --repo go.wit.com/apps/go-deb
- go-deb --no-gui --repo go.wit.com/apps/go-clone
- go-deb --no-gui --repo go.wit.com/apps/autotypist
- go-deb --no-gui --repo go.wit.com/apps/virtigoctl
- go-deb --no-gui --repo go.wit.com/apps/virtigo
- go-deb --no-gui --repo go.wit.com/apps/autotypist
- go-deb --no-gui --repo go.wit.com/apps/guireleaser
- go-deb --no-gui --repo go.wit.com/apps/gowebd
- go-deb --no-gui --repo go.wit.com/apps/networkQuality
- go-deb --no-gui --repo go.wit.com/apps/helloworld
- go-deb --no-gui --repo go.wit.com/apps/basicwindow
- go-deb --no-gui --repo go.wit.com/apps/gadgetwindow
- go-deb --no-gui --repo go.wit.com/apps/powerpaneld
- go-deb --no-gui --repo go.wit.com/lib/daemons/virtigod
- go-deb --no-gui --repo go.wit.com/apps/control-panel-cloudflare
- go-deb --no-gui --repo go.wit.com/apps/control-panel-dns
- go-deb --no-gui --repo go.wit.com/apps/control-panel-droplet
- go-deb --no-gui --repo go.wit.com/apps/control-panel-vpn
- # go-deb --no-gui --repo golang.org/x/tools/cmd/goimports
-
-build-releases:
- -go-deb --release --no-gui --repo go.wit.com/apps/autotypist
- -go-deb --release --no-gui --repo go.wit.com/apps/control-panel-dns
- -go-deb --release --no-gui --repo go.wit.com/apps/control-panel-digitalocean
- -go-deb --release --no-gui --repo go.wit.com/apps/control-panel-cloudflare
- -go-deb --release --no-gui --repo go.wit.com/apps/control-panel-vpn
- -go-deb --release --no-gui --repo go.wit.com/apps/go-gui-toolkits
- -go-deb --release --no-gui --repo go.wit.com/apps/guireleaser
- -go-deb --release --no-gui --repo go.wit.com/apps/go.wit.com
- -go-deb --release --no-gui --repo go.wit.com/apps/helloworld
- -go-deb --release --no-gui --repo go.wit.com/apps/go-deb
+build-release:
+ go-deb --release --no-gui --repo go.wit.com/apps/go-deb
debian: build
./go-deb --no-gui --keep-files --repo go.wit.com/apps/go-deb
diff --git a/buildPackage.go b/buildPackage.go
index bf0657f..b7c1b27 100644
--- a/buildPackage.go
+++ b/buildPackage.go
@@ -62,7 +62,7 @@ func (c *controlBox) buildPackage() (bool, error) {
os.Unsetenv("GO111MODULE")
path := c.pathL.String() + "@latest"
cmd := []string{"go", "install", "-v", "-x", path}
- if shell.Run(cmd) {
+ if r := Run(cmd); r.Error == nil {
log.Warn("go install worked")
} else {
return false, errors.New("go install")
@@ -84,7 +84,7 @@ func (c *controlBox) buildPackage() (bool, error) {
cmd = append(cmd, "-ldflags", "-X "+flag)
}
- if shell.Run(cmd) {
+ if r := Run(cmd); r.Error == nil {
log.Warn("go build worked")
} else {
return false, errors.New("go build")
@@ -118,13 +118,13 @@ func (c *controlBox) buildPackage() (bool, error) {
log.Warn("mkdir failed")
return false, errors.New("mkdir files/usr/bin")
}
- if !shell.Run([]string{"cp", fullfilename, "files/usr/bin"}) {
+ if r := Run([]string{"cp", fullfilename, "files/usr/bin"}); r.Error != nil {
log.Warn("cp failed")
- return false, errors.New("cp " + fullfilename)
+ return false, r.Error
}
- if !shell.Run([]string{"strip", "files/usr/bin/" + filename}) {
+ if r := Run([]string{"strip", "files/usr/bin/" + filename}); r.Error != nil {
log.Warn("strip failed")
- return false, errors.New("strip " + filename)
+ return false, r.Error
}
// put the README in there (if missing, generate it?)
@@ -142,8 +142,8 @@ func (c *controlBox) buildPackage() (bool, error) {
if !shell.Mkdir(path) {
return false, errors.New("no files/usr/lib")
}
- if !shell.Run([]string{"cp", readme, path}) {
- return false, errors.New("cp readme")
+ if r := Run([]string{"cp", readme, path}); r.Error != nil {
+ return false, r.Error
}
}
@@ -151,7 +151,7 @@ func (c *controlBox) buildPackage() (bool, error) {
return false, errors.New("write control file")
}
if shell.Exists("postinst") {
- shell.Run([]string{"cp", "postinst", "files/DEBIAN/"})
+ Run([]string{"cp", "postinst", "files/DEBIAN/"})
}
if c.status == nil {
@@ -167,26 +167,26 @@ func (c *controlBox) buildPackage() (bool, error) {
} else {
os.Setenv("GO111MODULE", "off")
}
- shell.Run([]string{"./build"})
+ Run([]string{"./build"})
}
- shell.Run([]string{"dpkg-deb", "--build", "files", fulldebname})
+ Run([]string{"dpkg-deb", "--build", "files", fulldebname})
if shell.Exists(fulldebname) {
} else {
log.Warn("build failed")
return false, errors.New("dpkg-deb --build failed")
}
- shell.Run([]string{"dpkg-deb", "-I", fulldebname})
- shell.Run([]string{"dpkg-deb", "-c", fulldebname})
+ Run([]string{"dpkg-deb", "-I", fulldebname})
+ Run([]string{"dpkg-deb", "-c", fulldebname})
// cleanup files
if shell.Exists("files") {
if argv.KeepFiles {
log.Info("keeping the build files/")
} else {
- shell.Run([]string{"rm", "-rf", "files"})
+ Run([]string{"rm", "-rf", "files"})
log.Info("running sync")
- shell.Run([]string{"sync"})
+ Run([]string{"sync"})
if shell.Exists("files") {
log.Warn("rm -rf files/ failed. Run() returned false")
return false, errors.New("rm files/")
diff --git a/cmd.go b/cmd.go
new file mode 100644
index 0000000..faaa3c6
--- /dev/null
+++ b/cmd.go
@@ -0,0 +1,184 @@
+package main
+
+// this is a simplified interaction with the excellent
+// go-cmd/cmd package to work 'shell' like.
+
+// in all cases here, STDERR -> STDOUT
+// If you want the output from whatever you run
+// to be captured like it appears when you see it
+// on the command line, this is what this tries to do
+
+/*
+ if r := shell.Run([]{"ping", "-c", "3", "localhost"}); r.Error == nil {
+ if r.Exit == 0 {
+ log.Println("ran ok")
+ } else {
+ log.Println("ran")
+ }
+ // all stdout/stderr captured in r.Stdout
+ }
+*/
+
+import (
+ "errors"
+ "fmt"
+ "time"
+
+ "github.com/go-cmd/cmd"
+ "go.wit.com/log"
+)
+
+func Run(args []string) cmd.Status {
+ return PwdRun("", args)
+}
+
+// absolutely doesn't echo anything
+func PwdRunQuiet(pwd string, args []string) cmd.Status {
+ var arg0 string
+ var argx []string
+ // Check if the slice has at least one element (the command name)
+ if len(args) == 0 {
+ var s cmd.Status
+ s.Error = errors.New("Error: Command slice is empty.")
+ return s
+ }
+ if len(args) == 1 {
+ // Pass the first element as the command, and the rest as variadic arguments
+ arg0 = args[0]
+ } else {
+ arg0 = args[0]
+ argx = args[1:]
+ }
+
+ // Start a long-running process, capture stdout and stderr
+ findCmd := cmd.NewCmd(arg0, argx...)
+ if pwd != "" {
+ findCmd.Dir = pwd
+ }
+ statusChan := findCmd.Start() // non-blocking
+
+ ticker := time.NewTicker(2 * time.Second)
+
+ // this is interesting, maybe useful, but wierd, but neat. interesting even
+ // Print last line of stdout every 2s
+ go func() {
+ for range ticker.C {
+ status := findCmd.Status()
+ n := len(status.Stdout)
+ if n != 0 {
+ fmt.Println(status.Stdout[n-1])
+ }
+ }
+ }()
+
+ // Stop command after 1 hour
+ go func() {
+ <-time.After(1 * time.Hour)
+ findCmd.Stop()
+ }()
+
+ // Check if command is done
+ select {
+ case finalStatus := <-statusChan:
+ log.Info("finalStatus =", finalStatus.Exit, finalStatus.Error)
+ return finalStatus
+ // done
+ default:
+ // no, still running
+ }
+
+ // Block waiting for command to exit, be stopped, or be killed
+ finalStatus := <-statusChan
+ return finalStatus
+}
+
+func blah(cmd []string) {
+ r := Run(cmd)
+ log.Info("cmd =", r.Cmd)
+ log.Info("complete =", r.Complete)
+ log.Info("exit =", r.Exit)
+ log.Info("err =", r.Error)
+ log.Info("len(stdout+stderr) =", len(r.Stdout))
+}
+
+// run these to see confirm the sytem behaves as expected
+func RunTest() {
+ blah([]string{"ping", "-c", "3", "localhost"})
+ blah([]string{"exit", "0"})
+ blah([]string{"exit", "-1"})
+ blah([]string{"true"})
+ blah([]string{"false"})
+ blah([]string{"grep", "root", "/etc/", "/proc/cmdline", "/usr/bin/chmod"})
+ blah([]string{"grep", "root", "/proc/cmdline"})
+ fmt.Sprint("blahdone")
+}
+
+// sets the exec dir if it's sent
+// combines stdout and stderr
+// echo's output
+func PwdRun(pwd string, args []string) cmd.Status {
+ var save []string // combined stdout & stderr
+ var arg0 string
+ var argx []string
+ // Check if the slice has at least one element (the command name)
+ if len(args) == 0 {
+ var s cmd.Status
+ s.Error = errors.New("Error: Command slice is empty.")
+ return s
+ }
+ if len(args) == 1 {
+ // Pass the first element as the command, and the rest as variadic arguments
+ arg0 = args[0]
+ } else {
+ arg0 = args[0]
+ argx = args[1:]
+ }
+
+ // Disable output buffering, enable streaming
+ cmdOptions := cmd.Options{
+ Buffered: false,
+ Streaming: true,
+ }
+
+ // Create Cmd with options
+ envCmd := cmd.NewCmdOptions(cmdOptions, arg0, argx...)
+ if pwd != "" {
+ envCmd.Dir = pwd
+ }
+
+ // Print STDOUT and STDERR lines streaming from Cmd
+ doneChan := make(chan struct{})
+ go func() {
+ defer close(doneChan)
+ // Done when both channels have been closed
+ // https://dave.cheney.net/2013/04/30/curious-channels
+ for envCmd.Stdout != nil || envCmd.Stderr != nil {
+ select {
+ case line, open := <-envCmd.Stdout:
+ if !open {
+ envCmd.Stdout = nil
+ continue
+ }
+ save = append(save, line)
+ fmt.Println(line)
+ case line, open := <-envCmd.Stderr:
+ if !open {
+ envCmd.Stderr = nil
+ continue
+ }
+ save = append(save, line)
+ fmt.Println(line)
+ }
+ }
+ }()
+
+ // Run and wait for Cmd to return, discard Status
+ <-envCmd.Start()
+
+ // Wait for goroutine to print everything
+ <-doneChan
+
+ s := envCmd.Status()
+ s.Stdout = save
+ return s
+}
diff --git a/main.go b/main.go
index edc3fda..4f30d19 100644
--- a/main.go
+++ b/main.go
@@ -27,6 +27,8 @@ var basicWindow *gadgets.BasicWindow
var resources embed.FS
func main() {
+ // RunTest()
+ // os.Exit(0)
if argv.Repo == "" {
log.Info("You need to tell me what repo you want to work on")
println("")
@@ -67,6 +69,10 @@ func main() {
os.Exit(-1)
}
+ // set the working directory to argv.Repo
+ log.Info("cd", cBox.status.Path())
+ os.Chdir(cBox.status.Path())
+
if argv.NoGui {
shell.TestTerminalColor()
// basicWindow.Show() // broken gui package. convert to protobuf