Rename pika to keld across the codebase

Amolith created

Change summary

.gitignore                     |  2 +-
AGENTS.md                      | 22 +++++++++++-----------
cmd/completions.go             | 16 ++++++++--------
cmd/completions_test.go        |  8 ++++----
cmd/root.go                    | 34 +++++++++++++++++-----------------
cmd/root_test.go               |  4 ++--
example/config.toml            |  8 ++++----
go.mod                         |  2 +-
internal/config/config.go      |  4 ++--
internal/config/config_test.go |  4 ++--
internal/config/files.go       | 14 +++++++-------
internal/config/files_test.go  |  8 ++++----
internal/form/form.go          |  2 +-
internal/restic/exec.go        |  8 ++++----
internal/restic/exec_test.go   |  6 +++---
main.go                        |  2 +-
mise.toml                      |  2 +-
17 files changed, 73 insertions(+), 73 deletions(-)

Detailed changes

AGENTS.md 🔗

@@ -1,8 +1,8 @@
-# AGENTS.md - Working with Pika
+# AGENTS.md - Working with Keld
 
 ## Project Overview
 
-**Pika** is a friendly TOML-configured wrapper around
+**Keld** is a friendly TOML-configured wrapper around
 [restic](https://restic.net/) (a backup tool). It provides:
 
 - Layered configuration with presets and command-specific overrides
@@ -58,7 +58,7 @@ main.go
 ### Section Merge Order
 
 Config sections are merged in ascending priority order. For
-`pika home@cloud backup`:
+`keld home@cloud backup`:
 
 ```text
 [global] → [global.backup] → [@cloud] → [@cloud.backup] →
@@ -68,10 +68,10 @@ CLI overrides
 
 ### Config File Discovery
 
-1. Default dirs: `/usr/share/pika`, `/etc/pika`, `~/.config/pika`
+1. Default dirs: `/usr/share/keld`, `/etc/keld`, `~/.config/keld`
 2. In each dir: `config.toml` then sorted `conf.d/*.toml`
-3. `PIKA_CONFIG_PATHS` env var (colon-separated, supports globs)
-4. `PIKA_CONFIG_FILE` replaces all above if set
+3. `KELD_CONFIG_PATHS` env var (colon-separated, supports globs)
+4. `KELD_CONFIG_FILE` replaces all above if set
 
 ### Special Config Keys
 
@@ -142,13 +142,13 @@ Using v2 API (not v1). Key differences:
 
 | Variable            | Purpose                                 |
 | ------------------- | --------------------------------------- |
-| `PIKA_CONFIG_FILE`  | Single config file (highest priority)   |
-| `PIKA_CONFIG_PATHS` | Colon-separated additional config paths |
-| `PIKA_DRYRUN`       | Set to enable dry-run mode              |
-| `PIKA_EXECUTABLE`   | Override restic binary path             |
+| `KELD_CONFIG_FILE`  | Single config file (highest priority)   |
+| `KELD_CONFIG_PATHS` | Colon-separated additional config paths |
+| `KELD_DRYRUN`       | Set to enable dry-run mode              |
+| `KELD_EXECUTABLE`   | Override restic binary path             |
 
 ## Development Workflow
 
 1. Make changes
 2. `mise run check` - full validation
-3. Test manually: `./pika --dry-run <preset> <command>`
+3. Test manually: `./keld --dry-run <preset> <command>`

cmd/completions.go 🔗

@@ -6,10 +6,10 @@ import (
 
 	"github.com/spf13/cobra"
 
-	"git.secluded.site/pika/internal/config"
+	"git.secluded.site/keld/internal/config"
 )
 
-// knownCommands lists the restic subcommands pika knows about. This is the
+// knownCommands lists the restic subcommands keld knows about. This is the
 // same set shown in the interactive menu (minus "quit").
 var knownCommands = []string{
 	"backup",
@@ -20,9 +20,9 @@ var knownCommands = []string{
 	"snapshots",
 }
 
-// pikaFlags lists pika's own flags (the ones extracted in extractOwnFlags).
+// keldFlags lists keld's own flags (the ones extracted in extractOwnFlags).
 // Cobra can't advertise these automatically because DisableFlagParsing is on.
-var pikaFlags = []string{
+var keldFlags = []string{
 	"--config",
 	"--dry-run",
 	"--help",
@@ -32,7 +32,7 @@ func init() {
 	rootCmd.ValidArgsFunction = completeArgs
 }
 
-// completeArgs provides dynamic shell completions for pika.
+// completeArgs provides dynamic shell completions for keld.
 //
 // It examines how many positional (non-flag) arguments have already been
 // provided and offers:
@@ -46,11 +46,11 @@ func init() {
 //   - if it's already a command, no more positional completions
 //   - 2+ positionals       → no further positional completions
 //
-// When the current word starts with "-", pika's own flags are offered instead.
+// When the current word starts with "-", keld's own flags are offered instead.
 func completeArgs(_ *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
-	// When the user is typing a flag, offer pika's own flags.
+	// When the user is typing a flag, offer keld's own flags.
 	if len(toComplete) > 0 && toComplete[0] == '-' {
-		return pikaFlags, cobra.ShellCompDirectiveNoFileComp
+		return keldFlags, cobra.ShellCompDirectiveNoFileComp
 	}
 
 	// Count how many positional args have already been accepted (i.e. are

cmd/completions_test.go 🔗

@@ -10,7 +10,7 @@ import (
 	"github.com/spf13/cobra"
 )
 
-// setupCompletionConfig writes a small TOML fixture and points PIKA_CONFIG_FILE
+// setupCompletionConfig writes a small TOML fixture and points KELD_CONFIG_FILE
 // at it, so config.Presets() returns deterministic results.
 func setupCompletionConfig(t *testing.T) {
 	t.Helper()
@@ -36,7 +36,7 @@ json = true
 	if err != nil {
 		t.Fatalf("writing fixture config: %v", err)
 	}
-	t.Setenv("PIKA_CONFIG_FILE", cfg)
+	t.Setenv("KELD_CONFIG_FILE", cfg)
 	t.Setenv("HOME", dir)
 }
 
@@ -144,10 +144,10 @@ func TestCompleteArgsFlagPrefix(t *testing.T) {
 func TestCompleteArgsSkipsFlags(t *testing.T) {
 	setupCompletionConfig(t)
 
-	// Simulate: pika --config ./pika.toml <tab>
+	// Simulate: keld --config ./keld.toml <tab>
 	// The flag and its value should not count as positionals, so we
 	// should still be at 0 positionals → presets + commands.
-	completions, directive := completeArgs(nil, []string{"--config", "./pika.toml"}, "")
+	completions, directive := completeArgs(nil, []string{"--config", "./keld.toml"}, "")
 	if directive != cobra.ShellCompDirectiveNoFileComp {
 		t.Fatalf("expected NoFileComp, got %v", directive)
 	}

cmd/root.go 🔗

@@ -10,10 +10,10 @@ import (
 	"charm.land/fang/v2"
 	"github.com/spf13/cobra"
 
-	"git.secluded.site/pika/internal/config"
-	"git.secluded.site/pika/internal/form"
-	"git.secluded.site/pika/internal/menu"
-	"git.secluded.site/pika/internal/restic"
+	"git.secluded.site/keld/internal/config"
+	"git.secluded.site/keld/internal/form"
+	"git.secluded.site/keld/internal/menu"
+	"git.secluded.site/keld/internal/restic"
 )
 
 var (
@@ -23,7 +23,7 @@ var (
 
 const overrideArgumentsKey = "_arguments"
 
-// menuItems defines the interactive command picker shown when pika is invoked
+// menuItems defines the interactive command picker shown when keld is invoked
 // with no arguments.
 var menuItems = []menu.Item{
 	{Label: "backup", Hotkey: 'b'},
@@ -36,15 +36,15 @@ var menuItems = []menu.Item{
 }
 
 var rootCmd = &cobra.Command{
-	Use:   "pika [preset] <command> [restic flags...]",
+	Use:   "keld [preset] <command> [restic flags...]",
 	Short: "A friendly wrapper around restic",
-	Long:  "pika resolves layered TOML config presets and executes restic with the merged result.",
-	Example: `  pika backup
-  pika home backup
-  pika home@nas backup --tag daily --verbose
-  pika --config ./pika.toml home backup
-  pika --dry-run home backup
-  pika --help`,
+	Long:  "keld resolves layered TOML config presets and executes restic with the merged result.",
+	Example: `  keld backup
+  keld home backup
+  keld home@nas backup --tag daily --verbose
+  keld --config ./keld.toml home backup
+  keld --dry-run home backup
+  keld --help`,
 
 	// Accept arbitrary args — we parse preset/command ourselves.
 	Args:               cobra.ArbitraryArgs,
@@ -63,13 +63,13 @@ var rootCmd = &cobra.Command{
 		}
 
 		if flagConfigFile != "" {
-			if err := os.Setenv("PIKA_CONFIG_FILE", flagConfigFile); err != nil {
-				return fmt.Errorf("setting PIKA_CONFIG_FILE: %w", err)
+			if err := os.Setenv("KELD_CONFIG_FILE", flagConfigFile); err != nil {
+				return fmt.Errorf("setting KELD_CONFIG_FILE: %w", err)
 			}
 		}
 		if flagDryRun {
-			if err := os.Setenv("PIKA_DRYRUN", "1"); err != nil {
-				return fmt.Errorf("setting PIKA_DRYRUN: %w", err)
+			if err := os.Setenv("KELD_DRYRUN", "1"); err != nil {
+				return fmt.Errorf("setting KELD_DRYRUN: %w", err)
 			}
 		}
 

cmd/root_test.go 🔗

@@ -248,7 +248,7 @@ json = true
 	if err != nil {
 		t.Fatalf("writing fixture: %v", err)
 	}
-	t.Setenv("PIKA_CONFIG_FILE", cfg)
+	t.Setenv("KELD_CONFIG_FILE", cfg)
 	t.Setenv("HOME", dir)
 
 	tests := []struct {
@@ -280,7 +280,7 @@ func TestValidatePresetNoConfig(t *testing.T) {
 	if err := os.WriteFile(cfg, []byte("[global]\n"), 0o600); err != nil {
 		t.Fatalf("writing fixture: %v", err)
 	}
-	t.Setenv("PIKA_CONFIG_FILE", cfg)
+	t.Setenv("KELD_CONFIG_FILE", cfg)
 	t.Setenv("HOME", dir)
 
 	err := validatePreset("anything")

example/config.toml 🔗

@@ -1,7 +1,7 @@
-# pika config merge order (lowest to highest precedence):
+# keld config merge order (lowest to highest precedence):
 #   [global] -> [global.<command>] -> split preset parts -> full preset -> CLI overrides
 #
-# For a split preset like `home@cloud` and command `backup`, pika checks:
+# For a split preset like `home@cloud` and command `backup`, keld checks:
 #   [global] -> [global.backup] -> [@cloud] -> [@cloud.backup] ->
 #   [home@] -> [home@.backup] -> [home@cloud] -> [home@cloud.backup]
 
@@ -16,7 +16,7 @@ exclude-file = "~/.config/restic/excludes.txt"
 exclude-if-present = ".nobackup"
 
 [home.backup]
-# Simple preset: `pika home backup`
+# Simple preset: `keld home backup`
 _arguments = ["/home/amolith"]
 tag = ["home"]
 
@@ -43,7 +43,7 @@ tag = ["home"]
 ["home@".backup]
 # Prefix + command section.
 _arguments = ["/home/amolith", "/etc"]
-exclude-if-present = ".pika-skip"
+exclude-if-present = ".keld-skip"
 
 ["home@".forget]
 # Prefix + different command section.

go.mod 🔗

@@ -1,4 +1,4 @@
-module git.secluded.site/pika
+module git.secluded.site/keld
 
 go 1.26.1
 

internal/config/config.go 🔗

@@ -363,7 +363,7 @@ func toStringSlice(v any) []string {
 	}
 }
 
-// IsDryRun reports whether the PIKA_DRYRUN environment variable is set.
+// IsDryRun reports whether the KELD_DRYRUN environment variable is set.
 func IsDryRun() bool {
-	return os.Getenv("PIKA_DRYRUN") != ""
+	return os.Getenv("KELD_DRYRUN") != ""
 }

internal/config/config_test.go 🔗

@@ -21,8 +21,8 @@ func TestResolve(t *testing.T) {
 	}
 
 	t.Setenv("HOME", homeDir)
-	t.Setenv("PIKA_CONFIG_FILE", configPath)
-	t.Setenv("PIKA_CONFIG_PATHS", "")
+	t.Setenv("KELD_CONFIG_FILE", configPath)
+	t.Setenv("KELD_CONFIG_PATHS", "")
 
 	tests := []struct {
 		name         string

internal/config/files.go 🔗

@@ -10,17 +10,17 @@ import (
 // DefaultConfigDirs lists the base directories searched for config files,
 // in ascending priority order.
 var DefaultConfigDirs = []string{
-	"/usr/share/pika",
-	"/etc/pika",
-	"~/.config/pika",
+	"/usr/share/keld",
+	"/etc/keld",
+	"~/.config/keld",
 }
 
 // DiscoverFiles returns config file paths in ascending priority order.
 //
 // The search order is:
 //  1. For each directory in DefaultConfigDirs: config.toml, then sorted conf.d/*.toml
-//  2. Paths/globs from the PIKA_CONFIG_PATHS env var (colon-separated)
-//  3. If PIKA_CONFIG_FILE is set, it replaces ALL of the above
+//  2. Paths/globs from the KELD_CONFIG_PATHS env var (colon-separated)
+//  3. If KELD_CONFIG_FILE is set, it replaces ALL of the above
 //
 // All paths support ~ (home dir) and $VAR expansion.
 func DiscoverFiles() []string {
@@ -29,7 +29,7 @@ func DiscoverFiles() []string {
 
 // discoverFiles is the testable core; getenv abstracts os.Getenv.
 func discoverFiles(getenv func(string) string) []string {
-	if single := getenv("PIKA_CONFIG_FILE"); single != "" {
+	if single := getenv("KELD_CONFIG_FILE"); single != "" {
 		return []string{ExpandPath(single)}
 	}
 
@@ -42,7 +42,7 @@ func discoverFiles(getenv func(string) string) []string {
 		paths = append(paths, sortedGlob(filepath.Join(dir, "conf.d", "*.toml"))...)
 	}
 
-	if extra := getenv("PIKA_CONFIG_PATHS"); extra != "" {
+	if extra := getenv("KELD_CONFIG_PATHS"); extra != "" {
 		for _, entry := range strings.Split(extra, ":") {
 			entry = ExpandPath(strings.TrimSpace(entry))
 			if strings.ContainsAny(entry, "*?[") {

internal/config/files_test.go 🔗

@@ -15,8 +15,8 @@ func TestDiscoverFiles_ConfigFileOverride(t *testing.T) {
 	}
 
 	t.Setenv("HOME", homeDir)
-	t.Setenv("PIKA_CONFIG_FILE", "~/only.toml")
-	t.Setenv("PIKA_CONFIG_PATHS", filepath.Join(tmpDir, "extras", "*.toml"))
+	t.Setenv("KELD_CONFIG_FILE", "~/only.toml")
+	t.Setenv("KELD_CONFIG_PATHS", filepath.Join(tmpDir, "extras", "*.toml"))
 
 	got := DiscoverFiles()
 	want := []string{filepath.Join(homeDir, "only.toml")}
@@ -65,8 +65,8 @@ func TestDiscoverFiles_Order(t *testing.T) {
 		DefaultConfigDirs = originalDirs
 	})
 
-	t.Setenv("PIKA_CONFIG_FILE", "")
-	t.Setenv("PIKA_CONFIG_PATHS", filepath.Join(extraDir, "*.toml")+":"+explicit)
+	t.Setenv("KELD_CONFIG_FILE", "")
+	t.Setenv("KELD_CONFIG_PATHS", filepath.Join(extraDir, "*.toml")+":"+explicit)
 
 	got := DiscoverFiles()
 	want := []string{

internal/form/form.go 🔗

@@ -1,5 +1,5 @@
 // Package form provides interactive huh-based prompts for collecting user
-// input when pika is invoked via the interactive menu.
+// input when keld is invoked via the interactive menu.
 package form
 
 import (

internal/restic/exec.go 🔗

@@ -7,10 +7,10 @@ import (
 	"strings"
 	"syscall"
 
-	"git.secluded.site/pika/internal/config"
+	"git.secluded.site/keld/internal/config"
 )
 
-// DefaultExecutable is the restic binary name used when PIKA_EXECUTABLE is
+// DefaultExecutable is the restic binary name used when KELD_EXECUTABLE is
 // unset.
 const DefaultExecutable = "restic"
 
@@ -60,9 +60,9 @@ func DryRun(cfg *config.ResolvedConfig) string {
 	return b.String()
 }
 
-// executable returns the restic binary name, respecting PIKA_EXECUTABLE.
+// executable returns the restic binary name, respecting KELD_EXECUTABLE.
 func executable() string {
-	if e := os.Getenv("PIKA_EXECUTABLE"); e != "" {
+	if e := os.Getenv("KELD_EXECUTABLE"); e != "" {
 		return config.ExpandPath(e)
 	}
 	return DefaultExecutable

internal/restic/exec_test.go 🔗

@@ -7,7 +7,7 @@ import (
 	"strings"
 	"testing"
 
-	"git.secluded.site/pika/internal/config"
+	"git.secluded.site/keld/internal/config"
 )
 
 func TestBuildArgv(t *testing.T) {
@@ -59,7 +59,7 @@ func TestBuildArgv(t *testing.T) {
 func TestBuildEnv(t *testing.T) {
 	t.Parallel()
 
-	const key = "PIKA_TEST_BUILD_ENV"
+	const key = "KELD_TEST_BUILD_ENV"
 	const val = "set-by-test"
 
 	env := buildEnv(map[string]string{key: val})
@@ -111,7 +111,7 @@ func TestDryRunExecutableOverride(t *testing.T) {
 	}
 
 	t.Setenv("HOME", homeDir)
-	t.Setenv("PIKA_EXECUTABLE", "~/bin/restic-alt")
+	t.Setenv("KELD_EXECUTABLE", "~/bin/restic-alt")
 
 	cfg := &config.ResolvedConfig{Command: "snapshots"}
 	output := DryRun(cfg)

main.go 🔗

@@ -1,6 +1,6 @@
 package main
 
-import "git.secluded.site/pika/cmd"
+import "git.secluded.site/keld/cmd"
 
 func main() {
 	cmd.Execute()

mise.toml 🔗

@@ -5,7 +5,7 @@ go = "latest"
 golangci-lint = "latest"
 
 [tasks.build]
-run = "go build -o pika ."
+run = "go build -o keld ."
 
 [tasks.install]
 run = "go install ."