summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmd/geheim/main.go22
-rw-r--r--internal/cli/cli.go25
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,