pkg/cli/cli.go

69 lines
1.3 KiB
Go

// Package cli provides the common boilerplate code around executing a cobra command.
package cli
import (
"context"
"errors"
"fmt"
"log/slog"
"os"
"os/signal"
"syscall"
"github.com/spf13/cobra"
"git.ifooth.com/common/pkg/version"
)
var (
// errSignal ...
errSignal = errors.New("signal")
)
// Run provides the common boilerplate code around executing a cobra command.
func Run(cmd *cobra.Command) int {
// 不开启 自动排序
cobra.EnableCommandSorting = false
cmd.CompletionOptions.DisableDefaultCmd = true
cmd.SilenceErrors = true
cmd.SilenceUsage = true
// 添加版本
cmd.SetVersionTemplate(`{{println .Version}}`)
cmd.Version = version.GetVersion()
if err := execute(cmd); err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
return 1
}
return 0
}
func execute(cmd *cobra.Command) error {
ctx, cancel := context.WithCancelCause(context.Background())
// graceful shutdown signal
signalChan := make(chan os.Signal, 1)
signal.Notify(signalChan, syscall.SIGINT, syscall.SIGTERM)
go func() {
select {
case s := <-signalChan:
slog.WarnContext(ctx, "Signal received", "signal", s)
cancel(fmt.Errorf("%w %s received", errSignal, s))
case <-ctx.Done():
}
}()
err := cmd.ExecuteContext(ctx)
if err == nil {
return nil
}
if errors.Is(err, errSignal) {
return nil
}
return err
}