Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 16 additions & 21 deletions internal/server/indexer/indexer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -515,25 +515,14 @@ func TestShouldIndexFile_WithGitIgnoreFilter(t *testing.T) {
_, teardown := setupTestEnv(t)
defer teardown()

wsDir := t.TempDir()
ws, err := workspace.Create(wsDir)
ws, err := workspace.Create(t.TempDir())
if err != nil {
t.Fatalf("workspace.Create: %v", err)
}

// Initialize a real git repo for gitignore to work
origDir, _ := os.Getwd()
os.Chdir(wsDir)
defer os.Chdir(origDir)

// Use git init to create a proper repo
gitCmd := filepath.Join("/usr", "bin", "git")
if _, err := os.Stat(gitCmd); err != nil {
t.Skip("git not available, skipping gitignore test")
}

// Create .gitignore that excludes .log files
if err := os.WriteFile(filepath.Join(wsDir, ".gitignore"), []byte("*.log\n"), 0644); err != nil {
// Create a .gitignore that ignores the build/ directory and *.log files.
// NewGitIgnore reads .gitignore directly — it needs no .git dir or git binary.
if err := os.WriteFile(filepath.Join(ws.Path, ".gitignore"), []byte("build/\n*.log\n"), 0644); err != nil {
t.Fatalf("write .gitignore: %v", err)
}

Expand All @@ -546,12 +535,18 @@ func TestShouldIndexFile_WithGitIgnoreFilter(t *testing.T) {
}
ws.Save()

// The GitIgnoreFilter should exercise the code path even if the actual
// gitignore behavior is partial — we at least cover the code branch.
_ = ShouldIndexFile(ws, "debug.log")
_ = ShouldIndexFile(ws, "main.go")
// Just exercising the code path — no assertions on gitignore behavior
// since it depends on git repo structure
// main.go is not ignored → should be kept (indexed).
if !ShouldIndexFile(ws, "main.go") {
t.Errorf("ShouldIndexFile(main.go) = false, want true (not ignored, should be kept)")
}
// app.log matches *.log → should be excluded.
if ShouldIndexFile(ws, "app.log") {
t.Errorf("ShouldIndexFile(app.log) = true, want false (ignored by *.log)")
}
// build/out.go is under build/ → should be excluded.
if ShouldIndexFile(ws, "build/out.go") {
t.Errorf("ShouldIndexFile(build/out.go) = true, want false (ignored by build/)")
}
}

// ---------------------------------------------------------------------------
Expand Down
30 changes: 12 additions & 18 deletions internal/server/indexer/scanner.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,19 @@ import (
gitutils "github.com/codetrek/haystack/core/utils/git"
"github.com/codetrek/haystack/internal/core/workspace"
"github.com/codetrek/haystack/internal/shared/running"
"github.com/codetrek/haystack/internal/shared/types"
"github.com/codetrek/haystack/internal/utils"
fsutils "github.com/codetrek/haystack/internal/utils/fs"
)

// buildExcludeFilter returns a keep-filter: Match==true => keep, Match==false => exclude.
func buildExcludeFilter(baseDir string, exclude types.Exclude) fsutils.ListFileFilter {
if exclude.UseGitIgnore {
return &GitIgnoreFilter{ignore: gitutils.NewGitIgnore(baseDir, true)}
}
return utils.NewSimpleFilterExclude(exclude.Customized)
}

type GitIgnoreFilter struct {
ignore *gitutils.GitIgnore
}
Expand Down Expand Up @@ -102,16 +111,8 @@ func ShouldIndexFile(w *workspace.Workspace, relPath string) bool {
baseDir := w.Path
filters := w.GetFilters()

var exclude fsutils.ListFileFilter
if filters.Exclude.UseGitIgnore {
exclude = &GitIgnoreFilter{
ignore: gitutils.NewGitIgnore(baseDir, true),
}
} else {
exclude = utils.NewSimpleFilter(filters.Exclude.Customized)
}

if exclude.Match(relPath, false) {
exclude := buildExcludeFilter(baseDir, filters.Exclude)
if !exclude.Match(relPath, false) {
return false
}

Expand All @@ -133,14 +134,7 @@ func (s *Scanner) processWorkspace(w *workspace.Workspace, forceRefresh bool) er
baseDir := w.Path
filters := w.GetFilters()

var exclude fsutils.ListFileFilter
if filters.Exclude.UseGitIgnore {
exclude = &GitIgnoreFilter{
ignore: gitutils.NewGitIgnore(baseDir, true),
}
} else {
exclude = utils.NewSimpleFilterExclude(filters.Exclude.Customized)
}
exclude := buildExcludeFilter(baseDir, filters.Exclude)

include := utils.NewSimpleFilter(filters.Include)
startTime := time.Now()
Expand Down
Loading