-
Notifications
You must be signed in to change notification settings - Fork 8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Display executed commands via Verbose Logging #111
Changes from 3 commits
1118d28
2cafe57
fdd19c2
0364570
81c8e3c
fc31760
d416305
8933468
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,38 +2,33 @@ package util | |
|
||
import ( | ||
"io/ioutil" | ||
"fmt" | ||
"os" | ||
"os/exec" | ||
"strings" | ||
"syscall" | ||
|
||
"github.com/fatih/color" | ||
) | ||
|
||
const defaultFailedCode = 1 | ||
|
||
type Executor struct { | ||
cmd *exec.Cmd | ||
} | ||
|
||
// StreamCommand sets up the output streams (and colors) to stream command output if verbose is configured | ||
func StreamCommand(cmd *exec.Cmd) error { | ||
return RunCommand(cmd, false) | ||
return Executor{cmd}.Execute(false) | ||
} | ||
|
||
// ForceStreamCommand sets up the output streams (and colors) to stream command output regardless of verbosity | ||
func ForceStreamCommand(cmd *exec.Cmd) error { | ||
return RunCommand(cmd, true) | ||
return Executor{cmd}.Execute(true) | ||
} | ||
|
||
// RunCommand executes the provided command, it also can sspecify if the output should be forced to print to the console | ||
func RunCommand(cmd *exec.Cmd, forceOutput bool) error { | ||
cmd.Stderr = os.Stderr | ||
if Logger().IsVerbose || forceOutput { | ||
cmd.Stdout = os.Stdout | ||
} else { | ||
cmd.Stdout = ioutil.Discard | ||
} | ||
|
||
color.Set(color.FgCyan) | ||
err := cmd.Run() | ||
color.Unset() | ||
return err | ||
func Command(path string, arg ...string) Executor { | ||
return Executor{exec.Command(path, arg...)} | ||
} | ||
|
||
// PassthruCommand is similar to ForceStreamCommand in that it will issue all output | ||
|
@@ -69,3 +64,49 @@ func PassthruCommand(cmd *exec.Cmd) (exitCode int) { | |
|
||
return | ||
} | ||
|
||
// RunCommand executes the provided command, it also can sspecify if the output should be forced to print to the console | ||
func (x Executor) Execute(forceOutput bool) error { | ||
x.cmd.Stderr = os.Stderr | ||
if Logger().IsVerbose || forceOutput { | ||
x.cmd.Stdout = os.Stdout | ||
} else { | ||
x.cmd.Stdout = ioutil.Discard | ||
} | ||
|
||
x.Log("Executing") | ||
color.Set(color.FgCyan) | ||
err := x.Run() | ||
color.Unset() | ||
return err | ||
} | ||
|
||
// Run runs a command via exec.Run() without modification or output of the underlying command. | ||
func (x Executor) Run() error { | ||
return x.cmd.Run() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we want to log all commands that are run? Or only commands that force/stream? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Probably all commands, but I wanted to lay out the initial API for it more flexibly so the refactoring can go either way. |
||
} | ||
|
||
// Log verbosely logs the command. | ||
func (x Executor) Log(tag string) { | ||
color.Set(color.FgYellow) | ||
Logger().Verbose.Printf("%s: %s", tag, x.ToString()) | ||
color.Unset() | ||
} | ||
|
||
// CmdToString converts a Command to a human-readable string with key context details. | ||
func (x Executor) ToString() string { | ||
context := "" | ||
if x.cmd.Dir != "" { | ||
context = fmt.Sprintf("(WD: %s", x.cmd.Dir) | ||
} | ||
if x.cmd.Env != nil { | ||
env := strings.Join(x.cmd.Env, " ") | ||
if context == "" { | ||
context = fmt.Sprintf("(Env: %s", env) | ||
} else { | ||
context = fmt.Sprintf("%s, Env: %s)", context, env) | ||
} | ||
} | ||
|
||
return fmt.Sprintf("%s %s %s", x.cmd.Path, strings.Join(x.cmd.Args[1:], " "), context) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You know, we could make this and
ForceStreamCommand
even easier to read on the caller side if we just take the command and args here instead of theexec.Cmd
and callexec.Command
just like theExecutor.Execute