@@ -14,15 +14,14 @@ import (
1414"time"
1515"unicode"
1616
17- "github.com/Unknwon/com"
18- "github.com/go-xorm/builder"
19-
2017"code.gitea.io/git"
21- api "code.gitea.io/sdk/gitea"
22-
2318"code.gitea.io/gitea/modules/base"
2419"code.gitea.io/gitea/modules/log"
2520"code.gitea.io/gitea/modules/setting"
21+ api "code.gitea.io/sdk/gitea"
22+
23+ "github.com/Unknwon/com"
24+ "github.com/go-xorm/builder"
2625)
2726
2827// ActionType represents the type of an action.
@@ -59,14 +58,16 @@ var (
5958issueReferenceKeywordsPat * regexp.Regexp
6059)
6160
61+ const issueRefRegexpStr = `(?:\S+/\S=)?#\d+`
62+
6263func assembleKeywordsPattern (words []string ) string {
63- return fmt .Sprintf (`(?i)(?:%s) \S+ ` , strings .Join (words , "|" ))
64+ return fmt .Sprintf (`(?i)(?:%s) %s ` , strings .Join (words , "|" ), issueRefRegexpStr )
6465}
6566
6667func init () {
6768issueCloseKeywordsPat = regexp .MustCompile (assembleKeywordsPattern (issueCloseKeywords ))
6869issueReopenKeywordsPat = regexp .MustCompile (assembleKeywordsPattern (issueReopenKeywords ))
69- issueReferenceKeywordsPat = regexp .MustCompile (`(?i)(?:)(^| )\S+` )
70+ issueReferenceKeywordsPat = regexp .MustCompile (issueRefRegexpStr )
7071}
7172
7273// Action represents user operation type and other information to
@@ -390,6 +391,49 @@ func (pc *PushCommits) AvatarLink(email string) string {
390391return pc .avatars [email ]
391392}
392393
394+ // getIssueFromRef returns the issue referenced by a ref. Returns a nil *Issue
395+ // if the provided ref is misformatted or references a non-existent issue.
396+ func getIssueFromRef (repo * Repository , ref string ) (* Issue , error ) {
397+ ref = ref [strings .IndexByte (ref , ' ' )+ 1 :]
398+ ref = strings .TrimRightFunc (ref , issueIndexTrimRight )
399+
400+ var refRepo * Repository
401+ poundIndex := strings .IndexByte (ref , '#' )
402+ if poundIndex < 0 {
403+ return nil , nil
404+ } else if poundIndex == 0 {
405+ refRepo = repo
406+ } else {
407+ slashIndex := strings .IndexByte (ref , '/' )
408+ if slashIndex < 0 || slashIndex >= poundIndex {
409+ return nil , nil
410+ }
411+ ownerName := ref [:slashIndex ]
412+ repoName := ref [slashIndex + 1 : poundIndex ]
413+ var err error
414+ refRepo , err = GetRepositoryByOwnerAndName (ownerName , repoName )
415+ if err != nil {
416+ if IsErrRepoNotExist (err ) {
417+ return nil , nil
418+ }
419+ return nil , err
420+ }
421+ }
422+ issueIndex , err := strconv .ParseInt (ref [poundIndex + 1 :], 10 , 64 )
423+ if err != nil {
424+ return nil , nil
425+ }
426+
427+ issue , err := GetIssueByIndex (refRepo .ID , int64 (issueIndex ))
428+ if err != nil {
429+ if IsErrIssueNotExist (err ) {
430+ return nil , nil
431+ }
432+ return nil , err
433+ }
434+ return issue , nil
435+ }
436+
393437// UpdateIssuesCommit checks if issues are manipulated by commit message.
394438func UpdateIssuesCommit (doer * User , repo * Repository , commits []* PushCommit ) error {
395439// Commits are appended in the reverse order.
@@ -398,31 +442,12 @@ func UpdateIssuesCommit(doer *User, repo *Repository, commits []*PushCommit) err
398442
399443refMarked := make (map [int64 ]bool )
400444for _ , ref := range issueReferenceKeywordsPat .FindAllString (c .Message , - 1 ) {
401- ref = ref [strings .IndexByte (ref , byte (' ' ))+ 1 :]
402- ref = strings .TrimRightFunc (ref , issueIndexTrimRight )
403-
404- if len (ref ) == 0 {
405- continue
406- }
407-
408- // Add repo name if missing
409- if ref [0 ] == '#' {
410- ref = fmt .Sprintf ("%s%s" , repo .FullName (), ref )
411- } else if ! strings .Contains (ref , "/" ) {
412- // FIXME: We don't support User#ID syntax yet
413- // return ErrNotImplemented
414- continue
415- }
416-
417- issue , err := GetIssueByRef (ref )
445+ issue , err := getIssueFromRef (repo , ref )
418446if err != nil {
419- if IsErrIssueNotExist (err ) || err == errMissingIssueNumber || err == errInvalidIssueNumber {
420- continue
421- }
422447return err
423448}
424449
425- if refMarked [issue .ID ] {
450+ if issue == nil || refMarked [issue .ID ] {
426451continue
427452}
428453refMarked [issue .ID ] = true
@@ -436,31 +461,12 @@ func UpdateIssuesCommit(doer *User, repo *Repository, commits []*PushCommit) err
436461refMarked = make (map [int64 ]bool )
437462// FIXME: can merge this one and next one to a common function.
438463for _ , ref := range issueCloseKeywordsPat .FindAllString (c .Message , - 1 ) {
439- ref = ref [strings .IndexByte (ref , byte (' ' ))+ 1 :]
440- ref = strings .TrimRightFunc (ref , issueIndexTrimRight )
441-
442- if len (ref ) == 0 {
443- continue
444- }
445-
446- // Add repo name if missing
447- if ref [0 ] == '#' {
448- ref = fmt .Sprintf ("%s%s" , repo .FullName (), ref )
449- } else if ! strings .Contains (ref , "/" ) {
450- // We don't support User#ID syntax yet
451- // return ErrNotImplemented
452- continue
453- }
454-
455- issue , err := GetIssueByRef (ref )
464+ issue , err := getIssueFromRef (repo , ref )
456465if err != nil {
457- if IsErrIssueNotExist (err ) || err == errMissingIssueNumber || err == errInvalidIssueNumber {
458- continue
459- }
460466return err
461467}
462468
463- if refMarked [issue .ID ] {
469+ if issue == nil || refMarked [issue .ID ] {
464470continue
465471}
466472refMarked [issue .ID ] = true
@@ -484,31 +490,12 @@ func UpdateIssuesCommit(doer *User, repo *Repository, commits []*PushCommit) err
484490
485491// It is conflict to have close and reopen at same time, so refsMarked doesn't need to reinit here.
486492for _ , ref := range issueReopenKeywordsPat .FindAllString (c .Message , - 1 ) {
487- ref = ref [strings .IndexByte (ref , byte (' ' ))+ 1 :]
488- ref = strings .TrimRightFunc (ref , issueIndexTrimRight )
489-
490- if len (ref ) == 0 {
491- continue
492- }
493-
494- // Add repo name if missing
495- if ref [0 ] == '#' {
496- ref = fmt .Sprintf ("%s%s" , repo .FullName (), ref )
497- } else if ! strings .Contains (ref , "/" ) {
498- // We don't support User#ID syntax yet
499- // return ErrNotImplemented
500- continue
501- }
502-
503- issue , err := GetIssueByRef (ref )
493+ issue , err := getIssueFromRef (repo , ref )
504494if err != nil {
505- if IsErrIssueNotExist (err ) || err == errMissingIssueNumber || err == errInvalidIssueNumber {
506- continue
507- }
508495return err
509496}
510497
511- if refMarked [issue .ID ] {
498+ if issue == nil || refMarked [issue .ID ] {
512499continue
513500}
514501refMarked [issue .ID ] = true
0 commit comments