@@ -20,11 +20,13 @@ import (
20
20
"fmt"
21
21
"os"
22
22
"path/filepath"
23
+ "regexp"
23
24
"sort"
24
25
"strconv"
25
26
"strings"
26
27
"text/template"
27
28
29
+ "github.com/GoogleCloudPlatform/magic-modules/tools/issue-labeler/labeler"
28
30
"magician/exec"
29
31
"magician/github"
30
32
"magician/provider"
44
46
type Diff struct {
45
47
Title string
46
48
Repo string
47
- DiffStats string
49
+ ShortStat string
48
50
}
49
51
50
52
type Errors struct {
@@ -187,31 +189,41 @@ func execGenerateComment(prNumber int, ghTokenMagicModules, buildId, buildStep,
187
189
for _ , repo := range []* source.Repo {& tpgRepo , & tpgbRepo , & tgcRepo , & tfoicsRepo } {
188
190
errors [repo .Title ] = []string {}
189
191
repo .Branch = newBranch
192
+ repo .Cloned = true
190
193
if err := ctlr .Clone (repo ); err != nil {
191
- fmt .Println ("Failed to clone repo: " , err )
192
- errors [repo .Title ] = append (errors [repo .Title ], "Failed to clone repo" )
193
- } else {
194
- repo .Cloned = true
194
+ fmt .Println ("Failed to clone repo at new branch: " , err )
195
+ errors [repo .Title ] = append (errors [repo .Title ], "Failed to clone repo at new branch" )
196
+ repo .Cloned = false
197
+ }
198
+ if err := ctlr .Fetch (repo , oldBranch ); err != nil {
199
+ fmt .Println ("Failed to fetch old branch: " , err )
200
+ errors [repo .Title ] = append (errors [repo .Title ], "Failed to clone repo at old branch" )
201
+ repo .Cloned = false
195
202
}
196
203
}
197
204
198
205
diffs := []Diff {}
199
- for _ , repo := range []source.Repo {tpgRepo , tpgbRepo , tgcRepo , tfoicsRepo } {
206
+ for _ , repo := range []* source.Repo {& tpgRepo , & tpgbRepo , & tgcRepo , & tfoicsRepo } {
200
207
if ! repo .Cloned {
201
208
fmt .Println ("Skipping diff; repo failed to clone: " , repo .Name )
202
209
continue
203
210
}
204
- diffStats , err := computeDiff ( & repo , oldBranch , ctlr )
211
+ shortStat , err := ctlr . DiffShortStat ( repo , oldBranch , newBranch )
205
212
if err != nil {
206
- fmt .Println ("diffing repo: " , err )
207
- errors [repo .Title ] = append (errors [repo .Title ], "Failed to compute repo diff stats " )
213
+ fmt .Println ("Failed to compute repo diff --shortstat : " , err )
214
+ errors [repo .Title ] = append (errors [repo .Title ], "Failed to compute repo diff shortstats " )
208
215
}
209
- if diffStats != "" {
216
+ if shortStat != "" {
210
217
diffs = append (diffs , Diff {
211
218
Title : repo .Title ,
212
219
Repo : repo .Name ,
213
- DiffStats : diffStats ,
220
+ ShortStat : shortStat ,
214
221
})
222
+ repo .ChangedFiles , err = ctlr .DiffNameOnly (repo , oldBranch , newBranch )
223
+ if err != nil {
224
+ fmt .Println ("Failed to compute repo diff --name-only: " , err )
225
+ errors [repo .Title ] = append (errors [repo .Title ], "Failed to compute repo changed filenames" )
226
+ }
215
227
}
216
228
}
217
229
data .Diffs = diffs
@@ -230,7 +242,11 @@ func execGenerateComment(prNumber int, ghTokenMagicModules, buildId, buildStep,
230
242
}
231
243
for _ , repo := range []source.Repo {tpgRepo , tpgbRepo } {
232
244
if ! repo .Cloned {
233
- fmt .Println ("Skipping breaking changes; repo failed to clone: " , repo .Name )
245
+ fmt .Println ("Skipping diff processor; repo failed to clone: " , repo .Name )
246
+ continue
247
+ }
248
+ if len (repo .ChangedFiles ) == 0 {
249
+ fmt .Println ("Skipping diff processor; no diff: " , repo .Name )
234
250
continue
235
251
}
236
252
err = buildDiffProcessor (diffProcessorPath , repo .Path , diffProcessorEnv , rnr )
@@ -267,6 +283,33 @@ func execGenerateComment(prNumber int, ghTokenMagicModules, buildId, buildStep,
267
283
sort .Strings (breakingChangesSlice )
268
284
data .BreakingChanges = breakingChangesSlice
269
285
286
+ // Compute affected resources based on changed files
287
+ affectedResources := map [string ]struct {}{}
288
+ for _ , repo := range []source.Repo {tpgRepo , tpgbRepo } {
289
+ if ! repo .Cloned {
290
+ fmt .Println ("Skipping changed file service labels; repo failed to clone: " , repo .Name )
291
+ continue
292
+ }
293
+ for _ , path := range repo .ChangedFiles {
294
+ if r := fileToResource (path ); r != "" {
295
+ affectedResources [r ] = struct {}{}
296
+ }
297
+ }
298
+ }
299
+ fmt .Printf ("affected resources based on changed files: %v\n " , maps .Keys (affectedResources ))
300
+
301
+ // Compute additional service labels based on affected resources
302
+ regexpLabels , err := labeler .BuildRegexLabels (labeler .EnrolledTeamsYaml )
303
+ if err != nil {
304
+ fmt .Println ("error building regexp labels: " , err )
305
+ errors ["Other" ] = append (errors ["Other" ], "Failed to parse service label mapping" )
306
+ }
307
+ if len (regexpLabels ) > 0 {
308
+ for _ , label := range labeler .ComputeLabels (maps .Keys (affectedResources ), regexpLabels ) {
309
+ uniqueServiceLabels [label ] = struct {}{}
310
+ }
311
+ }
312
+
270
313
// Add service labels to PR
271
314
if len (uniqueServiceLabels ) > 0 {
272
315
serviceLabelsSlice := maps .Keys (uniqueServiceLabels )
@@ -310,18 +353,21 @@ func execGenerateComment(prNumber int, ghTokenMagicModules, buildId, buildStep,
310
353
data .MissingTests = missingTests
311
354
}
312
355
313
- // Run unit tests for missing test detector
314
- if err = runMissingTestUnitTests (
315
- mmLocalPath ,
316
- tpgbRepo .Path ,
317
- targetURL ,
318
- commitSha ,
319
- prNumber ,
320
- gh ,
321
- rnr ,
322
- ); err != nil {
323
- fmt .Println ("Error running missing test detector unit tests: " , err )
324
- errors ["Other" ] = append (errors ["Other" ], "Missing test detector unit tests failed to run." )
356
+ // Run unit tests for missing test detector (currently only for beta)
357
+ if pathChanged ("tools/missing-test-detector" , tpgbRepo .ChangedFiles ) {
358
+ fmt .Printf ("Found diffs in missing test detector:\n %s\n Running tests.\n " , diffs )
359
+ if err = runMissingTestUnitTests (
360
+ mmLocalPath ,
361
+ tpgbRepo .Path ,
362
+ targetURL ,
363
+ commitSha ,
364
+ prNumber ,
365
+ gh ,
366
+ rnr ,
367
+ ); err != nil {
368
+ fmt .Println ("Error running missing test detector unit tests: " , err )
369
+ errors ["Other" ] = append (errors ["Other" ], "Missing test detector unit tests failed to run." )
370
+ }
325
371
}
326
372
327
373
// Add errors to data as an ordered list
@@ -356,18 +402,6 @@ func execGenerateComment(prNumber int, ghTokenMagicModules, buildId, buildStep,
356
402
}
357
403
}
358
404
359
- func computeDiff (repo * source.Repo , oldBranch string , ctlr * source.Controller ) (string , error ) {
360
- if err := ctlr .Fetch (repo , oldBranch ); err != nil {
361
- return "" , err
362
- }
363
- // Get shortstat summary of the diff
364
- diff , err := ctlr .Diff (repo , oldBranch , repo .Branch )
365
- if err != nil {
366
- return "" , err
367
- }
368
- return strings .TrimSuffix (diff , "\n " ), nil
369
- }
370
-
371
405
// Build the diff processor for tpg or tpgb
372
406
func buildDiffProcessor (diffProcessorPath , providerLocalPath string , env map [string ]string , rnr ExecRunner ) error {
373
407
for _ , path := range []string {"old" , "new" , "bin" } {
@@ -515,21 +549,6 @@ func updatePackageName(name, path string, rnr ExecRunner) error {
515
549
// Run unit tests for the missing test detector.
516
550
// Report results using Github API.
517
551
func runMissingTestUnitTests (mmLocalPath , tpgbLocalPath , targetURL , commitSha string , prNumber int , gh GithubClient , rnr ExecRunner ) error {
518
- if err := rnr .PushDir (mmLocalPath ); err != nil {
519
- return err
520
- }
521
-
522
- diffs , err := rnr .Run ("git" , []string {"diff" , "HEAD" , "origin/main" , "tools/missing-test-detector" }, nil )
523
- if err != nil {
524
- return err
525
- }
526
- if diffs == "" {
527
- // Short-circuit if there are no changes to the missing test detector
528
- return rnr .PopDir ()
529
- }
530
-
531
- fmt .Printf ("Found diffs in missing test detector:\n %s\n Running tests.\n " , diffs )
532
-
533
552
missingTestDetectorPath := filepath .Join (mmLocalPath , "tools" , "missing-test-detector" )
534
553
rnr .PushDir (missingTestDetectorPath )
535
554
if _ , err := rnr .Run ("go" , []string {"mod" , "tidy" }, nil ); err != nil {
@@ -565,6 +584,40 @@ func formatDiffComment(data diffCommentData) (string, error) {
565
584
return sb .String (), nil
566
585
}
567
586
587
+ var resourceFileRegexp = regexp .MustCompile (`^.*/services/[^/]+/(?:data_source_|resource_|iam_)(.*?)(?:_test|_sweeper|_iam_test|_generated_test|_internal_test)?.go` )
588
+ var resourceDocsRegexp = regexp .MustCompile (`^.*website/docs/(?:r|d)/(.*).html.markdown` )
589
+
590
+ func fileToResource (path string ) string {
591
+ var submatches []string
592
+ if strings .HasSuffix (path , ".go" ) {
593
+ submatches = resourceFileRegexp .FindStringSubmatch (path )
594
+ } else if strings .HasSuffix (path , ".html.markdown" ) {
595
+ submatches = resourceDocsRegexp .FindStringSubmatch (path )
596
+ }
597
+
598
+ if len (submatches ) == 0 {
599
+ return ""
600
+ }
601
+
602
+ // The regexes will each return the resource name as the first
603
+ // submatch, stripping any prefixes or suffixes.
604
+ resource := submatches [1 ]
605
+
606
+ if ! strings .HasPrefix (resource , "google_" ) {
607
+ resource = "google_" + resource
608
+ }
609
+ return resource
610
+ }
611
+
612
+ func pathChanged (path string , changedFiles []string ) bool {
613
+ for _ , f := range changedFiles {
614
+ if strings .HasPrefix (f , path ) {
615
+ return true
616
+ }
617
+ }
618
+ return false
619
+ }
620
+
568
621
func init () {
569
622
rootCmd .AddCommand (generateCommentCmd )
570
623
}
0 commit comments