summaryrefslogtreecommitdiff
path: root/internal/store
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-03-02 10:58:44 +0200
committerPaul Buetow <paul@buetow.org>2026-03-02 10:58:44 +0200
commit99bb2e39263dd477c8e438ff38ac1c158e4097a9 (patch)
tree34ef8d85af64112df6eba4efe0f69ebe112e7466 /internal/store
parentb636b12566ea6c2862bf3adc6686c57e0d785ca3 (diff)
store/cli: move search output to CLI layer (task 400)
Diffstat (limited to 'internal/store')
-rw-r--r--internal/store/store.go14
-rw-r--r--internal/store/store_test.go32
2 files changed, 36 insertions, 10 deletions
diff --git a/internal/store/store.go b/internal/store/store.go
index 8d251b3..e1fb4e8 100644
--- a/internal/store/store.go
+++ b/internal/store/store.go
@@ -155,8 +155,16 @@ func (s *Store) processIndexFile(ctx context.Context, path, searchTerm string, r
// printed; for ActionExport/ActionPathExport the content is written to ExportDir.
// Actions requiring external tools (paste, open, edit) are delegated to the
// optional actionFn callback — pass nil if those actions are not needed.
+// The optional onMatch callback lets callers handle presentation concerns
+// (for example, printing idx.String()) outside the store layer.
// Returns the sorted list of matching indexes for the caller's use.
-func (s *Store) Search(ctx context.Context, searchTerm string, action Action, actionFn func(context.Context, *Index, *Data) error) ([]*Index, error) {
+func (s *Store) Search(
+ ctx context.Context,
+ searchTerm string,
+ action Action,
+ actionFn func(context.Context, *Index, *Data) error,
+ onMatch func(*Index),
+) ([]*Index, error) {
var indexes IndexSlice
if err := s.WalkIndexes(ctx, searchTerm, func(idx *Index) error {
indexes = append(indexes, idx)
@@ -168,7 +176,9 @@ func (s *Store) Search(ctx context.Context, searchTerm string, action Action, ac
sort.Sort(indexes)
for _, idx := range indexes {
- fmt.Print(idx.String())
+ if onMatch != nil {
+ onMatch(idx)
+ }
if err := s.applyAction(ctx, idx, action, actionFn); err != nil {
return indexes, err
}
diff --git a/internal/store/store_test.go b/internal/store/store_test.go
index 86b7d0d..bae61bb 100644
--- a/internal/store/store_test.go
+++ b/internal/store/store_test.go
@@ -375,7 +375,7 @@ func TestRemoveEntry(t *testing.T) {
// --- TestSearch --------------------------------------------------------------
// TestSearch adds two entries, then calls Search with ActionNone and verifies
-// both descriptions are returned sorted and printed to stdout.
+// both descriptions are returned sorted without store-layer stdout side effects.
func TestSearch(t *testing.T) {
ctx, store, cfg, _, _ := testSetup(t)
initGitRepo(t, cfg.DataDir)
@@ -386,7 +386,20 @@ func TestSearch(t *testing.T) {
}
}
- results, err := store.Search(ctx, "", ActionNone, nil)
+ r, w, err := os.Pipe()
+ if err != nil {
+ t.Fatalf("creating pipe: %v", err)
+ }
+ oldStdout := os.Stdout
+ os.Stdout = w
+
+ results, err := store.Search(ctx, "", ActionNone, nil, nil)
+
+ w.Close()
+ os.Stdout = oldStdout
+ var out strings.Builder
+ io.Copy(&out, r)
+
if err != nil {
t.Fatalf("Search: %v", err)
}
@@ -397,6 +410,9 @@ func TestSearch(t *testing.T) {
if results[0].Description != "apple/entry" || results[1].Description != "zebra/entry" {
t.Errorf("unexpected sort order: %v, %v", results[0].Description, results[1].Description)
}
+ if out.String() != "" {
+ t.Errorf("Search(ActionNone) wrote unexpected stdout: %q", out.String())
+ }
}
// --- TestSearchActionCat -----------------------------------------------------
@@ -419,7 +435,7 @@ func TestSearchActionCat(t *testing.T) {
}
os.Stdout = w
- results, err := store.Search(ctx, "note.txt", ActionCat, nil)
+ results, err := store.Search(ctx, "note.txt", ActionCat, nil, nil)
w.Close()
os.Stdout = oldStdout
@@ -459,7 +475,7 @@ func TestSearchActionCatBinarySkip(t *testing.T) {
oldStdout := os.Stdout
os.Stdout = w
- results, searchErr := store.Search(ctx, "photo.jpg", ActionCat, nil)
+ results, searchErr := store.Search(ctx, "photo.jpg", ActionCat, nil, nil)
w.Close()
os.Stdout = oldStdout
@@ -519,7 +535,7 @@ func TestSearchActionExport(t *testing.T) {
t.Fatalf("Add: %v", err)
}
- results, err := store.Search(ctx, "report.txt", ActionExport, nil)
+ results, err := store.Search(ctx, "report.txt", ActionExport, nil, nil)
if err != nil {
t.Fatalf("Search ActionExport: %v", err)
}
@@ -759,7 +775,7 @@ func TestSearchActionPathExport(t *testing.T) {
t.Fatalf("Add: %v", err)
}
- results, err := store.Search(ctx, "report.txt", ActionPathExport, nil)
+ results, err := store.Search(ctx, "report.txt", ActionPathExport, nil, nil)
if err != nil {
t.Fatalf("Search ActionPathExport: %v", err)
}
@@ -800,7 +816,7 @@ func TestSearchActionWithCallback(t *testing.T) {
}
// ActionPaste falls through to the default/actionFn branch of applyAction.
- results, err := store.Search(ctx, "cb/entry.txt", ActionPaste, actionFn)
+ results, err := store.Search(ctx, "cb/entry.txt", ActionPaste, actionFn, nil)
if err != nil {
t.Fatalf("Search with callback: %v", err)
}
@@ -828,7 +844,7 @@ func TestSearchActionNilCallback(t *testing.T) {
}
// nil actionFn: applyAction must return nil without calling anything.
- _, err := store.Search(ctx, "nil/cb.txt", ActionPaste, nil)
+ _, err := store.Search(ctx, "nil/cb.txt", ActionPaste, nil, nil)
if err != nil {
t.Fatalf("Search with nil callback: %v", err)
}