mirror of
https://github.com/go-task/task.git
synced 2026-08-29 10:08:27 +02:00
feat: command timeouts (#2898)
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
package ast
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"go.yaml.in/yaml/v3"
|
||||
|
||||
"github.com/go-task/task/v3/errors"
|
||||
@@ -21,6 +23,7 @@ type Cmd struct {
|
||||
IgnoreError bool
|
||||
Defer bool
|
||||
Platforms []*Platform
|
||||
Timeout time.Duration
|
||||
}
|
||||
|
||||
func (c *Cmd) DeepCopy() *Cmd {
|
||||
@@ -40,6 +43,7 @@ func (c *Cmd) DeepCopy() *Cmd {
|
||||
IgnoreError: c.IgnoreError,
|
||||
Defer: c.Defer,
|
||||
Platforms: deepcopy.Slice(c.Platforms),
|
||||
Timeout: c.Timeout,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,11 +71,26 @@ func (c *Cmd) UnmarshalYAML(node *yaml.Node) error {
|
||||
IgnoreError bool `yaml:"ignore_error"`
|
||||
Defer *Defer
|
||||
Platforms []*Platform
|
||||
Timeout string
|
||||
}
|
||||
if err := node.Decode(&cmdStruct); err != nil {
|
||||
return errors.NewTaskfileDecodeError(err, node)
|
||||
}
|
||||
|
||||
if cmdStruct.Timeout != "" {
|
||||
timeout, err := parseTimeout(cmdStruct.Timeout, node)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.Timeout = timeout
|
||||
}
|
||||
|
||||
if cmdStruct.Defer != nil {
|
||||
// Rejected rather than dropped: without the field, yaml would
|
||||
// swallow the key without a word.
|
||||
if cmdStruct.Defer.Timeout != "" {
|
||||
return errors.NewTaskfileDecodeError(nil, node).WithMessage("timeout must be set next to defer, not inside it")
|
||||
}
|
||||
|
||||
// A deferred command
|
||||
if cmdStruct.Defer.Cmd != "" {
|
||||
@@ -121,3 +140,16 @@ func (c *Cmd) UnmarshalYAML(node *yaml.Node) error {
|
||||
|
||||
return errors.NewTaskfileDecodeError(nil, node).WithTypeMessage("command")
|
||||
}
|
||||
|
||||
// parseTimeout rejects non-positive durations, which would otherwise read as no
|
||||
// timeout at all - the unbounded run the key exists to prevent.
|
||||
func parseTimeout(s string, node *yaml.Node) (time.Duration, error) {
|
||||
timeout, err := time.ParseDuration(s)
|
||||
if err != nil {
|
||||
return 0, errors.NewTaskfileDecodeError(err, node).WithMessage("invalid timeout format")
|
||||
}
|
||||
if timeout <= 0 {
|
||||
return 0, errors.NewTaskfileDecodeError(nil, node).WithMessage("timeout must be greater than zero")
|
||||
}
|
||||
return timeout, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user