-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Improve shell command stderr handling
Changes in `shell` package: While there are many public functions for grabbing a command's mixed output or stdout output only, there is no way to specifically get Stderr instead. Stderr is needed to debug issues, which are (almost) always accompanied by an error (non-0 exit status). This commit changes the handling of stdout and stderr to make it possible to return a "merged" string (stdout+stderr) or stdout only. As we can now grab stderr separately, we can also add it to the returned error, if any. This means that every error that is returned by public functions in this package is now of type `ErrWithCmdOutput`, which makes it possible for the callee to explicitely get the stderr stream, if needed, or just print the whole error including stderr. It also means that per default, an error will not just be "FatalError{Underlying: exit status 1}", but instead contain the whole Stderr stream. The underlying error is encapsulated in the new error type. Signed-off-by: Ramon Rüttimann <me@ramonr.ch>
- Loading branch information
1 parent
964a544
commit e69eb63
Showing
3 changed files
with
174 additions
and
67 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
package shell | ||
|
||
import ( | ||
"strings" | ||
"sync" | ||
) | ||
|
||
// output contains the output after runnig a command. | ||
type output struct { | ||
stdout *outputStream | ||
stderr *outputStream | ||
// merged contains stdout and stderr merged into one stream. | ||
merged *merged | ||
} | ||
|
||
func newOutput() *output { | ||
m := new(merged) | ||
return &output{ | ||
merged: m, | ||
stdout: &outputStream{ | ||
merged: m, | ||
}, | ||
stderr: &outputStream{ | ||
merged: m, | ||
}, | ||
} | ||
} | ||
|
||
func (o *output) Stdout() string { | ||
return o.stdout.String() | ||
} | ||
|
||
func (o *output) Stderr() string { | ||
return o.stderr.String() | ||
} | ||
|
||
func (o *output) CombinedOutput() string { | ||
return o.merged.String() | ||
} | ||
|
||
type outputStream struct { | ||
Lines []string | ||
*merged | ||
} | ||
|
||
func (st *outputStream) WriteString(s string) (n int, err error) { | ||
st.Lines = append(st.Lines, string(s)) | ||
return st.merged.WriteString(s) | ||
} | ||
|
||
func (st *outputStream) String() string { | ||
return strings.Join(st.Lines, "\n") | ||
} | ||
|
||
type merged struct { | ||
// ensure that there are no parallel writes | ||
sync.Mutex | ||
Lines []string | ||
} | ||
|
||
func (m *merged) String() string { | ||
m.Lock() | ||
defer m.Unlock() | ||
|
||
return strings.Join(m.Lines, "\n") | ||
} | ||
|
||
func (m *merged) WriteString(s string) (n int, err error) { | ||
m.Lock() | ||
defer m.Unlock() | ||
|
||
m.Lines = append(m.Lines, string(s)) | ||
|
||
return len(s), nil | ||
} |