diff options
| -rw-r--r-- | cmd/geheim/main.go | 22 | ||||
| -rw-r--r-- | internal/cli/cli.go | 25 |
2 files changed, 32 insertions, 15 deletions
diff --git a/cmd/geheim/main.go b/cmd/geheim/main.go index 4032f53..4c432e8 100644 --- a/cmd/geheim/main.go +++ b/cmd/geheim/main.go @@ -1,13 +1,29 @@ -// main is the entry point for the geheim binary. -// It delegates all logic to the cli package and exits with the returned code. +// main is the thin entry point for the geheim binary. +// It sets up a signal-cancellable context, initialises the CLI, and exits +// with the code returned by Run. All command logic lives in internal/cli. package main import ( + "context" + "fmt" "os" + "os/signal" + "syscall" "codeberg.org/snonux/geheim/internal/cli" ) func main() { - os.Exit(cli.Run()) + // Cancel the context on SIGINT or SIGTERM so that long-running operations + // (fzf, external editors) terminate gracefully rather than being killed hard. + ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM) + defer stop() + + c, err := cli.New(ctx) + if err != nil { + fmt.Fprintf(os.Stderr, "FATAL %v\n", err) + os.Exit(3) + } + + os.Exit(c.Run(ctx, os.Args[1:])) } diff --git a/internal/cli/cli.go b/internal/cli/cli.go index 040d58b..7d59b94 100644 --- a/internal/cli/cli.go +++ b/internal/cli/cli.go @@ -59,20 +59,21 @@ type CLI struct { lastResult string // most recent search result description } -// Run is the package-level entry point called by cmd/geheim/main.go. -// It creates a CLI, then either dispatches a single command from os.Args -// or enters the interactive shell loop, and returns an exit code. -func Run() int { - ctx := context.Background() +// New initialises all runtime dependencies (config, PIN, cipher, store, git, +// clipboard, shell) and returns a ready-to-use CLI. cmd/geheim/main.go calls +// New with a signal-cancellable context so that long-running operations (fzf, +// external editors) are interrupted cleanly on SIGINT/SIGTERM. +func New(ctx context.Context) (*CLI, error) { + return newCLI(ctx) +} - c, err := newCLI(ctx) - if err != nil { - fatal(err.Error()) // fatal calls os.Exit(3) and does not return - return 3 //nolint:govet // unreachable; present for compiler flow analysis - } +// Run dispatches argv (typically os.Args[1:]) to the appropriate handler or +// enters the interactive shell loop. Returns an exit code suitable for +// os.Exit. The caller is responsible for calling sh.Close() when done; +// cmd/geheim/main.go does this via defer. +func (c *CLI) Run(ctx context.Context, argv []string) int { defer c.sh.Close() - - return c.run(ctx, os.Args[1:]) + return c.run(ctx, argv) } // newCLI initialises all dependencies: config, PIN, cipher, store, git, |
