@@ -10,7 +10,7 @@ import (
1010 "time"
1111)
1212
13- //Command represents a single command which can be executed
13+ // Command represents a single command which can be executed
1414type Command struct {
1515 Command string
1616 Env []string
@@ -22,10 +22,20 @@ type Command struct {
2222 executed bool
2323 exitCode int
2424 // stderr and stdout retrieve the output after the command was executed
25- stderr bytes.Buffer
26- stdout bytes.Buffer
25+ stderr bytes.Buffer
26+ stdout bytes.Buffer
27+ combined bytes.Buffer
2728}
2829
30+ // EnvVars represents a map where the key is the name of the env variable
31+ // and the value is the value of the variable
32+ //
33+ // Example:
34+ //
35+ // env := map[string]string{"ENV": "VALUE"}
36+ //
37+ type EnvVars map [string ]string
38+
2939// NewCommand creates a new command
3040// You can add option with variadic option argument
3141// Default timeout is set to 30 minutes
@@ -68,8 +78,28 @@ func NewCommand(cmd string, options ...func(*Command)) *Command {
6878// c.Execute()
6979//
7080func WithStandardStreams (c * Command ) {
71- c .StdoutWriter = os .Stdout
72- c .StderrWriter = os .Stderr
81+ c .StdoutWriter = NewMultiplexedWriter (os .Stdout , & c .stdout , & c .combined )
82+ c .StderrWriter = NewMultiplexedWriter (os .Stderr , & c .stdout , & c .combined )
83+ }
84+
85+ // WithCustomStdout allows to add custom writers to stdout
86+ func WithCustomStdout (writers ... io.Writer ) func (c * Command ) {
87+ return func (c * Command ) {
88+ writers = append (writers , & c .stdout , & c .combined )
89+ c .StdoutWriter = NewMultiplexedWriter (writers ... )
90+
91+ c .StderrWriter = NewMultiplexedWriter (& c .stderr , & c .combined )
92+ }
93+ }
94+
95+ // WithCustomStderr allows to add custom writers to stderr
96+ func WithCustomStderr (writers ... io.Writer ) func (c * Command ) {
97+ return func (c * Command ) {
98+ writers = append (writers , & c .stderr , & c .combined )
99+ c .StderrWriter = NewMultiplexedWriter (writers ... )
100+
101+ c .StdoutWriter = NewMultiplexedWriter (& c .stdout , & c .combined )
102+ }
73103}
74104
75105// WithTimeout sets the timeout of the command
@@ -95,25 +125,52 @@ func WithWorkingDir(dir string) func(c *Command) {
95125 }
96126}
97127
128+ // WithInheritedEnvironment uses the env from the current process and
129+ // allow to add more variables.
130+ func WithInheritedEnvironment (env EnvVars ) func (c * Command ) {
131+ return func (c * Command ) {
132+ c .Env = os .Environ ()
133+
134+ // Set custom variables
135+ fn := WithEnvironmentVariables (env )
136+ fn (c )
137+ }
138+ }
139+
140+ // WithEnvironmentVariables sets environment variables for the executed command
141+ func WithEnvironmentVariables (env EnvVars ) func (c * Command ) {
142+ return func (c * Command ) {
143+ for key , value := range env {
144+ c .AddEnv (key , value )
145+ }
146+ }
147+ }
148+
98149// AddEnv adds an environment variable to the command
99150// If a variable gets passed like ${VAR_NAME} the env variable will be read out by the current shell
100151func (c * Command ) AddEnv (key string , value string ) {
101152 value = os .ExpandEnv (value )
102153 c .Env = append (c .Env , fmt .Sprintf ("%s=%s" , key , value ))
103154}
104155
105- //Stdout returns the output to stdout
156+ // Stdout returns the output to stdout
106157func (c * Command ) Stdout () string {
107158 c .isExecuted ("Stdout" )
108159 return c .stdout .String ()
109160}
110161
111- //Stderr returns the output to stderr
162+ // Stderr returns the output to stderr
112163func (c * Command ) Stderr () string {
113164 c .isExecuted ("Stderr" )
114165 return c .stderr .String ()
115166}
116167
168+ // Combined returns the combined output of stderr and stdout according to their timeline
169+ func (c * Command ) Combined () string {
170+ c .isExecuted ("Combined" )
171+ return c .combined .String ()
172+ }
173+
117174//ExitCode returns the exit code of the command
118175func (c * Command ) ExitCode () int {
119176 c .isExecuted ("ExitCode" )
0 commit comments