@@ -15,6 +15,7 @@ import (
1515 "time"
1616
1717 log "github.com/linuxfoundation/easycla/cla-backend-go/logging"
18+ "github.com/linuxfoundation/easycla/cla-backend-go/users"
1819 "github.com/linuxfoundation/easycla/cla-backend-go/utils"
1920 "github.com/sirupsen/logrus"
2021
@@ -327,13 +328,15 @@ func GetCoAuthorsFromCommit(
327328 commitMessage := commit .GetCommit ().GetMessage ()
328329 // log.WithFields(f).Debugf("commit message: %s", commitMessage)
329330
330- re := regexp .MustCompile (`(?i)co-authored-by: (.*) <(.* )>` )
331+ re := regexp .MustCompile (`(?i)co-authored-by:\s*(.+?)\s*<([^<>]+ )>` )
331332 matches := re .FindAllStringSubmatch (commitMessage , - 1 )
332333 for _ , match := range matches {
333334 name := strings .TrimSpace (match [1 ])
334- email := strings .TrimSpace (match [2 ])
335- coAuthors = append (coAuthors , [2 ]string {name , email })
336- log .WithFields (f ).Debugf ("found co-author: name: %s, email: %s" , name , email )
335+ email := strings .ToLower (strings .TrimSpace (match [2 ]))
336+ if name != "" && email != "" {
337+ coAuthors = append (coAuthors , [2 ]string {name , email })
338+ log .WithFields (f ).Debugf ("found co-author: name: %s, email: %s" , name , email )
339+ }
337340 }
338341 }
339342 return coAuthors
@@ -343,6 +346,7 @@ func GetCoAuthorsFromCommit(
343346func ExpandWithCoAuthors (
344347 ctx context.Context ,
345348 client * github.Client ,
349+ usersService users.Service ,
346350 commit * github.RepositoryCommit ,
347351 pr int ,
348352 installationID int64 ,
@@ -355,7 +359,7 @@ func ExpandWithCoAuthors(
355359 coAuthors := GetCoAuthorsFromCommit (ctx , commit )
356360 log .WithFields (f ).Debugf ("co-authors found: %s" , coAuthors )
357361 for _ , coAuthor := range coAuthors {
358- summary := GetCoAuthorCommits (ctx , client , coAuthor , commit , pr , installationID )
362+ summary := GetCoAuthorCommits (ctx , client , usersService , coAuthor , commit , pr , installationID )
359363 * commitAuthors = append (* commitAuthors , summary )
360364 }
361365}
@@ -374,9 +378,11 @@ func IsValidGitHubUsername(username string) bool {
374378 return true
375379}
376380
381+ //nolint:gocyclo // complexity is acceptable for now
377382func GetCoAuthorCommits (
378383 ctx context.Context ,
379384 client * github.Client ,
385+ usersService users.Service ,
380386 coAuthor [2 ]string ,
381387 commit * github.RepositoryCommit ,
382388 pr int ,
@@ -398,8 +404,10 @@ func GetCoAuthorCommits(
398404 )
399405 name = strings .TrimSpace (coAuthor [0 ])
400406 email = strings .TrimSpace (coAuthor [1 ])
407+ lName := strings .ToLower (name )
401408
402- if cachedUser , ok := GithubUserCache .Get ([2 ]string {name , email }); ok {
409+ cacheKey := [2 ]string {lName , email }
410+ if cachedUser , ok := GithubUserCache .Get (cacheKey ); ok {
403411 log .WithFields (f ).Debugf ("GitHub user found in cache for name/email: %s/%s: %+v" , name , email , cachedUser )
404412 var summary * UserCommitSummary
405413 if cachedUser != nil {
@@ -454,19 +462,63 @@ func GetCoAuthorCommits(
454462 }
455463 }
456464
457- // 3. Try to find user by email
465+ // 3. Try to find user by email via GitHub APIs
458466 if user == nil {
459467 user , err = SearchGithubUserByEmail (ctx , client , email )
460468 if err != nil {
461- log .WithFields (f ).Debugf ("Co-author GitHub user not found via email %s: %v (error: %v)" , email , coAuthor , err )
469+ log .WithFields (f ).Debugf ("Co-author GitHub user not found via github email %s: %v (error: %v)" , email , coAuthor , err )
462470 user = nil
463471 }
464472 }
465473
474+ // 3b. Try to find user by email in our database
475+ if user == nil {
476+ var githubID string
477+ dbUsers , err2 := usersService .GetUsersByLFEmail (email )
478+ if err2 == nil {
479+ for _ , dbUser := range dbUsers {
480+ if dbUser .GithubID != "" {
481+ githubID = dbUser .GithubID
482+ // log.WithFields(f).Debugf("FOUND githubID.1 = %s", githubID)
483+ break
484+ }
485+ }
486+ } else {
487+ log .WithFields (f ).Debugf ("Co-author GitHub user not found via lf email %s: %v (error: %v)" , email , coAuthor , err2 )
488+ }
489+ if githubID == "" {
490+ dbUsers , err2 := usersService .GetUsersByEmail (email )
491+ if err2 == nil {
492+ for _ , dbUser := range dbUsers {
493+ if dbUser .GithubID != "" {
494+ githubID = dbUser .GithubID
495+ // log.WithFields(f).Debugf("FOUND githubID.2 = %s", githubID)
496+ break
497+ }
498+ }
499+ } else {
500+ log .WithFields (f ).Debugf ("Co-author GitHub user not found via emails %s: %v (error: %v)" , email , coAuthor , err2 )
501+ }
502+ }
503+ if githubID != "" {
504+ githubIDInt , err2 := strconv .ParseInt (githubID , 10 , 64 )
505+ if err2 != nil {
506+ log .WithFields (f ).Debugf ("Co-author GitHub user not found via lf email %s, wrong GitHub ID: %s: %v (error: %v)" , email , githubID , coAuthor , err2 )
507+ } else {
508+ user , err = GetGithubUserByID (ctx , client , githubIDInt )
509+ if err != nil {
510+ log .WithFields (f ).Debugf ("Error fetching user by ID %d: %v" , githubIDInt , err )
511+ user = nil
512+ }
513+ // log.WithFields(f).Debugf("FOUND user = (%s, %d, %s, %s)", *user.Login, *user.ID, *user.Name, *user.Email)
514+ }
515+ }
516+ }
517+
466518 // 4. Last resort - try to find by name=login
467- if user == nil && IsValidGitHubUsername (name ) {
519+ if user == nil && IsValidGitHubUsername (lName ) {
468520 // Note that Co-authored-by: name <email> is not actually a GitHub login but rather a name - but we are trying hard to find a GitHub profile
469- user , err = GetGithubUserByLogin (ctx , client , name )
521+ user , err = GetGithubUserByLogin (ctx , client , lName )
470522 if err != nil {
471523 log .WithFields (f ).Debugf ("Co-author GitHub user not found via name=login=%s: %v (error: %v)" , name , coAuthor , err )
472524 user = nil
@@ -512,11 +564,11 @@ func GetCoAuthorCommits(
512564 log .WithFields (f ).Debugf ("Co-author GitHub user details not found: %v" , coAuthor )
513565 }
514566
515- GithubUserCache .Set ([ 2 ] string { name , email } , user )
567+ GithubUserCache .Set (cacheKey , user )
516568 return summary
517569}
518570
519- func GetPullRequestCommitAuthors (ctx context.Context , installationID int64 , pullRequestID int , owner , repo string , withCoAuthors bool ) ([]* UserCommitSummary , * string , error ) {
571+ func GetPullRequestCommitAuthors (ctx context.Context , usersService users. Service , installationID int64 , pullRequestID int , owner , repo string , withCoAuthors bool ) ([]* UserCommitSummary , * string , error ) {
520572 f := logrus.Fields {
521573 "functionName" : "github.github_repository.GetPullRequestCommitAuthors" ,
522574 "pullRequestID" : pullRequestID ,
@@ -571,7 +623,7 @@ func GetPullRequestCommitAuthors(ctx context.Context, installationID int64, pull
571623 Authorized : false ,
572624 })
573625 if withCoAuthors {
574- ExpandWithCoAuthors (ctx , client , commit , pullRequestID , installationID , & userCommitSummary )
626+ ExpandWithCoAuthors (ctx , client , usersService , commit , pullRequestID , installationID , & userCommitSummary )
575627 }
576628 }
577629
0 commit comments