Skip to content

Commit 9af3aae

Browse files
committed
Merge branch 'master' of https://github.com/go-gitea/gitea
2 parents 3566e9e + ab62da2 commit 9af3aae

37 files changed

+1635
-1505
lines changed

docker/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@ DOCKER_REF := $(DOCKER_IMAGE):$(DOCKER_TAG)
88
.PHONY: docker
99
docker:
1010
docker run -ti --rm -v $(CURDIR):/srv/app/src/code.gitea.io/gitea -w /srv/app/src/code.gitea.io/gitea -e TAGS="bindata $(TAGS)" webhippie/golang:edge make clean generate build
11-
docker build -t $(DOCKER_REF) .
11+
docker build --disable-content-trust=false -t $(DOCKER_REF) .

docs/content/doc/advanced/customizing-gitea.en-us.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ When you find the correct .tmpl file, you need to copy it in the `custom/templat
4949
You can now customize the template you copied in `custom/templates`, being carefully to not break the Gitea syntax.
5050
Any statement contained inside `{{` and `}}` are Gitea templete's syntax and shouldn't be touch, unless you know what are you doing.
5151

52+
To add in custom HTML to the header or the footer of the page, in the `templates/custom` directory there are `header.tmpl` and `footer.tmpl` that can be modified. This is useful if you want to add in custom CSS files, or additional Javascript.
53+
5254
## Customizing gitignores, labels, licenses, locales, and readmes.
5355

5456
Place your own files in corresponding sub-folder under `custom/options`.

models/action.go

Lines changed: 57 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -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 (
5958
issueReferenceKeywordsPat *regexp.Regexp
6059
)
6160

61+
const issueRefRegexpStr = `(?:\S+/\S=)?#\d+`
62+
6263
func 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

6667
func init() {
6768
issueCloseKeywordsPat = regexp.MustCompile(assembleKeywordsPattern(issueCloseKeywords))
6869
issueReopenKeywordsPat = 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 {
390391
return 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.
394438
func 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

399443
refMarked := make(map[int64]bool)
400444
for _, 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)
418446
if err != nil {
419-
if IsErrIssueNotExist(err) || err == errMissingIssueNumber || err == errInvalidIssueNumber {
420-
continue
421-
}
422447
return err
423448
}
424449

425-
if refMarked[issue.ID] {
450+
if issue == nil || refMarked[issue.ID] {
426451
continue
427452
}
428453
refMarked[issue.ID] = true
@@ -436,31 +461,12 @@ func UpdateIssuesCommit(doer *User, repo *Repository, commits []*PushCommit) err
436461
refMarked = make(map[int64]bool)
437462
// FIXME: can merge this one and next one to a common function.
438463
for _, 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)
456465
if err != nil {
457-
if IsErrIssueNotExist(err) || err == errMissingIssueNumber || err == errInvalidIssueNumber {
458-
continue
459-
}
460466
return err
461467
}
462468

463-
if refMarked[issue.ID] {
469+
if issue == nil || refMarked[issue.ID] {
464470
continue
465471
}
466472
refMarked[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.
486492
for _, 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)
504494
if err != nil {
505-
if IsErrIssueNotExist(err) || err == errMissingIssueNumber || err == errInvalidIssueNumber {
506-
continue
507-
}
508495
return err
509496
}
510497

511-
if refMarked[issue.ID] {
498+
if issue == nil || refMarked[issue.ID] {
512499
continue
513500
}
514501
refMarked[issue.ID] = true

models/action_test.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package models
22

33
import (
4+
"fmt"
45
"path"
56
"strings"
67
"testing"
@@ -154,6 +155,35 @@ func TestPushCommits_AvatarLink(t *testing.T) {
154155
pushCommits.AvatarLink("nonexistent@example.com"))
155156
}
156157

158+
func Test_getIssueFromRef(t *testing.T) {
159+
assert.NoError(t, PrepareTestDatabase())
160+
repo := AssertExistsAndLoadBean(t, &Repository{ID: 1}).(*Repository)
161+
for _, test := range []struct {
162+
Ref string
163+
ExpectedIssueID int64
164+
}{
165+
{"#2", 2},
166+
{"reopen #2", 2},
167+
{"user2/repo2#1", 4},
168+
{"fixes user2/repo2#1", 4},
169+
} {
170+
issue, err := getIssueFromRef(repo, test.Ref)
171+
assert.NoError(t, err)
172+
if assert.NotNil(t, issue) {
173+
assert.EqualValues(t, test.ExpectedIssueID, issue.ID)
174+
}
175+
}
176+
177+
for _, badRef := range []string{
178+
"doesnotexist/doesnotexist#1",
179+
fmt.Sprintf("#%d", NonexistentID),
180+
} {
181+
issue, err := getIssueFromRef(repo, badRef)
182+
assert.NoError(t, err)
183+
assert.Nil(t, issue)
184+
}
185+
}
186+
157187
func TestUpdateIssuesCommit(t *testing.T) {
158188
assert.NoError(t, PrepareTestDatabase())
159189
pushCommits := []*PushCommit{

models/issue.go

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
package models
66

77
import (
8-
"errors"
98
"fmt"
109
"path"
1110
"sort"
@@ -22,11 +21,6 @@ import (
2221
"code.gitea.io/gitea/modules/util"
2322
)
2423

25-
var (
26-
errMissingIssueNumber = errors.New("No issue number specified")
27-
errInvalidIssueNumber = errors.New("Invalid issue number")
28-
)
29-
3024
// Issue represents an issue or pull request of repository.
3125
type Issue struct {
3226
ID int64 `xorm:"pk autoincr"`
@@ -961,32 +955,6 @@ func NewIssue(repo *Repository, issue *Issue, labelIDs []int64, uuids []string)
961955
return nil
962956
}
963957

964-
// GetIssueByRef returns an Issue specified by a GFM reference.
965-
// See https://help.github.com/articles/writing-on-github#references for more information on the syntax.
966-
func GetIssueByRef(ref string) (*Issue, error) {
967-
n := strings.IndexByte(ref, '#')
968-
if n == -1 {
969-
return nil, errMissingIssueNumber
970-
}
971-
972-
index, err := com.StrTo(ref[n+1:]).Int64()
973-
if err != nil {
974-
return nil, errInvalidIssueNumber
975-
}
976-
977-
i := strings.IndexByte(ref[:n], '/')
978-
if i < 2 {
979-
return nil, ErrInvalidReference
980-
}
981-
982-
repo, err := GetRepositoryByOwnerAndName(ref[:i], ref[i+1:n])
983-
if err != nil {
984-
return nil, err
985-
}
986-
987-
return GetIssueByIndex(repo.ID, index)
988-
}
989-
990958
// GetRawIssueByIndex returns raw issue without loading attributes by index in a repository.
991959
func GetRawIssueByIndex(repoID, index int64) (*Issue, error) {
992960
issue := &Issue{

models/repo.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -605,9 +605,14 @@ func (repo *Repository) RepoPath() string {
605605
return repo.repoPath(x)
606606
}
607607

608+
// GitConfigPath returns the path to a repository's git config/ directory
609+
func GitConfigPath(repoPath string) string {
610+
return filepath.Join(repoPath, "config")
611+
}
612+
608613
// GitConfigPath returns the repository git config path
609614
func (repo *Repository) GitConfigPath() string {
610-
return filepath.Join(repo.RepoPath(), "config")
615+
return GitConfigPath(repo.RepoPath())
611616
}
612617

613618
// RelLink returns the repository relative link

0 commit comments

Comments
 (0)