From 60f717b97ce6c375679080472750e60aab9dcd8f Mon Sep 17 00:00:00 2001 From: Paul Buetow Date: Sat, 18 Apr 2026 08:47:27 +0300 Subject: refactor: move Gitter interface to consumer package internal/cli (task p6) Per Go best practice (100 Go Mistakes #6): interfaces belong where they are used, not where they are implemented. Move Gitter from internal/git to internal/cli/git.go. Compile-time assertions (var _ Gitter = ...) kept in the new location. internal/git retains concrete *Git and *NoOp types. Co-Authored-By: Claude Sonnet 4.6 --- internal/cli/git.go | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 internal/cli/git.go (limited to 'internal/cli/git.go') diff --git a/internal/cli/git.go b/internal/cli/git.go new file mode 100644 index 0000000..4921a38 --- /dev/null +++ b/internal/cli/git.go @@ -0,0 +1,48 @@ +// Package cli — git abstraction for the CLI layer. +// +// This file defines the Gitter interface, which the CLI uses to abstract over +// real git operations (*git.Git) and no-op stubs (*git.NoOp). The interface +// lives here in the consumer package (internal/cli) rather than in the +// producer package (internal/git), following Go best practice #6 from +// "100 Go Mistakes": interfaces should be defined where they are used, not +// where they are implemented. +// +// Keeping the interface here avoids tight coupling between internal/git and its +// callers: internal/git does not need to know who depends on it, and new +// consumers can define their own narrower interfaces as needed. +package cli + +import ( + "context" + + "codeberg.org/snonux/foostore/internal/git" +) + +// Gitter abstracts git operations so that the CLI dispatch logic works +// identically whether backed by a real git repository (*git.Git) or a no-op +// stub (*git.NoOp — used when the KeePass database file lives outside a repo). +type Gitter interface { + // Add stages a single file for the next commit. + Add(ctx context.Context, filePath string) error + + // Remove stages a file deletion for the next commit. + Remove(ctx context.Context, filePath string) error + + // Status prints the current git status of the working directory. + Status(ctx context.Context) error + + // Commit records all staged changes with a generic commit message. + Commit(ctx context.Context) error + + // Reset discards all uncommitted changes in the working directory. + Reset(ctx context.Context) error + + // Sync pulls from and pushes to each configured remote repository. + Sync(ctx context.Context, syncRepos []string) error +} + +// Compile-time assertions: both concrete git types must satisfy Gitter. +// These assertions live in the consumer (cli), not the producer (git), +// so that internal/git remains free of any dependency on this package. +var _ Gitter = (*git.Git)(nil) +var _ Gitter = (*git.NoOp)(nil) -- cgit v1.2.3