55 "path/filepath"
66 "regexp"
77 "sort"
8+ "strconv"
89 "strings"
910
1011 "github.com/shurcooL/githubv4"
@@ -83,44 +84,27 @@ Loop:
8384 continue
8485 }
8586
86- // Fetch files once if paths/ignore_paths are specified.
87- var files []string
88-
87+ // Filter pull request if paths or ignorePaths is specified and no wanted paths were found
8988 if len (request .Source .Paths ) > 0 || len (request .Source .IgnorePaths ) > 0 {
90- files , err = manager .ListModifiedFiles (p .Number )
89+ found , err := HasWantedFiles (
90+ strconv .Itoa (p .Number ),
91+ request .Source .Paths ,
92+ request .Source .IgnorePaths ,
93+ p .Files ,
94+ p .FilesPageInfo .HasNextPage ,
95+ string (p .FilesPageInfo .EndCursor ),
96+ manager ,
97+ )
98+
9199 if err != nil {
92- return nil , fmt . Errorf ( "failed to list modified files: %s" , err )
100+ return nil , err
93101 }
94- }
95102
96- // Skip version if no files match the specified paths.
97- if len (request .Source .Paths ) > 0 {
98- var wanted []string
99- for _ , pattern := range request .Source .Paths {
100- w , err := FilterPath (files , pattern )
101- if err != nil {
102- return nil , fmt .Errorf ("path match failed: %s" , err )
103- }
104- wanted = append (wanted , w ... )
105- }
106- if len (wanted ) == 0 {
103+ if ! found {
107104 continue Loop
108105 }
109106 }
110107
111- // Skip version if all files are ignored.
112- if len (request .Source .IgnorePaths ) > 0 {
113- wanted := files
114- for _ , pattern := range request .Source .IgnorePaths {
115- wanted , err = FilterIgnorePath (wanted , pattern )
116- if err != nil {
117- return nil , fmt .Errorf ("ignore path match failed: %s" , err )
118- }
119- }
120- if len (wanted ) == 0 {
121- continue Loop
122- }
123- }
124108 response = append (response , NewVersion (p ))
125109 }
126110
@@ -138,37 +122,88 @@ Loop:
138122 return response , nil
139123}
140124
125+ func HasWantedFiles (prNumber string , paths []string , ignorePaths []string , files []ChangedFileObject , hasMoreFiles bool , nextFileCursor string , manager Github ) (bool , error ) {
126+ // construct a slice that contains 'wanted' files and use this to determine if we should continue
127+ // files are wanted either when they appear in the paths list or don't appear in the ignore paths list
128+ var wanted []ChangedFileObject
129+ var err error
130+
131+ if len (paths ) > 0 {
132+ for _ , pattern := range paths {
133+ w , err := FilterPath (files , pattern )
134+ if err != nil {
135+ return false , fmt .Errorf ("path match failed: %s" , err )
136+ }
137+ wanted = append (wanted , w ... )
138+ }
139+ } else {
140+ wanted = files
141+ }
142+
143+ for _ , pattern := range ignorePaths {
144+ wanted , err = FilterIgnorePath (wanted , pattern )
145+ if err != nil {
146+ return false , fmt .Errorf ("ignore path match failed: %s" , err )
147+ }
148+ }
149+
150+ if len (wanted ) > 0 {
151+ // wanted files were found
152+ return true , nil
153+ }
154+
155+ if ! hasMoreFiles {
156+ // no wanted files were found and there are no more files to examine
157+ return false , nil
158+ }
159+
160+ // no wanted files were found, but there are more files to check
161+ // fetch them now and then check them in another iteration of this function
162+ files , hasMoreFiles , nextFileCursor , err = manager .GetChangedFiles (
163+ prNumber ,
164+ 100 ,
165+ nextFileCursor ,
166+ )
167+ if err != nil {
168+ return false , fmt .Errorf ("get more files failed: %s" , err )
169+ }
170+
171+ return HasWantedFiles (prNumber , paths , ignorePaths , files , hasMoreFiles , nextFileCursor , manager )
172+ }
173+
141174// ContainsSkipCI returns true if a string contains [ci skip] or [skip ci].
142175func ContainsSkipCI (s string ) bool {
143176 re := regexp .MustCompile ("(?i)\\ [(ci skip|skip ci)\\ ]" )
144177 return re .MatchString (s )
145178}
146179
147180// FilterIgnorePath ...
148- func FilterIgnorePath (files []string , pattern string ) ([]string , error ) {
149- var out []string
150- for _ , file := range files {
181+ func FilterIgnorePath (files []ChangedFileObject , pattern string ) ([]ChangedFileObject , error ) {
182+ var out []ChangedFileObject
183+ for _ , cfo := range files {
184+ file := cfo .Path
151185 match , err := filepath .Match (pattern , file )
152186 if err != nil {
153187 return nil , err
154188 }
155189 if ! match && ! IsInsidePath (pattern , file ) {
156- out = append (out , file )
190+ out = append (out , cfo )
157191 }
158192 }
159193 return out , nil
160194}
161195
162196// FilterPath ...
163- func FilterPath (files []string , pattern string ) ([]string , error ) {
164- var out []string
165- for _ , file := range files {
197+ func FilterPath (files []ChangedFileObject , pattern string ) ([]ChangedFileObject , error ) {
198+ var out []ChangedFileObject
199+ for _ , cfo := range files {
200+ file := cfo .Path
166201 match , err := filepath .Match (pattern , file )
167202 if err != nil {
168203 return nil , err
169204 }
170205 if match || IsInsidePath (pattern , file ) {
171- out = append (out , file )
206+ out = append (out , cfo )
172207 }
173208 }
174209 return out , nil
0 commit comments