Diff of everything #1

Closed
wants to merge 17 commits into
from

Conversation

Projects
None yet
4 participants
Owner

natefinch commented Jun 18, 2015

No description provided.

Please delete this.

I think this should be a function, not a method

func Run(cmd *exec.Cmd, opts ...Option) {

...

}

natefinch added some commits Jun 17, 2015

switch to a log.Print style function call
This prevents formatting characters from becoming a problem in output
make log funcs take a string
Although this means that most log packages will need to be used with a wrapper function, it makes the intent much more clear - that a single string will be passed per call.
deputy.go
+ }
+
+ errsrc := &bytes.Buffer{}
+ if d.Errors == FromStderr {
@rogpeppe

rogpeppe Jun 23, 2015

How about defining a multiWriter function:

func dualWriter(w0, w1 io.Writer) io.Writer {
     if w1 == nil {
         return w0
     }
     return io.MultiWriter(w0, w1)
}

then:

switch d.Errors {
case FromStderr:
    cmd.Stderr = dualWriter(errsrc, cmd.Stderr)
case FromStdin:
    cmd.Stdout = dualWriter(errsrc, cmd.Stdout)
}

?

@natefinch

natefinch Jun 23, 2015

Owner

Sounds good, thanks.

deputy.go
+ }
+
+ if err != nil && errsrc.Len() > 0 {
+ return fmt.Errorf("%s: %s", err, strings.TrimSpace(errsrc.String()))
@rogpeppe

rogpeppe Jun 23, 2015

bytes.TrimSpace(errsrc.Bytes())

(saves an allocation FWIW) ?

deputy.go
+ // Errors describes how errors should be handled.
+ Errors ErrorHandling
+ // StdoutLog takes a function that will receive lines written to stdout from
+ // the command.
@rogpeppe

rogpeppe Jun 23, 2015

// Note that this will override the Stdout field if it's already set.
(and likewise for StderrLog below)
?

@rogpeppe

rogpeppe Jun 23, 2015

also, perhaps mention whether the lines are newline-terminated or not.

deputy.go
+ }
+
+ err := d.run(cmd)
+
@natefinch

natefinch Jun 23, 2015

Owner

Not sure what the question is here.... d is the receiver?

@rogpeppe

rogpeppe Jun 23, 2015

sorry, "d" == "delete this line"
unfortunate conflict of nomenclature.

deputy.go
+func pipe(log func(string), r io.Reader, errs chan<- error) {
+ scanner := bufio.NewScanner(r)
+ for scanner.Scan() {
+ w := scanner.Text()
deputy.go
+
+// Run starts the specified command and waits for it to complete. Its behavior
+// conforms to the Options passed to it at construction time.
+func (d Deputy) Run(cmd *exec.Cmd) error {
@rogpeppe

rogpeppe Jun 23, 2015

// Note that, like cmd.Run, Deputy.Run should not be used with
// StdoutPipe or StderrPipe.

+ }
+ if d.StdoutLog != nil {
+ var err error
+ d.stdoutPipe, err = cmd.StdoutPipe()
@rogpeppe

rogpeppe Jun 23, 2015

If both StdoutLog and StderrLog are set, I wonder if it would be
better to just use a single pipe - that way the stdout and stderr
log messages cannot be reordered.

deputy.go
+
+func (d Deputy) wait(cmd *exec.Cmd, errs <-chan error) error {
+ var err1, err2 error
+ if d.stdoutPipe != nil {
@rogpeppe

rogpeppe Jun 23, 2015

// Note that it's important that we wait for the pipes
// to be closed before calling cmd.Wait otherwise
// Wait can close the pipes before we have read
// all their data.

?

deputy.go
+ StdoutLog func(string)
+ // StdoutLog takes a function that will receive lines written to stderr from
+ // the command.
+ StderrLog func(string)
@rogpeppe

rogpeppe Jun 23, 2015

I wonder if it would be better for these to take a []byte argument to save an allocation,
which can be reasonably significant for verbose logging.

LGTM with some comments and suggestions.

@natefinch natefinch closed this Jun 26, 2015

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment