@@ -22,6 +22,12 @@ type Command struct {
22
22
envs []string
23
23
}
24
24
25
+ // CommandOptions contains options for running a command.
26
+ type CommandOptions struct {
27
+ Args []string
28
+ Envs []string
29
+ }
30
+
25
31
// String returns the string representation of the command.
26
32
func (c * Command ) String () string {
27
33
if len (c .args ) == 0 {
@@ -50,6 +56,15 @@ func (c *Command) AddEnvs(envs ...string) *Command {
50
56
return c
51
57
}
52
58
59
+ // AddOptions adds options to the command.
60
+ func (c * Command ) AddOptions (opts ... CommandOptions ) * Command {
61
+ for _ , opt := range opts {
62
+ c .AddArgs (opt .Args ... )
63
+ c .AddEnvs (opt .Envs ... )
64
+ }
65
+ return c
66
+ }
67
+
53
68
// AddCommitter appends given committer to the command.
54
69
func (c * Command ) AddCommitter (committer * Signature ) * Command {
55
70
c .AddEnvs ("GIT_COMMITTER_NAME=" + committer .Name , "GIT_COMMITTER_EMAIL=" + committer .Email )
@@ -87,36 +102,52 @@ func (w *limitDualWriter) Write(p []byte) (int, error) {
87
102
return w .w .Write (p )
88
103
}
89
104
90
- // RunInDirPipelineWithTimeout executes the command in given directory and
91
- // timeout duration. It pipes stdout and stderr to supplied io.Writer.
92
- // DefaultTimeout will be used if the timeout duration is less than
105
+ // RunInDirOptions contains options for running a command in a directory.
106
+ type RunInDirOptions struct {
107
+ // Stdin is the input to the command.
108
+ Stdin io.Reader
109
+ // Stdout is the outputs from the command.
110
+ Stdout io.Writer
111
+ // Stderr is the error output from the command.
112
+ Stderr io.Writer
113
+ // Timeout is the duration to wait before timing out.
114
+ Timeout time.Duration
115
+ }
116
+
117
+ // RunInDirWithOptions executes the command in given directory and options. It
118
+ // pipes stdin from supplied io.Reader, and pipes stdout and stderr to supplied
119
+ // io.Writer. DefaultTimeout will be used if the timeout duration is less than
93
120
// time.Nanosecond (i.e. less than or equal to 0). It returns an ErrExecTimeout
94
121
// if the execution was timed out.
95
- func (c * Command ) RunInDirPipelineWithTimeout (timeout time.Duration , stdout , stderr io.Writer , dir string ) (err error ) {
96
- if timeout < time .Nanosecond {
97
- timeout = DefaultTimeout
122
+ func (c * Command ) RunInDirWithOptions (dir string , opts ... RunInDirOptions ) (err error ) {
123
+ var opt RunInDirOptions
124
+ if len (opts ) > 0 {
125
+ opt = opts [0 ]
126
+ }
127
+ if opt .Timeout < time .Nanosecond {
128
+ opt .Timeout = DefaultTimeout
98
129
}
99
130
100
131
buf := new (bytes.Buffer )
101
- w := stdout
132
+ w := opt . Stdout
102
133
if logOutput != nil {
103
134
buf .Grow (512 )
104
135
w = & limitDualWriter {
105
136
W : buf ,
106
137
N : int64 (buf .Cap ()),
107
- w : stdout ,
138
+ w : opt . Stdout ,
108
139
}
109
140
}
110
141
111
142
defer func () {
112
143
if len (dir ) == 0 {
113
- log ("[timeout: %v] %s\n %s" , timeout , c , buf .Bytes ())
144
+ log ("[timeout: %v] %s\n %s" , opt . Timeout , c , buf .Bytes ())
114
145
} else {
115
- log ("[timeout: %v] %s: %s\n %s" , timeout , dir , c , buf .Bytes ())
146
+ log ("[timeout: %v] %s: %s\n %s" , opt . Timeout , dir , c , buf .Bytes ())
116
147
}
117
148
}()
118
149
119
- ctx , cancel := context .WithTimeout (context .Background (), timeout )
150
+ ctx , cancel := context .WithTimeout (context .Background (), opt . Timeout )
120
151
defer func () {
121
152
cancel ()
122
153
if err == context .DeadlineExceeded {
@@ -129,8 +160,9 @@ func (c *Command) RunInDirPipelineWithTimeout(timeout time.Duration, stdout, std
129
160
cmd .Env = append (os .Environ (), c .envs ... )
130
161
}
131
162
cmd .Dir = dir
163
+ cmd .Stdin = opt .Stdin
132
164
cmd .Stdout = w
133
- cmd .Stderr = stderr
165
+ cmd .Stderr = opt . Stderr
134
166
if err = cmd .Start (); err != nil {
135
167
return err
136
168
}
@@ -153,6 +185,21 @@ func (c *Command) RunInDirPipelineWithTimeout(timeout time.Duration, stdout, std
153
185
case err = <- result :
154
186
return err
155
187
}
188
+
189
+ }
190
+
191
+ // RunInDirPipelineWithTimeout executes the command in given directory and
192
+ // timeout duration. It pipes stdout and stderr to supplied io.Writer.
193
+ // DefaultTimeout will be used if the timeout duration is less than
194
+ // time.Nanosecond (i.e. less than or equal to 0). It returns an ErrExecTimeout
195
+ // if the execution was timed out.
196
+ func (c * Command ) RunInDirPipelineWithTimeout (timeout time.Duration , stdout , stderr io.Writer , dir string ) (err error ) {
197
+ return c .RunInDirWithOptions (dir , RunInDirOptions {
198
+ Stdin : nil ,
199
+ Stdout : stdout ,
200
+ Stderr : stderr ,
201
+ Timeout : timeout ,
202
+ })
156
203
}
157
204
158
205
// RunInDirPipeline executes the command in given directory and default timeout
0 commit comments