diff options
| author | Paul Buetow <paul@buetow.org> | 2026-04-29 16:02:24 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-04-29 16:02:24 +0300 |
| commit | 751c82f337f9dc4756846cf7c547d31668d6587d (patch) | |
| tree | f607ea6bfad096d8e0085ca115d69aab52cccf06 | |
| parent | 3c1523cc7794da059912c70fb82a708047bc6d72 (diff) | |
The fish subcommand prints a purely static shell-integration script and
needs no backend, cipher, store, git, or shell. Previously cli.New ran
in main() before dispatch, triggering the KeePass Argon2 KDF and adding
~1.8s to every interactive fish shell startup that sources the script.
Export FishIntegrationScript and dispatch `fish` directly from main()
before constructing the CLI. Local timing: `foostore fish` drops from
~1.834s to ~0.003s.
Bump version to v0.8.1.
Amp-Thread-ID: https://ampcode.com/threads/T-019dd950-11ef-77aa-bb92-810f22601023
Co-authored-by: Amp <amp@ampcode.com>
| -rw-r--r-- | cmd/foostore/main.go | 14 | ||||
| -rw-r--r-- | internal/cli/cli_fish.go | 12 | ||||
| -rw-r--r-- | internal/version/version.go | 2 |
3 files changed, 24 insertions, 4 deletions
diff --git a/cmd/foostore/main.go b/cmd/foostore/main.go index 82283da..1e7a184 100644 --- a/cmd/foostore/main.go +++ b/cmd/foostore/main.go @@ -28,6 +28,20 @@ func main() { os.Exit(0) } + // Short-circuit the "fish" subcommand: it emits a purely static shell + // integration script and needs no backend, cipher, store, git, or shell + // initialisation. Skipping cli.New avoids the KeePass Argon2 KDF cost + // (~1.8s), which makes every interactive fish shell startup that sources + // `foostore fish | source` correspondingly faster. + if len(args) == 1 && args[0] == "fish" { + binaryPath, err := os.Executable() + if err != nil { + binaryPath = "foostore" + } + fmt.Print(cli.FishIntegrationScript(binaryPath)) + os.Exit(0) + } + // 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) diff --git a/internal/cli/cli_fish.go b/internal/cli/cli_fish.go index b2d3616..0590345 100644 --- a/internal/cli/cli_fish.go +++ b/internal/cli/cli_fish.go @@ -28,14 +28,14 @@ func (c *CLI) cmdFish(stdout io.Writer) int { if err != nil { binaryPath = "foostore" } - script := fishIntegrationScript(binaryPath) + script := FishIntegrationScript(binaryPath) if _, err := io.WriteString(stdout, script); err != nil { return 1 } return 0 } -// fishIntegrationScript returns the complete fish shell integration script for +// FishIntegrationScript returns the complete fish shell integration script for // the given binary path. The script combines the foostore completion rules and // the ge wrapper function so users need only source a single output: // @@ -44,7 +44,13 @@ func (c *CLI) cmdFish(stdout io.Writer) int { // The binary name is extracted from binaryPath (basename without path) and used // wherever "foostore" appears in complete directives, making the script // correct even when the binary is renamed. -func fishIntegrationScript(binaryPath string) string { +// +// This function is exported so cmd/foostore/main.go can short-circuit the +// "fish" subcommand before constructing a CLI — the script is purely static +// and needs no backend, cipher, store, git, or shell initialisation. Avoiding +// that init shaves ~1.8s (KeePass Argon2 KDF) off every interactive fish +// shell startup that sources `foostore fish`. +func FishIntegrationScript(binaryPath string) string { bin := filepath.Base(binaryPath) var b strings.Builder diff --git a/internal/version/version.go b/internal/version/version.go index d019841..0a0a258 100644 --- a/internal/version/version.go +++ b/internal/version/version.go @@ -2,4 +2,4 @@ package version // Version is the current release version of foostore. -const Version = "v0.7.0" +const Version = "v0.8.1" |
