Add repo-memory integration tests

This commit is contained in:
2026-03-20 16:01:48 +08:00
parent dd6b9c2c1f
commit 9915e12a30
16 changed files with 1394 additions and 79 deletions
@@ -15,52 +15,7 @@ import (
)
func main() {
if len(os.Args) < 2 {
usage()
os.Exit(2)
}
switch os.Args[1] {
case "init":
if err := runInit(os.Args[2:]); err != nil {
fatal(err)
}
case "add":
if err := runAdd(os.Args[2:]); err != nil {
fatal(err)
}
case "ingest":
if err := runIngest(os.Args[2:]); err != nil {
fatal(err)
}
case "search":
if err := runSearch(os.Args[2:]); err != nil {
fatal(err)
}
case "list":
if err := runList(os.Args[2:]); err != nil {
fatal(err)
}
case "events":
if err := runEvents(os.Args[2:]); err != nil {
fatal(err)
}
case "link":
if err := runLink(os.Args[2:]); err != nil {
fatal(err)
}
case "verify":
if err := runVerify(os.Args[2:]); err != nil {
fatal(err)
}
case "repos":
if err := runRepos(os.Args[2:]); err != nil {
fatal(err)
}
default:
usage()
os.Exit(2)
}
os.Exit(Execute(os.Args[1:], os.Stdout, os.Stderr))
}
type stringSliceFlag []string
@@ -76,6 +31,7 @@ func (s *stringSliceFlag) Set(value string) error {
func runInit(args []string) error {
fs := flag.NewFlagSet("init", flag.ContinueOnError)
fs.SetOutput(commandStderr)
dbPath := fs.String("db", "repo-memory.db", "SQLite database path")
if err := fs.Parse(args); err != nil {
return err
@@ -91,12 +47,13 @@ func runInit(args []string) error {
return err
}
fmt.Printf("initialized %s\n", *dbPath)
_, _ = fmt.Fprintf(commandStdout, "initialized %s\n", *dbPath)
return nil
}
func runIngest(args []string) error {
fs := flag.NewFlagSet("ingest", flag.ContinueOnError)
fs.SetOutput(commandStderr)
dbPath := fs.String("db", "repo-memory.db", "SQLite database path")
repoPath := fs.String("repo", "", "Repository root")
scanPath := fs.String("path", "docs/ai", "Relative path under repo to scan for markdown")
@@ -156,12 +113,13 @@ func runIngest(args []string) error {
}
}
fmt.Printf("ingested %d docs from %s\n", len(docs), absRepo)
_, _ = fmt.Fprintf(commandStdout, "ingested %d docs from %s\n", len(docs), absRepo)
return nil
}
func runAdd(args []string) error {
fs := flag.NewFlagSet("add", flag.ContinueOnError)
fs.SetOutput(commandStderr)
dbPath := fs.String("db", "repo-memory.db", "SQLite database path")
repoPath := fs.String("repo", "", "Repository root")
kind := fs.String("kind", "", "Knowledge kind, e.g. term|chain|danger")
@@ -237,12 +195,13 @@ func runAdd(args []string) error {
return err
}
fmt.Printf("upserted entry %d (%s:%s)\n", entryID, input.Kind, input.Key)
_, _ = fmt.Fprintf(commandStdout, "upserted entry %d (%s:%s)\n", entryID, input.Kind, input.Key)
return nil
}
func runSearch(args []string) error {
fs := flag.NewFlagSet("search", flag.ContinueOnError)
fs.SetOutput(commandStderr)
dbPath := fs.String("db", "repo-memory.db", "SQLite database path")
query := fs.String("query", "", "Search query")
repo := fs.String("repo", "", "Optional repo path filter (substring match)")
@@ -269,20 +228,21 @@ func runSearch(args []string) error {
return err
}
if len(results) == 0 {
fmt.Println("no results")
_, _ = fmt.Fprintln(commandStdout, "no results")
return nil
}
for i, r := range results {
fmt.Printf("%d. [%s] %s:%s [%s]\n", i+1, filepath.Base(r.RepoPath), r.Kind, r.Key, r.Status)
fmt.Printf(" %s\n", r.Title)
fmt.Printf(" %s\n", r.Snippet)
_, _ = fmt.Fprintf(commandStdout, "%d. [%s] %s:%s [%s]\n", i+1, filepath.Base(r.RepoPath), r.Kind, r.Key, r.Status)
_, _ = fmt.Fprintf(commandStdout, " %s\n", r.Title)
_, _ = fmt.Fprintf(commandStdout, " %s\n", r.Snippet)
}
return nil
}
func runRepos(args []string) error {
fs := flag.NewFlagSet("repos", flag.ContinueOnError)
fs.SetOutput(commandStderr)
dbPath := fs.String("db", "repo-memory.db", "SQLite database path")
if err := fs.Parse(args); err != nil {
return err
@@ -299,18 +259,19 @@ func runRepos(args []string) error {
return err
}
if len(repos) == 0 {
fmt.Println("no repos")
_, _ = fmt.Fprintln(commandStdout, "no repos")
return nil
}
for _, repo := range repos {
fmt.Printf("- %s (%d entries, updated %s)\n", repo.Path, repo.EntryCount, repo.UpdatedAt.Format(time.RFC3339))
_, _ = fmt.Fprintf(commandStdout, "- %s (%d entries, updated %s)\n", repo.Path, repo.EntryCount, repo.UpdatedAt.Format(time.RFC3339))
}
return nil
}
func runList(args []string) error {
fs := flag.NewFlagSet("list", flag.ContinueOnError)
fs.SetOutput(commandStderr)
dbPath := fs.String("db", "repo-memory.db", "SQLite database path")
repo := fs.String("repo", "", "Optional repo path filter (substring match)")
kind := fs.String("kind", "", "Optional knowledge kind filter")
@@ -336,19 +297,20 @@ func runList(args []string) error {
return err
}
if len(items) == 0 {
fmt.Println("no entries")
_, _ = fmt.Fprintln(commandStdout, "no entries")
return nil
}
for _, item := range items {
fmt.Printf("- #%d [%s] %s:%s [%s]\n", item.ID, filepath.Base(item.RepoPath), item.Kind, item.Key, item.Status)
fmt.Printf(" %s\n", item.Summary)
_, _ = fmt.Fprintf(commandStdout, "- #%d [%s] %s:%s [%s]\n", item.ID, filepath.Base(item.RepoPath), item.Kind, item.Key, item.Status)
_, _ = fmt.Fprintf(commandStdout, " %s\n", item.Summary)
}
return nil
}
func runEvents(args []string) error {
fs := flag.NewFlagSet("events", flag.ContinueOnError)
fs.SetOutput(commandStderr)
dbPath := fs.String("db", "repo-memory.db", "SQLite database path")
id := fs.Int64("id", 0, "Entry id")
repo := fs.String("repo", "", "Repo root when resolving by kind/key")
@@ -378,19 +340,19 @@ func runEvents(args []string) error {
return err
}
if len(events) == 0 {
fmt.Println("no events")
_, _ = fmt.Fprintln(commandStdout, "no events")
return nil
}
fmt.Printf("%s:%s [%s] #%d\n", entry.Kind, entry.Key, entry.Status, entry.ID)
_, _ = fmt.Fprintf(commandStdout, "%s:%s [%s] #%d\n", entry.Kind, entry.Key, entry.Status, entry.ID)
for _, ev := range events {
line := fmt.Sprintf("- %s %s", ev.CreatedAt.Format(time.RFC3339), ev.EventType)
if ev.FromStatus != "" || ev.ToStatus != "" {
line += fmt.Sprintf(" (%s -> %s)", emptyDash(ev.FromStatus), emptyDash(ev.ToStatus))
}
fmt.Println(line)
_, _ = fmt.Fprintln(commandStdout, line)
if ev.Reason != "" {
fmt.Printf(" reason: %s\n", ev.Reason)
_, _ = fmt.Fprintf(commandStdout, " reason: %s\n", ev.Reason)
}
}
return nil
@@ -398,6 +360,7 @@ func runEvents(args []string) error {
func runLink(args []string) error {
fs := flag.NewFlagSet("link", flag.ContinueOnError)
fs.SetOutput(commandStderr)
dbPath := fs.String("db", "repo-memory.db", "SQLite database path")
fromID := fs.Int64("from-id", 0, "From entry id")
toID := fs.Int64("to-id", 0, "To entry id")
@@ -416,12 +379,13 @@ func runLink(args []string) error {
return err
}
fmt.Printf("linked #%d -[%s]-> #%d\n", *fromID, *relation, *toID)
_, _ = fmt.Fprintf(commandStdout, "linked #%d -[%s]-> #%d\n", *fromID, *relation, *toID)
return nil
}
func runVerify(args []string) error {
fs := flag.NewFlagSet("verify", flag.ContinueOnError)
fs.SetOutput(commandStderr)
dbPath := fs.String("db", "repo-memory.db", "SQLite database path")
repo := fs.String("repo", "", "Optional repo root to verify; if omitted, verify all known repos")
if err := fs.Parse(args); err != nil {
@@ -451,14 +415,14 @@ func runVerify(args []string) error {
}
}
if len(repoRoots) == 0 {
fmt.Println("no repos")
_, _ = fmt.Fprintln(commandStdout, "no repos")
return nil
}
for _, repoRoot := range repoRoots {
gitState := detectGitState(repoRoot)
if gitState.commit == "" {
fmt.Printf("%s: skipped (not a git repo or no HEAD)\n", repoRoot)
_, _ = fmt.Fprintf(commandStdout, "%s: skipped (not a git repo or no HEAD)\n", repoRoot)
continue
}
if _, err := st.UpsertRepo(context.Background(), store.RepoState{
@@ -494,14 +458,14 @@ func runVerify(args []string) error {
return err
}
}
fmt.Printf("%s: verified %d entries, %d downgraded, %d stale\n", repoRoot, len(candidates), changedCount, staleCount)
_, _ = fmt.Fprintf(commandStdout, "%s: verified %d entries, %d downgraded, %d stale\n", repoRoot, len(candidates), changedCount, staleCount)
}
return nil
}
func usage() {
fmt.Fprintf(os.Stderr, `repo-memory: repo memory CLI
_, _ = fmt.Fprintf(commandStderr, `repo-memory: repo memory CLI
Usage:
repo-memory init --db repo-memory.db
@@ -516,11 +480,6 @@ Usage:
`)
}
func fatal(err error) {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
type gitState struct {
branch string
commit string