all repos — erl @ ad8f97f9fb886a7c2e7ef7ef8a738ae7f0c9ddf5

Execute Reload Loop

feat: add quiet flag

Alan Pearce
commit

ad8f97f9fb886a7c2e7ef7ef8a738ae7f0c9ddf5

parent

921c8f0ae3eec6acf4f3cfb236f3a7f0869006e9

4 files changed, 72 insertions(+), 16 deletions(-)

changed files
M command/command.gocommand/command.go
@@ -9,7 +9,7 @@ "os/exec"
"strings" "time" - "github.com/fatih/color" + "alin.ovh/erl/output" ) type Command interface {
@@ -24,14 +24,13 @@
name string args []string - opts Options + out output.Output - printFail func(string, ...any) - printInfo func(string, ...any) - printSuccess func(string, ...any) + opts Options } type Options struct { + Output io.Writer Stdout io.Writer Stderr io.Writer }
@@ -45,15 +44,16 @@ }
if options.Stderr == nil { options.Stderr = os.Stderr } + if options.Output == nil { + options.Output = os.Stderr + } return &Cmd{ name: name, args: args, opts: options, - printFail: color.New(color.FgRed).PrintfFunc(), - printInfo: color.New().PrintfFunc(), - printSuccess: color.New(color.FgGreen).PrintfFunc(), + out: output.New(options.Output), } }
@@ -65,11 +65,11 @@ return fmt.Errorf("error killing command: %v", err)
} if cmd.ProcessState == nil { - cmd.printInfo("[command not stopped, waiting %s seconds before killing]\n", timeout) + cmd.out.Info("[command not stopped, waiting %s seconds before killing]\n", timeout) time.Sleep(timeout) if cmd.ProcessState == nil { - cmd.printInfo("[command not stopped, killing]\n") + cmd.out.Info("[command not stopped, killing]\n") err := cmd.Process.Kill() if err != nil { return fmt.Errorf("error killing command: %v", err)
@@ -91,9 +91,9 @@ if err != nil {
var exitErr *exec.ExitError if errors.As(err, &exitErr) { if cmd.Exited() { - cmd.printFail("[command exited with code %d]\n", cmd.ProcessState.ExitCode()) + cmd.out.Fail("[command exited with code %d]\n", cmd.ProcessState.ExitCode()) } else { - cmd.printFail("[command stopped]\n") + cmd.out.Fail("[command stopped]\n") } } else { return fmt.Errorf("error waiting for command: %v", err)
@@ -101,7 +101,7 @@ }
} if cmd.Exited() && cmd.ProcessState.Success() { - cmd.printSuccess("[command finished]\n") + cmd.out.Success("[command finished]\n") } return nil
@@ -109,7 +109,7 @@ }
func (cmd *Cmd) Start() error { cmd.makeCommand() - cmd.printSuccess("[running: %s %s]\n", cmd.name, strings.Join(cmd.args, " ")) + cmd.out.Success("[running: %s %s]\n", cmd.name, strings.Join(cmd.args, " ")) err := cmd.Cmd.Start() if err != nil { return fmt.Errorf("error starting command: %v", err)
M command/command_test.gocommand/command_test.go
@@ -2,6 +2,7 @@ package command
import ( "bytes" + "io" "testing" "time" )
@@ -41,6 +42,7 @@ t.Parallel()
var stdout, stderr bytes.Buffer cmd := New(tt.cmdName, tt.args, Options{ + Output: io.Discard, Stdout: &stdout, Stderr: &stderr, })
@@ -101,6 +103,7 @@ t.Parallel()
var stdout, stderr bytes.Buffer cmd := New(tt.cmdName, tt.args, Options{ + Output: io.Discard, Stdout: &stdout, Stderr: &stderr, })
@@ -135,6 +138,7 @@ t.Parallel()
var stdout, stderr bytes.Buffer cmd := New("echo", []string{"test"}, Options{ + Output: io.Discard, Stdout: &stdout, Stderr: &stderr, })
@@ -160,6 +164,7 @@
// Use a command that will fail var stdout, stderr bytes.Buffer cmd := New("ls", []string{"/nonexistent/directory/12345"}, Options{ + Output: io.Discard, Stdout: &stdout, Stderr: &stderr, })
@@ -188,6 +193,7 @@ t.Parallel()
var stdout, stderr bytes.Buffer cmd := New("sleep", []string{"10"}, Options{ + Output: io.Discard, Stdout: &stdout, Stderr: &stderr, })
@@ -227,6 +233,7 @@ t.Parallel()
var stdout, stderr bytes.Buffer cmd := New("echo", []string{"test"}, Options{ + Output: io.Discard, Stdout: &stdout, Stderr: &stderr, })
@@ -243,6 +250,7 @@ t.Parallel()
var stdout, stderr bytes.Buffer cmd := New("echo", []string{"test"}, Options{ + Output: io.Discard, Stdout: &stdout, Stderr: &stderr, })
@@ -272,6 +280,7 @@ t.Parallel()
var stdout, stderr bytes.Buffer cmd := New("echo", []string{"test"}, Options{ + Output: io.Discard, Stdout: &stdout, Stderr: &stderr, })
@@ -286,6 +295,7 @@ t.Parallel()
var stdout, stderr bytes.Buffer cmd := New("sleep", []string{"1"}, Options{ + Output: io.Discard, Stdout: &stdout, Stderr: &stderr, })
@@ -308,6 +318,7 @@ t.Parallel()
var stdout, stderr bytes.Buffer cmd := New("echo", []string{"test"}, Options{ + Output: io.Discard, Stdout: &stdout, Stderr: &stderr, })
@@ -336,6 +347,7 @@ t.Parallel()
var stdout, stderr bytes.Buffer cmd := New("echo", []string{"test"}, Options{ + Output: io.Discard, Stdout: &stdout, Stderr: &stderr, })
@@ -372,6 +384,7 @@ t.Parallel()
var stdout, stderr bytes.Buffer cmd := New("echo", []string{"hello", "world"}, Options{ + Output: io.Discard, Stdout: &stdout, Stderr: &stderr, })
@@ -408,6 +421,7 @@ var _ Command = &Cmd{}
var stdout, stderr bytes.Buffer cmd := New("echo", []string{"test"}, Options{ + Output: io.Discard, Stdout: &stdout, Stderr: &stderr, })
M main.gomain.go
@@ -3,6 +3,7 @@
import ( "context" "flag" + "io" "log" "os" "os/signal"
@@ -20,7 +21,8 @@ "alin.ovh/erl/watcher"
) var ( - Exec = flag.String("exec", "", "command to execute on file change") + Exec = flag.String("exec", "", "command to execute on file change") + Quiet = flag.Bool("quiet", false, "suppress own output") ) func Start(ctx context.Context, w watcher.Watcher, sm *state.StateMachine) {
@@ -128,7 +130,12 @@ syscall.SIGTERM,
) defer cancel() - cmd := command.New(program, args, command.Options{}) + copts := command.Options{} + if *Quiet { + copts.Output = io.Discard + } + + cmd := command.New(program, args, copts) sm := state.New(cmd, log.New(os.Stderr, "state: ", log.Lmsgprefix)) Start(ctx, watcher, sm) }
A output/output.go
@@ -0,0 +1,35 @@
+package output + +import ( + "io" + + "github.com/fatih/color" +) + +type Output struct { + Writer io.Writer + + fail, info, success *color.Color +} + +func New(writer io.Writer) Output { + return Output{ + Writer: writer, + + fail: color.New(color.FgRed), + info: color.New(), + success: color.New(color.FgGreen), + } +} + +func (o Output) Fail(format string, args ...any) { + o.fail.Fprintf(o.Writer, format, args...) +} + +func (o Output) Info(format string, args ...any) { + o.info.Fprintf(o.Writer, format, args...) +} + +func (o Output) Success(format string, args ...any) { + o.success.Fprintf(o.Writer, format, args...) +}