| 16 | ) |
| 17 | |
| 18 | func executeRootCmdWithContext() error { |
| 19 | // trap Ctrl+C and other signals, then call cancel on the context |
| 20 | ctx, cancel := context.WithCancel(context.Background()) |
| 21 | c := make(chan os.Signal, 1) |
| 22 | signal.Notify(c, os.Interrupt, syscall.SIGTERM) |
| 23 | defer func() { |
| 24 | signal.Stop(c) |
| 25 | }() |
| 26 | var gotSignal os.Signal |
| 27 | var wg sync.WaitGroup |
| 28 | wg.Go(func() { |
| 29 | select { |
| 30 | case gotSignal = <-c: |
| 31 | cancel() |
| 32 | case <-ctx.Done(): |
| 33 | } |
| 34 | }) |
| 35 | |
| 36 | err := cmd.NewCmdRoot().ExecuteContext(ctx) |
| 37 | cancel() |
| 38 | wg.Wait() |
| 39 | if gotSignal != nil && err != nil { |
| 40 | err = fmt.Errorf("received %v signal from OS: %w", gotSignal.String(), err) |
| 41 | } else if gotSignal != nil { |
| 42 | err = fmt.Errorf("received %v signal from OS", gotSignal.String()) |
| 43 | } |
| 44 | return err |
| 45 | } |
| 46 | |
| 47 | func main() { |
| 48 | exitCode := 0 |