Compare commits

...

8 Commits

Author SHA1 Message Date
Jeff Carr e621f228ba linux only code 2025-02-22 06:53:24 -06:00
Jeff Carr 590ce71782 new autogenpb 2025-02-20 09:39:36 -06:00
Jeff Carr 2b1f7f54d5 testing for using 'sudo' 2025-02-14 18:40:31 -06:00
Jeff Carr d70cf82ecc sudo with pseudo tty 2025-02-12 15:11:29 -06:00
Jeff Carr 364d666eb6 add RunVerbose() RunVerboseOnError() 2025-02-07 11:22:11 -06:00
Jeff Carr 0146183226 remote output 2025-01-29 12:25:44 -06:00
Jeff Carr 098c7d3771 forge config has user xterm settings 2025-01-16 10:25:29 -06:00
Jeff Carr 1534b9fbbc shell exec for 'forge commit' 2025-01-12 06:35:36 -06:00
4 changed files with 185 additions and 4 deletions

47
cmd.go
View File

@ -2,6 +2,7 @@ package shell
import ( import (
"errors" "errors"
"fmt"
"os" "os"
"time" "time"
@ -241,3 +242,49 @@ func RemoveFirstElement(slice []string) (string, []string) {
} }
return slice[0], slice[1:] // Return the slice without the first element return slice[0], slice[1:] // Return the slice without the first element
} }
func RunVerbose(cmd []string) (*cmd.Status, error) {
pwd, _ := os.Getwd()
log.Info("Running:", pwd, cmd)
r, err := RunStrict(cmd)
if err != nil {
log.Info("Error", cmd, err)
}
for _, line := range r.Stdout {
log.Info(line)
}
for _, line := range r.Stderr {
log.Info(line)
}
return r, err
}
func RunVerboseOnError(cmd []string) (*cmd.Status, error) {
r, err := RunStrict(cmd)
if err == nil {
return r, err
}
pwd, _ := os.Getwd()
log.Info("Run Error:", pwd, cmd, err)
for _, line := range r.Stdout {
log.Info(line)
}
for _, line := range r.Stderr {
log.Info(line)
}
return r, err
}
func RunStrict(cmd []string) (*cmd.Status, error) {
pwd, _ := os.Getwd()
result := PathRunQuiet(pwd, cmd)
if result.Error != nil {
log.Warn(pwd, cmd, "wow. golang is cool. an os.Error:", result.Error)
return &result, result.Error
}
if result.Exit != 0 {
// log.Warn(cmd, "failed with", result.Exit, repo.GetGoPath())
return &result, errors.New(fmt.Sprint(cmd, "failed with", result.Exit))
}
return &result, nil
}

71
exec.go Normal file
View File

@ -0,0 +1,71 @@
package shell
import (
"errors"
"os"
"os/exec"
"go.wit.com/log"
)
func Exec(args []string) error {
if len(args) == 0 {
return errors.New("Error: Command slice is empty.")
}
// Start a long-running process, capture stdout and stderr
a, b := RemoveFirstElement(args)
process := exec.Command(a, b...)
process.Stderr = os.Stderr
process.Stdin = os.Stdin
process.Stdout = os.Stdout
process.Start()
err := process.Wait()
log.Log(INFO, "shell.Exec() err =", err)
return nil
}
func ExecCheck(args []string) error {
if len(args) == 0 {
return errors.New("Error: Command slice is empty.")
}
// Start a long-running process, capture stdout and stderr
a, b := RemoveFirstElement(args)
process := exec.Command(a, b...)
process.Stderr = os.Stderr
process.Stdin = os.Stdin
process.Stdout = os.Stdout
err := process.Run()
if err != nil {
log.Info("ExecCheck() err", err)
return err
}
// log.Info("ExecCheck() nil")
return nil
}
func PathExecVerbose(path string, args []string) error {
if len(args) == 0 {
return errors.New("Error: Command slice is empty.")
}
// Start a long-running process, capture stdout and stderr
a, b := RemoveFirstElement(args)
process := exec.Command(a, b...)
process.Dir = path
process.Stderr = os.Stderr
process.Stdin = os.Stdin
process.Stdout = os.Stdout
err := process.Run()
log.Info("Exec() cmd:", args)
if err != nil {
log.Info("ExecCheck() err", err)
return err
}
// log.Info("ExecCheck() nil")
return nil
}

62
exec_linux.go Normal file
View File

@ -0,0 +1,62 @@
package shell
import (
"fmt"
"os"
"os/exec"
"syscall"
)
func SudoRaw(c []string) {
args := []string{"-S"}
args = append(args, c...)
cmd := exec.Command("sudo", args...)
// Assign the current process's standard input, output, and error
cmd.Stderr = os.Stderr
cmd.Stdout = os.Stdout
cmd.Stdin = os.Stdin
// Ensure the process has a terminal session
cmd.SysProcAttr = &syscall.SysProcAttr{
Setsid: true, // Start a new session
}
err := cmd.Run()
if err != nil {
fmt.Println("Command execution failed:", err)
}
}
func Sudo(c []string) error {
args := []string{"-S"}
// args := []string{}
args = append(args, c...)
cmd := exec.Command("sudo", args...)
// Open the terminal device directly to preserve input/output control
tty, err := os.OpenFile("/dev/tty", os.O_RDWR, 0)
if err != nil {
fmt.Println("Failed to open /dev/tty:", err)
return err
}
defer tty.Close()
// Assign the TTY explicitly
cmd.Stdin = tty
cmd.Stdout = tty
cmd.Stderr = tty
// Ensure the new process gets its own session
cmd.SysProcAttr = &syscall.SysProcAttr{
Setsid: true, // Start a new session
}
// Run the command
if err := cmd.Run(); err != nil {
fmt.Println("Command execution failed:", err)
}
fmt.Println("\nProcess finished. TTY restored.")
return nil
}

View File

@ -3,7 +3,6 @@ package shell
import ( import (
"fmt" "fmt"
"os" "os"
"strings"
"go.wit.com/log" "go.wit.com/log"
) )
@ -127,16 +126,17 @@ func XtermCmd(path string, cmd []string) {
// runs an xterm // runs an xterm
// waits until xterm exits // waits until xterm exits
func XtermCmdWait(path string, cmd []string) { func XtermCmdWait(path string, cmd []string) {
var argsXterm = getXtermCmd(cmd) // var argsXterm = getXtermCmd(cmd)
log.Info("XtermCmd() path =", path, "cmd =", argsXterm) log.Info("XtermCmd() path =", path, "cmd =", cmd)
// keeps git diff from exiting on small diffs // keeps git diff from exiting on small diffs
os.Setenv("LESS", "-+F -+X -R") os.Setenv("LESS", "-+F -+X -R")
PathRunLog(path, argsXterm, INFO) PathRunLog(path, cmd, INFO)
} }
/*
// spawns an xterm with something you can run at a command line // spawns an xterm with something you can run at a command line
// then executes bash // then executes bash
func XtermCmdBash(path string, cmd []string) { func XtermCmdBash(path string, cmd []string) {
@ -149,3 +149,4 @@ func XtermCmdBash(path string, cmd []string) {
log.Info("XtermCmd() path =", path, "cmd =", tmp) log.Info("XtermCmd() path =", path, "cmd =", tmp)
go PathRunLog(path, tmp, INFO) go PathRunLog(path, tmp, INFO)
} }
*/