diff --git a/app.go b/app.go index a62aa237f1..09b13be617 100644 --- a/app.go +++ b/app.go @@ -1,6 +1,7 @@ package cli import ( + "context" "flag" "fmt" "io" @@ -207,6 +208,13 @@ func (a *App) useShortOptionHandling() bool { // Run is the entry point to the cli app. Parses the arguments slice and routes // to the proper flag/args combination func (a *App) Run(arguments []string) (err error) { + return a.RunContext(context.Background(), arguments) +} + +// RunContext is like Run except it takes a Context that will be +// passed to its commands and sub-commands. Through this, you can +// propagate timeouts and cancellation requests +func (a *App) RunContext(ctx context.Context, arguments []string) (err error) { a.Setup() // handle the completion flag separately from the flagset since @@ -224,7 +232,7 @@ func (a *App) Run(arguments []string) (err error) { err = parseIter(set, a, arguments[1:], shellComplete) nerr := normalizeFlags(a.Flags, set) - context := NewContext(a, set, nil) + context := NewContext(a, set, &Context{Context: ctx}) if nerr != nil { _, _ = fmt.Fprintln(a.Writer, nerr) _ = ShowAppHelp(context) diff --git a/context.go b/context.go index 13fb52358d..5b59e753b4 100644 --- a/context.go +++ b/context.go @@ -5,10 +5,7 @@ import ( "errors" "flag" "fmt" - "os" - "os/signal" "strings" - "syscall" ) // Context is a type that is passed through to @@ -36,14 +33,7 @@ func NewContext(app *App, set *flag.FlagSet, parentCtx *Context) *Context { c.Command = &Command{} if c.Context == nil { - ctx, cancel := context.WithCancel(context.Background()) - go func() { - defer cancel() - sigs := make(chan os.Signal, 1) - signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM) - <-sigs - }() - c.Context = ctx + c.Context = context.Background() } return c