Skip to content

Commit d655692

Browse files
committed
feat: deprecate options timeout in favor of command options
CommandOptions now can take a context and a timeout. Deprecate current options timeout property in favor of that. The current behavior is not affected and RunWithTimeout methods should be removed in the future. Use *Command.WithTimeout and *Command.SetTimeout instead. Signed-off-by: Ayman Bagabas <[email protected]>
1 parent bbccf28 commit d655692

13 files changed

+167
-45
lines changed

command.go

+77-40
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,11 @@ import (
1717

1818
// Command contains the name, arguments and environment variables of a command.
1919
type Command struct {
20-
name string
21-
args []string
22-
envs []string
23-
ctx context.Context
20+
name string
21+
args []string
22+
envs []string
23+
timeout time.Duration
24+
ctx context.Context
2425
}
2526

2627
// CommandOptions contains options for running a command.
@@ -69,17 +70,29 @@ func (c *Command) AddEnvs(envs ...string) *Command {
6970
return c
7071
}
7172

72-
// WithContext sets the context for the command.
73-
func (c *Command) WithContext(ctx context.Context) *Command {
73+
// WithContext returns a new Command with the given context.
74+
func (c Command) WithContext(ctx context.Context) *Command {
7475
c.ctx = ctx
75-
return c
76+
return &c
77+
}
78+
79+
// WithTimeout returns a new Command with given timeout.
80+
func (c Command) WithTimeout(timeout time.Duration) *Command {
81+
c.timeout = timeout
82+
return &c
83+
}
84+
85+
// SetTimeout sets the timeout for the command.
86+
func (c *Command) SetTimeout(timeout time.Duration) {
87+
c.timeout = timeout
7688
}
7789

7890
// AddOptions adds options to the command.
7991
// Note: only the last option will take effect if there are duplicated options.
8092
func (c *Command) AddOptions(opts ...CommandOptions) *Command {
8193
for _, opt := range opts {
82-
c = c.WithContext(opt.Context)
94+
c.timeout = opt.Timeout
95+
c.ctx = opt.Context
8396
c.AddArgs(opt.Args...)
8497
c.AddEnvs(opt.Envs...)
8598
}
@@ -93,7 +106,7 @@ func (c *Command) AddCommitter(committer *Signature) *Command {
93106
}
94107

95108
// DefaultTimeout is the default timeout duration for all commands.
96-
const DefaultTimeout = time.Minute
109+
const DefaultTimeout = time.Second
97110

98111
// A limitDualWriter writes to W but limits the amount of data written to just N
99112
// bytes. On the other hand, it passes everything to w.
@@ -132,6 +145,8 @@ type RunInDirOptions struct {
132145
// Stderr is the error output from the command.
133146
Stderr io.Writer
134147
// Timeout is the duration to wait before timing out.
148+
//
149+
// Deprecated: Use CommandOptions.Timeout or *Command.WithTimeout instead.
135150
Timeout time.Duration
136151
}
137152

@@ -145,10 +160,15 @@ func (c *Command) RunInDirWithOptions(dir string, opts ...RunInDirOptions) (err
145160
if len(opts) > 0 {
146161
opt = opts[0]
147162
}
148-
if opt.Timeout < 0 {
149-
opt.Timeout = -1
150-
} else if opt.Timeout == 0 {
151-
opt.Timeout = DefaultTimeout
163+
164+
timeout := c.timeout
165+
// TODO: remove this in newer version
166+
if opt.Timeout > 0 {
167+
timeout = opt.Timeout
168+
}
169+
170+
if timeout == 0 {
171+
timeout = DefaultTimeout
152172
}
153173

154174
buf := new(bytes.Buffer)
@@ -164,9 +184,9 @@ func (c *Command) RunInDirWithOptions(dir string, opts ...RunInDirOptions) (err
164184

165185
defer func() {
166186
if len(dir) == 0 {
167-
log("[timeout: %v] %s\n%s", opt.Timeout, c, buf.Bytes())
187+
log("[timeout: %v] %s\n%s", timeout, c, buf.Bytes())
168188
} else {
169-
log("[timeout: %v] %s: %s\n%s", opt.Timeout, dir, c, buf.Bytes())
189+
log("[timeout: %v] %s: %s\n%s", timeout, dir, c, buf.Bytes())
170190
}
171191
}()
172192

@@ -175,9 +195,9 @@ func (c *Command) RunInDirWithOptions(dir string, opts ...RunInDirOptions) (err
175195
ctx = c.ctx
176196
}
177197

178-
if opt.Timeout > 0 {
198+
if timeout > 0 {
179199
var cancel context.CancelFunc
180-
ctx, cancel = context.WithTimeout(ctx, opt.Timeout)
200+
ctx, cancel = context.WithTimeout(ctx, timeout)
181201
defer func() {
182202
cancel()
183203
if err == context.DeadlineExceeded {
@@ -219,55 +239,72 @@ func (c *Command) RunInDirWithOptions(dir string, opts ...RunInDirOptions) (err
219239

220240
}
221241

242+
// RunInDirPipeline executes the command in given directory and default timeout
243+
// duration. It pipes stdout and stderr to supplied io.Writer.
244+
func (c *Command) RunInDirPipeline(stdout, stderr io.Writer, dir string) error {
245+
return c.RunInDirWithOptions(dir, RunInDirOptions{
246+
Stdin: nil,
247+
Stdout: stdout,
248+
Stderr: stderr,
249+
})
250+
}
251+
222252
// RunInDirPipelineWithTimeout executes the command in given directory and
223253
// timeout duration. It pipes stdout and stderr to supplied io.Writer.
224254
// DefaultTimeout will be used if the timeout duration is less than
225255
// time.Nanosecond (i.e. less than or equal to 0). It returns an ErrExecTimeout
226256
// if the execution was timed out.
257+
//
258+
// Deprecated: Use RunInDirPipeline and CommandOptions instead.
259+
// TODO: remove this in the next major version
227260
func (c *Command) RunInDirPipelineWithTimeout(timeout time.Duration, stdout, stderr io.Writer, dir string) (err error) {
228-
return c.RunInDirWithOptions(dir, RunInDirOptions{
229-
Stdin: nil,
230-
Stdout: stdout,
231-
Stderr: stderr,
232-
Timeout: timeout,
233-
})
234-
}
235-
236-
// RunInDirPipeline executes the command in given directory and default timeout
237-
// duration. It pipes stdout and stderr to supplied io.Writer.
238-
func (c *Command) RunInDirPipeline(stdout, stderr io.Writer, dir string) error {
239-
return c.RunInDirPipelineWithTimeout(DefaultTimeout, stdout, stderr, dir)
261+
if timeout != 0 {
262+
c = c.WithTimeout(timeout)
263+
}
264+
return c.RunInDirPipeline(stdout, stderr, dir)
240265
}
241266

242267
// RunInDirWithTimeout executes the command in given directory and timeout
243268
// duration. It returns stdout in []byte and error (combined with stderr).
269+
//
270+
// Deprecated: Use RunInDir and CommandOptions instead.
271+
// TODO: remove this in the next major version
244272
func (c *Command) RunInDirWithTimeout(timeout time.Duration, dir string) ([]byte, error) {
245-
stdout := new(bytes.Buffer)
246-
stderr := new(bytes.Buffer)
247-
if err := c.RunInDirPipelineWithTimeout(timeout, stdout, stderr, dir); err != nil {
248-
return nil, concatenateError(err, stderr.String())
273+
if timeout != 0 {
274+
c = c.WithTimeout(timeout)
249275
}
250-
return stdout.Bytes(), nil
276+
return c.RunInDir(dir)
251277
}
252278

253279
// RunInDir executes the command in given directory and default timeout
254280
// duration. It returns stdout and error (combined with stderr).
255281
func (c *Command) RunInDir(dir string) ([]byte, error) {
256-
return c.RunInDirWithTimeout(DefaultTimeout, dir)
282+
stdout := new(bytes.Buffer)
283+
stderr := new(bytes.Buffer)
284+
if err := c.RunInDirPipeline(stdout, stderr, dir); err != nil {
285+
return nil, concatenateError(err, stderr.String())
286+
}
287+
return stdout.Bytes(), nil
257288
}
258289

259290
// RunWithTimeout executes the command in working directory and given timeout
260291
// duration. It returns stdout in string and error (combined with stderr).
292+
//
293+
// Deprecated: Use RunInDir and CommandOptions instead.
294+
// TODO: remove this in the next major version
261295
func (c *Command) RunWithTimeout(timeout time.Duration) ([]byte, error) {
262-
stdout, err := c.RunInDirWithTimeout(timeout, "")
263-
if err != nil {
264-
return nil, err
296+
if timeout != 0 {
297+
c = c.WithTimeout(timeout)
265298
}
266-
return stdout, nil
299+
return c.Run()
267300
}
268301

269302
// Run executes the command in working directory and default timeout duration.
270303
// It returns stdout in string and error (combined with stderr).
271304
func (c *Command) Run() ([]byte, error) {
272-
return c.RunWithTimeout(DefaultTimeout)
305+
stdout, err := c.RunInDir("")
306+
if err != nil {
307+
return nil, err
308+
}
309+
return stdout, nil
273310
}

command_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,6 @@ func TestCommand_AddEnvs(t *testing.T) {
6060
}
6161

6262
func TestCommand_RunWithTimeout(t *testing.T) {
63-
_, err := NewCommand("version").RunWithTimeout(time.Nanosecond)
63+
_, err := NewCommand("version").WithTimeout(time.Nanosecond).Run()
6464
assert.Equal(t, ErrExecTimeout, err)
6565
}

repo.go

+28
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ type InitOptions struct {
6060
Bare bool
6161
// The timeout duration before giving up for each shell command execution. The
6262
// default timeout duration will be used when not supplied.
63+
//
64+
// Deprecated: Use CommandOptions.Timeout instead.
6365
Timeout time.Duration
6466
// The additional options to be passed to the underlying git.
6567
CommandOptions
@@ -119,6 +121,8 @@ type CloneOptions struct {
119121
Depth uint64
120122
// The timeout duration before giving up for each shell command execution. The
121123
// default timeout duration will be used when not supplied.
124+
//
125+
// Deprecated: Use CommandOptions.Timeout instead.
122126
Timeout time.Duration
123127
// The additional options to be passed to the underlying git.
124128
CommandOptions
@@ -165,6 +169,8 @@ type FetchOptions struct {
165169
Prune bool
166170
// The timeout duration before giving up for each shell command execution. The
167171
// default timeout duration will be used when not supplied.
172+
//
173+
// Deprecated: Use CommandOptions.Timeout instead.
168174
Timeout time.Duration
169175
// The additional options to be passed to the underlying git.
170176
CommandOptions
@@ -200,6 +206,8 @@ type PullOptions struct {
200206
Branch string
201207
// The timeout duration before giving up for each shell command execution. The
202208
// default timeout duration will be used when not supplied.
209+
//
210+
// Deprecated: Use CommandOptions.Timeout instead.
203211
Timeout time.Duration
204212
// The additional options to be passed to the underlying git.
205213
CommandOptions
@@ -236,6 +244,8 @@ func (r *Repository) Pull(opts ...PullOptions) error {
236244
type PushOptions struct {
237245
// The timeout duration before giving up for each shell command execution. The
238246
// default timeout duration will be used when not supplied.
247+
//
248+
// Deprecated: Use CommandOptions.Timeout instead.
239249
Timeout time.Duration
240250
// The additional options to be passed to the underlying git.
241251
CommandOptions
@@ -272,6 +282,8 @@ type CheckoutOptions struct {
272282
BaseBranch string
273283
// The timeout duration before giving up for each shell command execution. The
274284
// default timeout duration will be used when not supplied.
285+
//
286+
// Deprecated: Use CommandOptions.Timeout instead.
275287
Timeout time.Duration
276288
// The additional options to be passed to the underlying git.
277289
CommandOptions
@@ -315,6 +327,8 @@ type ResetOptions struct {
315327
Hard bool
316328
// The timeout duration before giving up for each shell command execution. The
317329
// default timeout duration will be used when not supplied.
330+
//
331+
// Deprecated: Use CommandOptions.Timeout instead.
318332
Timeout time.Duration
319333
// The additional options to be passed to the underlying git.
320334
CommandOptions
@@ -353,6 +367,8 @@ func (r *Repository) Reset(rev string, opts ...ResetOptions) error {
353367
type MoveOptions struct {
354368
// The timeout duration before giving up for each shell command execution. The
355369
// default timeout duration will be used when not supplied.
370+
//
371+
// Deprecated: Use CommandOptions.Timeout instead.
356372
Timeout time.Duration
357373
// The additional options to be passed to the underlying git.
358374
CommandOptions
@@ -391,6 +407,8 @@ type AddOptions struct {
391407
Pathspecs []string
392408
// The timeout duration before giving up for each shell command execution. The
393409
// default timeout duration will be used when not supplied.
410+
//
411+
// Deprecated: Use CommandOptions.Timeout instead.
394412
Timeout time.Duration
395413
// The additional options to be passed to the underlying git.
396414
CommandOptions
@@ -433,6 +451,8 @@ type CommitOptions struct {
433451
Author *Signature
434452
// The timeout duration before giving up for each shell command execution. The
435453
// default timeout duration will be used when not supplied.
454+
//
455+
// Deprecated: Use CommandOptions.Timeout instead.
436456
Timeout time.Duration
437457
// The additional options to be passed to the underlying git.
438458
CommandOptions
@@ -488,6 +508,8 @@ type NameStatus struct {
488508
type ShowNameStatusOptions struct {
489509
// The timeout duration before giving up for each shell command execution. The
490510
// default timeout duration will be used when not supplied.
511+
//
512+
// Deprecated: Use CommandOptions.Timeout instead.
491513
Timeout time.Duration
492514
// The additional options to be passed to the underlying git.
493515
CommandOptions
@@ -554,6 +576,8 @@ func (r *Repository) ShowNameStatus(rev string, opts ...ShowNameStatusOptions) (
554576
type RevParseOptions struct {
555577
// The timeout duration before giving up for each shell command execution. The
556578
// default timeout duration will be used when not supplied.
579+
//
580+
// Deprecated: Use CommandOptions.Timeout instead.
557581
Timeout time.Duration
558582
// The additional options to be passed to the underlying git.
559583
CommandOptions
@@ -598,6 +622,8 @@ type CountObject struct {
598622
type CountObjectsOptions struct {
599623
// The timeout duration before giving up for each shell command execution. The
600624
// default timeout duration will be used when not supplied.
625+
//
626+
// Deprecated: Use CommandOptions.Timeout instead.
601627
Timeout time.Duration
602628
// The additional options to be passed to the underlying git.
603629
CommandOptions
@@ -663,6 +689,8 @@ func (r *Repository) CountObjects(opts ...CountObjectsOptions) (*CountObject, er
663689
type FsckOptions struct {
664690
// The timeout duration before giving up for each shell command execution. The
665691
// default timeout duration will be used when not supplied.
692+
//
693+
// Deprecated: Use CommandOptions.Timeout instead.
666694
Timeout time.Duration
667695
// The additional options to be passed to the underlying git.
668696
CommandOptions

repo_blame.go

+2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ import (
1414
type BlameOptions struct {
1515
// The timeout duration before giving up for each shell command execution. The
1616
// default timeout duration will be used when not supplied.
17+
//
18+
// Deprecated: Use CommandOptions.Timeout instead.
1719
Timeout time.Duration
1820
// The additional options to be passed to the underlying git.
1921
CommandOptions

repo_blob.go

+2
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import "time"
1212
type CatFileBlobOptions struct {
1313
// The timeout duration before giving up for each shell command execution.
1414
// The default timeout duration will be used when not supplied.
15+
//
16+
// Deprecated: Use CommandOptions.Timeout instead.
1517
Timeout time.Duration
1618
// The additional options to be passed to the underlying git.
1719
CommandOptions

repo_commit.go

+2
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ loop:
7272
type CatFileCommitOptions struct {
7373
// The timeout duration before giving up for each shell command execution.
7474
// The default timeout duration will be used when not supplied.
75+
//
76+
// Deprecated: Use CommandOptions.Timeout instead.
7577
Timeout time.Duration
7678
// The additional options to be passed to the underlying git.
7779
CommandOptions

repo_diff.go

+2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ type DiffOptions struct {
2020
Base string
2121
// The timeout duration before giving up for each shell command execution. The
2222
// default timeout duration will be used when not supplied.
23+
//
24+
// Deprecated: Use CommandOptions.Timeout instead.
2325
Timeout time.Duration
2426
// The additional options to be passed to the underlying git.
2527
CommandOptions

repo_grep.go

+2
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ type GrepOptions struct {
2727
ExtendedRegexp bool
2828
// The timeout duration before giving up for each shell command execution. The
2929
// default timeout duration will be used when not supplied.
30+
//
31+
// Deprecated: Use CommandOptions.Timeout instead.
3032
Timeout time.Duration
3133
// The additional options to be passed to the underlying git.
3234
CommandOptions

repo_pull.go

+2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ import (
1515
type MergeBaseOptions struct {
1616
// The timeout duration before giving up for each shell command execution. The
1717
// default timeout duration will be used when not supplied.
18+
//
19+
// Deprecated: Use CommandOptions.Timeout instead.
1820
Timeout time.Duration
1921
// The additional options to be passed to the underlying git.
2022
CommandOptions

0 commit comments

Comments
 (0)