diff --git a/.github/workflows/mutation-testing.yml b/.github/workflows/mutation-testing.yml index cd77d39..12ade38 100644 --- a/.github/workflows/mutation-testing.yml +++ b/.github/workflows/mutation-testing.yml @@ -35,6 +35,6 @@ jobs: version: 'local' workers: '2' timeout: '60' - threshold: 0 - fail-on-gate: 'false' # TODO: Fix gomu bugs (.gomuignore, incremental analysis, not viable rate) + threshold: '40' # Current baseline ~46%, will improve incrementally + fail-on-gate: 'true' diff --git a/internal/analysis/git.go b/internal/analysis/git.go index 6898c85..e7536ec 100644 --- a/internal/analysis/git.go +++ b/internal/analysis/git.go @@ -67,11 +67,16 @@ func (g *GitIntegration) GetChangedFiles(baseBranch string) ([]string, error) { return []string{}, nil } - // Filter for Go files + // Filter for Go files and apply ignore patterns var goFiles []string for _, file := range files { if IsGoSourceFile(file) { + // Check if file should be ignored by .gomuignore + if g.ignoreParser != nil && g.ignoreParser.ShouldIgnore(file) { + continue + } + // Convert to absolute path absPath := filepath.Join(g.workDir, file) goFiles = append(goFiles, absPath) diff --git a/internal/analysis/incremental.go b/internal/analysis/incremental.go index 97cfcd7..1335a40 100644 --- a/internal/analysis/incremental.go +++ b/internal/analysis/incremental.go @@ -25,6 +25,7 @@ type IncrementalAnalyzer struct { history HistoryStore workDir string ignoreParser IgnoreParser + incremental bool } // IgnoreParser defines the interface for ignore file parsing. @@ -33,7 +34,7 @@ type IgnoreParser interface { } // NewIncrementalAnalyzer creates a new incremental analyzer. -func NewIncrementalAnalyzer(workDir string, historyStore HistoryStore) (*IncrementalAnalyzer, error) { +func NewIncrementalAnalyzer(workDir string, historyStore HistoryStore, incremental bool) (*IncrementalAnalyzer, error) { // Validate that the workDir exists if _, err := os.Stat(workDir); err != nil { if os.IsNotExist(err) { @@ -44,10 +45,11 @@ func NewIncrementalAnalyzer(workDir string, historyStore HistoryStore) (*Increme } return &IncrementalAnalyzer{ - hasher: NewFileHasher(), - git: NewGitIntegration(workDir), - history: historyStore, - workDir: workDir, + hasher: NewFileHasher(), + git: NewGitIntegration(workDir), + history: historyStore, + workDir: workDir, + incremental: incremental, }, nil } @@ -91,9 +93,7 @@ func (a *IncrementalAnalyzer) AnalyzeFiles() ([]FileAnalysisResult, error) { // getFilesToAnalyze returns the list of files that should be analyzed. func (a *IncrementalAnalyzer) getFilesToAnalyze() ([]string, error) { - // Always enable incremental analysis by default - incrementalEnabled := true - if incrementalEnabled && a.git.IsGitRepository() { + if a.incremental && a.git.IsGitRepository() { // Use Git diff to get changed files with intelligent default base branch return a.git.GetChangedFiles("main") } diff --git a/internal/analysis/incremental_test.go b/internal/analysis/incremental_test.go index 7ac22ce..83c496d 100644 --- a/internal/analysis/incremental_test.go +++ b/internal/analysis/incremental_test.go @@ -49,7 +49,7 @@ func TestIncrementalAnalyzer_NewIncrementalAnalyzer(t *testing.T) { tempDir := t.TempDir() history := NewMockHistoryStore() - analyzer, err := NewIncrementalAnalyzer(tempDir, history) + analyzer, err := NewIncrementalAnalyzer(tempDir, history, false) if err != nil { t.Fatalf("Failed to create incremental analyzer: %v", err) } @@ -86,7 +86,7 @@ func TestIncrementalAnalyzer_AnalyzeFiles(t *testing.T) { t.Fatalf("Failed to create go.mod: %v", err) } - analyzer, err := NewIncrementalAnalyzer(tempDir, history) + analyzer, err := NewIncrementalAnalyzer(tempDir, history, false) if err != nil { t.Fatalf("Failed to create incremental analyzer: %v", err) } @@ -142,7 +142,7 @@ func TestIncrementalAnalyzer_GetFilesNeedingUpdate(t *testing.T) { t.Fatalf("Failed to create go.mod: %v", err) } - analyzer, err := NewIncrementalAnalyzer(tempDir, history) + analyzer, err := NewIncrementalAnalyzer(tempDir, history, false) if err != nil { t.Fatalf("Failed to create incremental analyzer: %v", err) } @@ -187,7 +187,7 @@ func TestIncrementalAnalyzer_PrintAnalysisReport(t *testing.T) { history := NewMockHistoryStore() tempDir := t.TempDir() - analyzer, err := NewIncrementalAnalyzer(tempDir, history) + analyzer, err := NewIncrementalAnalyzer(tempDir, history, false) if err != nil { t.Fatalf("Failed to create incremental analyzer: %v", err) } @@ -218,7 +218,7 @@ func TestIncrementalAnalyzer_EdgeCases(t *testing.T) { history := NewMockHistoryStore() // Test with empty directory - analyzer, err := NewIncrementalAnalyzer(tempDir, history) + analyzer, err := NewIncrementalAnalyzer(tempDir, history, false) if err != nil { t.Fatalf("Failed to create incremental analyzer: %v", err) } @@ -247,7 +247,7 @@ func TestIncrementalAnalyzer_InvalidPath(t *testing.T) { history := NewMockHistoryStore() // Test with non-existent directory - _, err := NewIncrementalAnalyzer("/nonexistent/path", history) + _, err := NewIncrementalAnalyzer("/nonexistent/path", history, false) if err == nil { t.Error("Expected error for non-existent path") } @@ -259,7 +259,7 @@ func TestIncrementalAnalyzer_analyzeFile(t *testing.T) { mockHistory := NewMockHistoryStore() - analyzer, err := NewIncrementalAnalyzer(tmpDir, mockHistory) + analyzer, err := NewIncrementalAnalyzer(tmpDir, mockHistory, false) if err != nil { t.Fatalf("Failed to create incremental analyzer: %v", err) } @@ -346,7 +346,7 @@ func TestIncrementalAnalyzer_hasTestFilesChanged(t *testing.T) { tmpDir := t.TempDir() mockHistory := NewMockHistoryStore() - analyzer, err := NewIncrementalAnalyzer(tmpDir, mockHistory) + analyzer, err := NewIncrementalAnalyzer(tmpDir, mockHistory, false) if err != nil { t.Fatalf("Failed to create incremental analyzer: %v", err) } diff --git a/internal/execution/engine.go b/internal/execution/engine.go index 0a9d91e..9019e1d 100644 --- a/internal/execution/engine.go +++ b/internal/execution/engine.go @@ -132,8 +132,8 @@ func (e *Engine) checkCompilationWithOverlay(mutCtx *MutationContext) error { // Get the directory containing the original file for compilation compileDir := filepath.Dir(mutCtx.OriginalPath) - // Build only the specific file to avoid issues with other invalid files in the directory - cmd := exec.CommandContext(ctx, "go", "build", "-overlay="+mutCtx.OverlayPath, filepath.Base(mutCtx.OriginalPath)) + // Build the entire package with overlay to properly resolve dependencies + cmd := exec.CommandContext(ctx, "go", "build", "-overlay="+mutCtx.OverlayPath, ".") cmd.Dir = compileDir output, err := cmd.CombinedOutput() diff --git a/pkg/gomu/engine.go b/pkg/gomu/engine.go index 78d480d..4a56006 100644 --- a/pkg/gomu/engine.go +++ b/pkg/gomu/engine.go @@ -187,7 +187,7 @@ func (e *Engine) performIncrementalAnalysis(absPath string, opts *RunOptions, ig var err error - e.incrementalAnalyzer, err = analysis.NewIncrementalAnalyzer(absPath, historyWrapper) + e.incrementalAnalyzer, err = analysis.NewIncrementalAnalyzer(absPath, historyWrapper, opts.Incremental) if err != nil { return nil, nil, fmt.Errorf("failed to create incremental analyzer: %w", err) }