switch to using go-cmd/cmd
Signed-off-by: Jeff Carr <jcarr@wit.com>
This commit is contained in:
parent
38e55b2609
commit
54b9acef69
34
Makefile
34
Makefile
|
@ -54,38 +54,8 @@ build-test-failure: build
|
||||||
build-test-keep-files: build
|
build-test-keep-files: build
|
||||||
./go-deb --no-gui --keep-files --repo go.wit.com/apps/go-deb
|
./go-deb --no-gui --keep-files --repo go.wit.com/apps/go-deb
|
||||||
|
|
||||||
build-all:
|
build-release:
|
||||||
go-deb --no-gui --repo go.wit.com/apps/go-deb
|
go-deb --release --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
|
|
||||||
|
|
||||||
debian: build
|
debian: build
|
||||||
./go-deb --no-gui --keep-files --repo go.wit.com/apps/go-deb
|
./go-deb --no-gui --keep-files --repo go.wit.com/apps/go-deb
|
||||||
|
|
|
@ -62,7 +62,7 @@ func (c *controlBox) buildPackage() (bool, error) {
|
||||||
os.Unsetenv("GO111MODULE")
|
os.Unsetenv("GO111MODULE")
|
||||||
path := c.pathL.String() + "@latest"
|
path := c.pathL.String() + "@latest"
|
||||||
cmd := []string{"go", "install", "-v", "-x", path}
|
cmd := []string{"go", "install", "-v", "-x", path}
|
||||||
if shell.Run(cmd) {
|
if r := Run(cmd); r.Error == nil {
|
||||||
log.Warn("go install worked")
|
log.Warn("go install worked")
|
||||||
} else {
|
} else {
|
||||||
return false, errors.New("go install")
|
return false, errors.New("go install")
|
||||||
|
@ -84,7 +84,7 @@ func (c *controlBox) buildPackage() (bool, error) {
|
||||||
cmd = append(cmd, "-ldflags", "-X "+flag)
|
cmd = append(cmd, "-ldflags", "-X "+flag)
|
||||||
}
|
}
|
||||||
|
|
||||||
if shell.Run(cmd) {
|
if r := Run(cmd); r.Error == nil {
|
||||||
log.Warn("go build worked")
|
log.Warn("go build worked")
|
||||||
} else {
|
} else {
|
||||||
return false, errors.New("go build")
|
return false, errors.New("go build")
|
||||||
|
@ -118,13 +118,13 @@ func (c *controlBox) buildPackage() (bool, error) {
|
||||||
log.Warn("mkdir failed")
|
log.Warn("mkdir failed")
|
||||||
return false, errors.New("mkdir files/usr/bin")
|
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")
|
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")
|
log.Warn("strip failed")
|
||||||
return false, errors.New("strip " + filename)
|
return false, r.Error
|
||||||
}
|
}
|
||||||
|
|
||||||
// put the README in there (if missing, generate it?)
|
// put the README in there (if missing, generate it?)
|
||||||
|
@ -142,8 +142,8 @@ func (c *controlBox) buildPackage() (bool, error) {
|
||||||
if !shell.Mkdir(path) {
|
if !shell.Mkdir(path) {
|
||||||
return false, errors.New("no files/usr/lib")
|
return false, errors.New("no files/usr/lib")
|
||||||
}
|
}
|
||||||
if !shell.Run([]string{"cp", readme, path}) {
|
if r := Run([]string{"cp", readme, path}); r.Error != nil {
|
||||||
return false, errors.New("cp readme")
|
return false, r.Error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,7 +151,7 @@ func (c *controlBox) buildPackage() (bool, error) {
|
||||||
return false, errors.New("write control file")
|
return false, errors.New("write control file")
|
||||||
}
|
}
|
||||||
if shell.Exists("postinst") {
|
if shell.Exists("postinst") {
|
||||||
shell.Run([]string{"cp", "postinst", "files/DEBIAN/"})
|
Run([]string{"cp", "postinst", "files/DEBIAN/"})
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.status == nil {
|
if c.status == nil {
|
||||||
|
@ -167,26 +167,26 @@ func (c *controlBox) buildPackage() (bool, error) {
|
||||||
} else {
|
} else {
|
||||||
os.Setenv("GO111MODULE", "off")
|
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) {
|
if shell.Exists(fulldebname) {
|
||||||
} else {
|
} else {
|
||||||
log.Warn("build failed")
|
log.Warn("build failed")
|
||||||
return false, errors.New("dpkg-deb --build failed")
|
return false, errors.New("dpkg-deb --build failed")
|
||||||
}
|
}
|
||||||
shell.Run([]string{"dpkg-deb", "-I", fulldebname})
|
Run([]string{"dpkg-deb", "-I", fulldebname})
|
||||||
shell.Run([]string{"dpkg-deb", "-c", fulldebname})
|
Run([]string{"dpkg-deb", "-c", fulldebname})
|
||||||
|
|
||||||
// cleanup files
|
// cleanup files
|
||||||
if shell.Exists("files") {
|
if shell.Exists("files") {
|
||||||
if argv.KeepFiles {
|
if argv.KeepFiles {
|
||||||
log.Info("keeping the build files/")
|
log.Info("keeping the build files/")
|
||||||
} else {
|
} else {
|
||||||
shell.Run([]string{"rm", "-rf", "files"})
|
Run([]string{"rm", "-rf", "files"})
|
||||||
log.Info("running sync")
|
log.Info("running sync")
|
||||||
shell.Run([]string{"sync"})
|
Run([]string{"sync"})
|
||||||
if shell.Exists("files") {
|
if shell.Exists("files") {
|
||||||
log.Warn("rm -rf files/ failed. Run() returned false")
|
log.Warn("rm -rf files/ failed. Run() returned false")
|
||||||
return false, errors.New("rm files/")
|
return false, errors.New("rm files/")
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
6
main.go
6
main.go
|
@ -27,6 +27,8 @@ var basicWindow *gadgets.BasicWindow
|
||||||
var resources embed.FS
|
var resources embed.FS
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
// RunTest()
|
||||||
|
// os.Exit(0)
|
||||||
if argv.Repo == "" {
|
if argv.Repo == "" {
|
||||||
log.Info("You need to tell me what repo you want to work on")
|
log.Info("You need to tell me what repo you want to work on")
|
||||||
println("")
|
println("")
|
||||||
|
@ -67,6 +69,10 @@ func main() {
|
||||||
os.Exit(-1)
|
os.Exit(-1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// set the working directory to argv.Repo
|
||||||
|
log.Info("cd", cBox.status.Path())
|
||||||
|
os.Chdir(cBox.status.Path())
|
||||||
|
|
||||||
if argv.NoGui {
|
if argv.NoGui {
|
||||||
shell.TestTerminalColor()
|
shell.TestTerminalColor()
|
||||||
// basicWindow.Show() // broken gui package. convert to protobuf
|
// basicWindow.Show() // broken gui package. convert to protobuf
|
||||||
|
|
Loading…
Reference in New Issue