Skip to content

Commit 9741c22

Browse files
committed
feat: more refactoring
1 parent 141bb4f commit 9741c22

File tree

13 files changed

+414
-303
lines changed

13 files changed

+414
-303
lines changed

bin/canary

-6.64 MB
Binary file not shown.

bin/canary_test_build

633 Bytes
Binary file not shown.

internal/cmds/files/files.go

Lines changed: 2 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ package files
88
import (
99
"fmt"
1010
"os"
11-
"sort"
1211

1312
"github.com/spf13/cobra"
13+
"go.devnw.com/canary"
1414
"go.devnw.com/canary/internal/storage"
1515
)
1616

@@ -62,66 +62,13 @@ Examples:
6262

6363
// Format output
6464
fmt.Printf("Implementation files for %s:\n\n", reqID)
65-
formatFilesList(fileGroups)
65+
fmt.Print(canary.FormatFilesList(fileGroups))
6666

6767
return nil
6868
},
6969
}
7070

7171
// formatFilesList formats file groups by aspect
72-
func formatFilesList(fileGroups map[string][]*storage.Token) {
73-
// Group files by aspect
74-
aspectFiles := make(map[string][]string)
75-
fileCounts := make(map[string]int)
76-
77-
for filePath, tokens := range fileGroups {
78-
// Get aspect from first token (all tokens in same file may have different aspects)
79-
aspects := make(map[string]bool)
80-
for _, token := range tokens {
81-
aspects[token.Aspect] = true
82-
}
83-
84-
// Add file to each unique aspect
85-
for aspect := range aspects {
86-
aspectFiles[aspect] = append(aspectFiles[aspect], filePath)
87-
}
88-
89-
fileCounts[filePath] = len(tokens)
90-
}
91-
92-
// Sort aspects for consistent output
93-
var aspects []string
94-
for aspect := range aspectFiles {
95-
aspects = append(aspects, aspect)
96-
}
97-
sort.Strings(aspects)
98-
99-
// Display by aspect
100-
for _, aspect := range aspects {
101-
files := aspectFiles[aspect]
102-
sort.Strings(files)
103-
104-
fmt.Printf("**%s:**\n", aspect)
105-
for _, file := range files {
106-
count := fileCounts[file]
107-
plural := "token"
108-
if count > 1 {
109-
plural = "tokens"
110-
}
111-
fmt.Printf(" %s (%d %s)\n", file, count, plural)
112-
}
113-
fmt.Println()
114-
}
115-
116-
// Summary
117-
totalFiles := len(fileGroups)
118-
totalTokens := 0
119-
for _, tokens := range fileGroups {
120-
totalTokens += len(tokens)
121-
}
122-
fmt.Printf("Total: %d files, %d tokens\n", totalFiles, totalTokens)
123-
}
124-
12572
func init() {
12673
FilesCmd.Flags().String("prompt", "", "Custom prompt file or embedded prompt name (future use)")
12774
FilesCmd.Flags().Bool("all", false, "Include spec and template files")

internal/cmds/files/files_test.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"path/filepath"
1010
"testing"
1111

12+
"go.devnw.com/canary"
1213
"go.devnw.com/canary/internal/storage"
1314
)
1415

@@ -114,7 +115,7 @@ func TestCANARY_CBIN_CLI_001_CLI_FilesCmd_Formatting(t *testing.T) {
114115
}
115116

116117
// Test that formatFilesList doesn't panic
117-
formatFilesList(fileGroups)
118+
canary.FormatFilesList(fileGroups)
118119

119120
// Verify total counts
120121
totalFiles := len(fileGroups)
@@ -141,7 +142,7 @@ func TestCANARY_CBIN_CLI_001_CLI_FilesCmd_AspectGrouping(t *testing.T) {
141142
}
142143

143144
// Format output (should group by aspect)
144-
formatFilesList(fileGroups)
145+
canary.FormatFilesList(fileGroups)
145146

146147
// Verify that file appears under both aspects
147148
aspectFiles := make(map[string][]string)

internal/cmds/grep/grep.go

Lines changed: 4 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ package grep
88
import (
99
"fmt"
1010
"os"
11-
"strings"
1211

1312
"github.com/spf13/cobra"
13+
"go.devnw.com/canary"
1414
"go.devnw.com/canary/internal/storage"
1515
)
1616

@@ -53,7 +53,7 @@ Examples:
5353
defer db.Close()
5454

5555
// Search for matching tokens
56-
tokens, err := grepTokens(db, pattern)
56+
tokens, err := canary.GrepTokens(db, pattern)
5757
if err != nil {
5858
return fmt.Errorf("search tokens: %w", err)
5959
}
@@ -67,101 +67,16 @@ Examples:
6767
fmt.Printf("Found %d tokens matching '%s':\n\n", len(tokens), pattern)
6868

6969
if groupBy == "requirement" {
70-
displayGrepResultsByRequirement(tokens)
70+
fmt.Print(canary.FormatGrepResultsByRequirement(tokens))
7171
} else {
72-
displayGrepResults(tokens)
72+
fmt.Print(canary.FormatGrepResults(tokens))
7373
}
7474

7575
return nil
7676
},
7777
}
7878

7979
// grepTokens searches for tokens matching the pattern
80-
func grepTokens(db *storage.DB, pattern string) ([]*storage.Token, error) {
81-
if pattern == "" {
82-
return []*storage.Token{}, nil
83-
}
84-
85-
// Get all tokens and filter by pattern
86-
// We use SearchTokens which already does keyword matching
87-
tokens, err := db.SearchTokens(pattern)
88-
if err != nil {
89-
return nil, err
90-
}
91-
92-
// Additional filtering for file paths and test names
93-
allTokens, err := db.ListTokens(nil, "", "", 0)
94-
if err != nil {
95-
return nil, err
96-
}
97-
98-
patternLower := strings.ToLower(pattern)
99-
matchMap := make(map[string]*storage.Token)
100-
101-
// Add tokens from keyword search
102-
for _, token := range tokens {
103-
key := fmt.Sprintf("%s:%s:%s:%d", token.ReqID, token.Feature, token.FilePath, token.LineNumber)
104-
matchMap[key] = token
105-
}
106-
107-
// Add tokens matching file path, test, or bench
108-
for _, token := range allTokens {
109-
if strings.Contains(strings.ToLower(token.FilePath), patternLower) ||
110-
strings.Contains(strings.ToLower(token.Test), patternLower) ||
111-
strings.Contains(strings.ToLower(token.Bench), patternLower) {
112-
key := fmt.Sprintf("%s:%s:%s:%d", token.ReqID, token.Feature, token.FilePath, token.LineNumber)
113-
matchMap[key] = token
114-
}
115-
}
116-
117-
// Convert map back to slice
118-
result := make([]*storage.Token, 0, len(matchMap))
119-
for _, token := range matchMap {
120-
result = append(result, token)
121-
}
122-
123-
return result, nil
124-
}
125-
126-
// displayGrepResults shows grep results in a simple list format
127-
func displayGrepResults(tokens []*storage.Token) {
128-
for _, token := range tokens {
129-
fmt.Printf("📌 %s - %s\n", token.ReqID, token.Feature)
130-
fmt.Printf(" Status: %s | Aspect: %s\n", token.Status, token.Aspect)
131-
fmt.Printf(" Location: %s:%d\n", token.FilePath, token.LineNumber)
132-
if token.Test != "" {
133-
fmt.Printf(" Test: %s\n", token.Test)
134-
}
135-
if token.Bench != "" {
136-
fmt.Printf(" Bench: %s\n", token.Bench)
137-
}
138-
fmt.Println()
139-
}
140-
}
141-
142-
// displayGrepResultsByRequirement groups results by requirement ID
143-
func displayGrepResultsByRequirement(tokens []*storage.Token) {
144-
// Group by requirement
145-
reqMap := make(map[string][]*storage.Token)
146-
for _, token := range tokens {
147-
reqMap[token.ReqID] = append(reqMap[token.ReqID], token)
148-
}
149-
150-
// Display grouped results
151-
for reqID, reqTokens := range reqMap {
152-
fmt.Printf("## %s (%d tokens)\n\n", reqID, len(reqTokens))
153-
for _, token := range reqTokens {
154-
fmt.Printf(" 📌 %s\n", token.Feature)
155-
fmt.Printf(" Status: %s | Aspect: %s | %s:%d\n",
156-
token.Status, token.Aspect, token.FilePath, token.LineNumber)
157-
if token.Test != "" {
158-
fmt.Printf(" Test: %s\n", token.Test)
159-
}
160-
}
161-
fmt.Println()
162-
}
163-
}
164-
16580
func init() {
16681
GrepCmd.Flags().String("prompt", "", "Custom prompt file or embedded prompt name (future use)")
16782
GrepCmd.Flags().String("db", ".canary/canary.db", "Path to database file")

internal/cmds/grep/grep_test.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"path/filepath"
1010
"testing"
1111

12+
"go.devnw.com/canary"
1213
"go.devnw.com/canary/internal/storage"
1314
)
1415

@@ -96,7 +97,7 @@ func TestCANARY_CBIN_CLI_001_CLI_GrepCmd(t *testing.T) {
9697

9798
for _, tt := range tests {
9899
t.Run(tt.name, func(t *testing.T) {
99-
tokens, err := grepTokens(db, tt.pattern)
100+
tokens, err := canary.GrepTokens(db, tt.pattern)
100101
if err != nil {
101102
t.Fatalf("grepTokens failed: %v", err)
102103
}
@@ -162,7 +163,7 @@ func TestCANARY_CBIN_CLI_001_CLI_GrepCmd_CaseInsensitive(t *testing.T) {
162163

163164
for _, tt := range tests {
164165
t.Run(tt.pattern, func(t *testing.T) {
165-
tokens, err := grepTokens(db, tt.pattern)
166+
tokens, err := canary.GrepTokens(db, tt.pattern)
166167
if err != nil {
167168
t.Fatalf("grepTokens failed: %v", err)
168169
}
@@ -191,7 +192,7 @@ func TestCANARY_CBIN_CLI_001_CLI_GrepCmd_EmptyPattern(t *testing.T) {
191192
defer db.Close()
192193

193194
// Empty pattern should return no results
194-
tokens, err := grepTokens(db, "")
195+
tokens, err := canary.GrepTokens(db, "")
195196
if err != nil {
196197
t.Fatalf("grepTokens failed: %v", err)
197198
}

0 commit comments

Comments
 (0)