go/pkg/cli/app.go
Snider 74256fb708
Standardize CLI Error Handling (#318)
* Standardize CLI error handling and deprecate cli.Fatal

- Updated `pkg/cli/output.go` to send error and warning output to `os.Stderr`.
- Added `ErrorWrap`, `ErrorWrapVerb`, and `ErrorWrapAction` helpers to `pkg/cli/output.go`.
- Deprecated `cli.Fatal` family of functions in `pkg/cli/errors.go`.
- Introduced `cli.ExitError` and `cli.Exit` helper to allow commands to return specific exit codes.
- Updated `pkg/cli/app.go` to silence Cobra errors and handle error printing and process exit in `Main`.
- Refactored multiple commands (QA, SDK, CI, Updater) to return errors instead of exiting abruptly.
- Replaced direct `os.Stderr` writes with standardized CLI or log helpers across the codebase.
- Updated tests to accommodate changes in output destination.

* Fix CI failure: remove unused fmt import in pkg/mcp/transport_tcp.go

- Removed unused "fmt" import in `pkg/mcp/transport_tcp.go` that was causing CI failure.
- Verified build and relevant tests pass.

* Standardize CLI error handling and fix formatting issues

- Updated `pkg/cli/output.go` to send error and warning output to `os.Stderr`.
- Added `ErrorWrap`, `ErrorWrapVerb`, and `ErrorWrapAction` helpers to `pkg/cli/output.go`.
- Deprecated `cli.Fatal` family of functions in `pkg/cli/errors.go`.
- Introduced `cli.ExitError` and `cli.Exit` helper to allow commands to return specific exit codes.
- Updated `pkg/cli/app.go` to silence Cobra errors and handle error printing and process exit in `Main`.
- Refactored multiple commands (QA, SDK, CI, Updater) to return errors instead of exiting abruptly.
- Replaced direct `os.Stderr` writes with standardized CLI or log helpers across the codebase.
- Updated tests to accommodate changes in output destination.
- Fixed formatting in `pkg/io/local/client.go`.
- Removed unused `fmt` import in `pkg/mcp/transport_tcp.go`.

* Standardize CLI error handling and fix CI issues

- Updated `pkg/cli/output.go` to send error and warning output to `os.Stderr`.
- Added `ErrorWrap`, `ErrorWrapVerb`, and `ErrorWrapAction` helpers to `pkg/cli/output.go`.
- Deprecated `cli.Fatal` family of functions in `pkg/cli/errors.go`.
- Introduced `cli.ExitError` and `cli.Exit` helper to allow commands to return specific exit codes.
- Updated `pkg/cli/app.go` to silence Cobra errors and handle error printing and process exit in `Main`.
- Refactored multiple commands (QA, SDK, CI, Updater) to return errors instead of exiting abruptly.
- Replaced direct `os.Stderr` writes with standardized CLI or log helpers across the codebase.
- Updated tests to accommodate changes in output destination.
- Fixed formatting in `pkg/io/local/client.go`.
- Removed unused `fmt` import in `pkg/mcp/transport_tcp.go`.
- Fixed potential `gh` context issue in `.github/workflows/auto-merge.yml` by providing `GH_REPO`.

---------

Co-authored-by: Claude <developers@lethean.io>
2026-02-05 06:55:49 +00:00

110 lines
2.9 KiB
Go

package cli
import (
"os"
"github.com/host-uk/core/pkg/framework"
"github.com/host-uk/core/pkg/log"
"github.com/spf13/cobra"
)
const (
// AppName is the CLI application name.
AppName = "core"
)
// AppVersion is set at build time via ldflags:
//
// go build -ldflags="-X github.com/host-uk/core/pkg/cli.AppVersion=v1.0.0"
var AppVersion = "dev"
// Main initialises and runs the CLI application.
// This is the main entry point for the CLI.
// Exits with code 1 on error.
func Main() {
// Initialise CLI runtime with services
if err := Init(Options{
AppName: AppName,
Version: AppVersion,
Services: []framework.Option{
framework.WithName("i18n", NewI18nService(I18nOptions{})),
framework.WithName("log", NewLogService(log.Options{
Level: log.LevelInfo,
})),
},
}); err != nil {
Error(err.Error())
os.Exit(1)
}
defer Shutdown()
// Add completion command to the CLI's root
RootCmd().AddCommand(completionCmd)
if err := Execute(); err != nil {
code := 1
var exitErr *ExitError
if As(err, &exitErr) {
code = exitErr.Code
}
Error(err.Error())
os.Exit(code)
}
}
// completionCmd generates shell completion scripts.
var completionCmd = &cobra.Command{
Use: "completion [bash|zsh|fish|powershell]",
Short: "Generate shell completion script",
Long: `Generate shell completion script for the specified shell.
To load completions:
Bash:
$ source <(core completion bash)
# To load completions for each session, execute once:
# Linux:
$ core completion bash > /etc/bash_completion.d/core
# macOS:
$ core completion bash > $(brew --prefix)/etc/bash_completion.d/core
Zsh:
# If shell completion is not already enabled in your environment,
# you will need to enable it. You can execute the following once:
$ echo "autoload -U compinit; compinit" >> ~/.zshrc
# To load completions for each session, execute once:
$ core completion zsh > "${fpath[1]}/_core"
# You will need to start a new shell for this setup to take effect.
Fish:
$ core completion fish | source
# To load completions for each session, execute once:
$ core completion fish > ~/.config/fish/completions/core.fish
PowerShell:
PS> core completion powershell | Out-String | Invoke-Expression
# To load completions for every new session, run:
PS> core completion powershell > core.ps1
# and source this file from your PowerShell profile.
`,
DisableFlagsInUseLine: true,
ValidArgs: []string{"bash", "zsh", "fish", "powershell"},
Args: cobra.MatchAll(cobra.ExactArgs(1), cobra.OnlyValidArgs),
Run: func(cmd *cobra.Command, args []string) {
switch args[0] {
case "bash":
_ = cmd.Root().GenBashCompletion(os.Stdout)
case "zsh":
_ = cmd.Root().GenZshCompletion(os.Stdout)
case "fish":
_ = cmd.Root().GenFishCompletion(os.Stdout, true)
case "powershell":
_ = cmd.Root().GenPowerShellCompletionWithDesc(os.Stdout)
}
},
}