@@ -3,6 +3,7 @@ package git
33import (
44 "bytes"
55 "fmt"
6+ "os"
67 "os/exec"
78 "path/filepath"
89 "strings"
@@ -14,15 +15,15 @@ import (
1415// FindChangedFiles executes a git diff against a specified base reference and pipes the output through a user-defined grep command or sequence.
1516// The baseRef parameter specifies the base git reference for comparison (e.g., "main", "develop").
1617// The filterCmd parameter should include the full command to be executed after git diff, such as "grep '_test.go$'" or "grep -v '_test.go$' | sort".
17- func FindChangedFiles (baseRef , filterCmd string , excludePaths [] string ) ([]string , error ) {
18- // Constructing the exclusion part of the git command
19- excludeStr := ""
20- for _ , path := range excludePaths {
21- excludeStr += fmt .Sprintf ( "':(exclude)%s' " , path )
18+ func FindChangedFiles (rootGoModPath , baseRef , filterCmd string ) ([]string , error ) {
19+ // Find directories containing a go.mod file and build an exclusion string
20+ excludeStr , err := buildExcludeStringForGoModDirs ( rootGoModPath )
21+ if err != nil {
22+ return nil , fmt .Errorf ( "error finding go.mod directories: %w " , err )
2223 }
2324
2425 // First command to list files changed between the baseRef and HEAD, excluding specified paths
25- diffCmdStr := fmt .Sprintf ("git diff --name-only --diff-filter=AM %s...HEAD %s " , baseRef , excludeStr )
26+ diffCmdStr := fmt .Sprintf ("git diff --name-only --diff-filter=AM %s...HEAD -- %s %s " , baseRef , rootGoModPath , excludeStr )
2627 diffCmd := exec .Command ("bash" , "-c" , diffCmdStr )
2728
2829 // Using a buffer to capture stdout and a separate buffer for stderr
@@ -36,7 +37,7 @@ func FindChangedFiles(baseRef, filterCmd string, excludePaths []string) ([]strin
3637 return nil , fmt .Errorf ("error executing git diff command: %s; error: %w; stderr: %s" , diffCmdStr , err , errBuf .String ())
3738 }
3839
39- // Check if there are any files listed, if not, return an empty slice
40+ // Check if there are any files listed; if not, return an empty slice
4041 diffOutput := strings .TrimSpace (out .String ())
4142 if diffOutput == "" {
4243 return []string {}, nil
@@ -74,6 +75,32 @@ func FindChangedFiles(baseRef, filterCmd string, excludePaths []string) ([]strin
7475 return files , nil
7576}
7677
78+ // buildExcludeStringForGoModDirs searches the given root directory for subdirectories
79+ // containing a go.mod file and returns a formatted string to exclude those directories
80+ // (except the root directory if it contains a go.mod file) from git diff.
81+ func buildExcludeStringForGoModDirs (rootGoModPath string ) (string , error ) {
82+ var excludeStr string
83+
84+ err := filepath .Walk (rootGoModPath , func (path string , info os.FileInfo , err error ) error {
85+ if err != nil {
86+ return err
87+ }
88+ if info .Name () == "go.mod" {
89+ dir := filepath .Dir (path )
90+ // Skip excluding the root directory if go.mod is found there
91+ if dir != rootGoModPath {
92+ excludeStr += fmt .Sprintf ("':(exclude)%s/**' " , dir )
93+ }
94+ }
95+ return nil
96+ })
97+ if err != nil {
98+ return "" , err
99+ }
100+
101+ return excludeStr , nil
102+ }
103+
77104func Diff (baseBranch string ) (* utils.CmdOutput , error ) {
78105 return utils .ExecuteCmd ("git" , "diff" , "--name-only" , baseBranch )
79106}
0 commit comments