Skip to content

Commit e6ef5d1

Browse files
committed
fix
1 parent bc7d599 commit e6ef5d1

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+1088
-1178
lines changed

assets/go-licenses.json

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

models/activities/action.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ func (a *Action) LoadActUser(ctx context.Context) {
200200
}
201201
}
202202

203-
func (a *Action) loadRepo(ctx context.Context) {
203+
func (a *Action) LoadRepo(ctx context.Context) {
204204
if a.Repo != nil {
205205
return
206206
}
@@ -250,7 +250,7 @@ func (a *Action) GetActDisplayNameTitle(ctx context.Context) string {
250250

251251
// GetRepoUserName returns the name of the action repository owner.
252252
func (a *Action) GetRepoUserName(ctx context.Context) string {
253-
a.loadRepo(ctx)
253+
a.LoadRepo(ctx)
254254
if a.Repo == nil {
255255
return "(non-existing-repo)"
256256
}
@@ -265,7 +265,7 @@ func (a *Action) ShortRepoUserName(ctx context.Context) string {
265265

266266
// GetRepoName returns the name of the action repository.
267267
func (a *Action) GetRepoName(ctx context.Context) string {
268-
a.loadRepo(ctx)
268+
a.LoadRepo(ctx)
269269
if a.Repo == nil {
270270
return "(non-existing-repo)"
271271
}
@@ -644,7 +644,7 @@ func NotifyWatchers(ctx context.Context, actions ...*Action) error {
644644
}
645645

646646
if repoChanged {
647-
act.loadRepo(ctx)
647+
act.LoadRepo(ctx)
648648
repo = act.Repo
649649

650650
// check repo owner exist.

models/issues/comment_code.go

+3-7
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ import (
77
"context"
88

99
"code.gitea.io/gitea/models/db"
10+
"code.gitea.io/gitea/models/renderhelper"
1011
user_model "code.gitea.io/gitea/models/user"
11-
"code.gitea.io/gitea/modules/markup"
1212
"code.gitea.io/gitea/modules/markup/markdown"
1313

1414
"xorm.io/builder"
@@ -112,12 +112,8 @@ func findCodeComments(ctx context.Context, opts FindCommentsOptions, issue *Issu
112112
}
113113

114114
var err error
115-
rctx := markup.NewRenderContext(ctx).
116-
WithRepoFacade(issue.Repo).
117-
WithLinks(markup.Links{Base: issue.Repo.Link()}).
118-
WithMetas(issue.Repo.ComposeMetas(ctx))
119-
if comment.RenderedContent, err = markdown.RenderString(rctx,
120-
comment.Content); err != nil {
115+
rctx := renderhelper.NewRenderContextRepoComment(ctx, issue.Repo)
116+
if comment.RenderedContent, err = markdown.RenderString(rctx, comment.Content); err != nil {
121117
return nil, err
122118
}
123119
}

models/renderhelper/commit_checker.go

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// Copyright 2024 The Gitea Authors. All rights reserved.
2+
// SPDX-License-Identifier: MIT
3+
4+
package renderhelper
5+
6+
import (
7+
"context"
8+
"io"
9+
10+
"code.gitea.io/gitea/modules/git"
11+
"code.gitea.io/gitea/modules/gitrepo"
12+
"code.gitea.io/gitea/modules/log"
13+
)
14+
15+
type commitChecker struct {
16+
ctx context.Context
17+
commitCache map[string]bool
18+
gitRepoFacade gitrepo.Repository
19+
20+
gitRepo *git.Repository
21+
gitRepoCloser io.Closer
22+
}
23+
24+
func newCommitChecker(ctx context.Context, gitRepo gitrepo.Repository) *commitChecker {
25+
return &commitChecker{ctx: ctx, commitCache: make(map[string]bool), gitRepoFacade: gitRepo}
26+
}
27+
28+
func (c *commitChecker) Close() error {
29+
if c != nil && c.gitRepoCloser != nil {
30+
return c.gitRepoCloser.Close()
31+
}
32+
return nil
33+
}
34+
35+
func (c *commitChecker) IsCommitIDExisting(commitID string) bool {
36+
exist, inCache := c.commitCache[commitID]
37+
if inCache {
38+
return exist
39+
}
40+
41+
if c.gitRepo == nil {
42+
r, closer, err := gitrepo.RepositoryFromContextOrOpen(c.ctx, c.gitRepoFacade)
43+
if err != nil {
44+
log.Error("unable to open repository: %s Error: %v", gitrepo.RepoGitURL(c.gitRepoFacade), err)
45+
return false
46+
}
47+
c.gitRepo, c.gitRepoCloser = r, closer
48+
}
49+
50+
exist = c.gitRepo.IsReferenceExist(commitID) // Don't use IsObjectExist since it doesn't support short hashs with gogit edition.
51+
c.commitCache[commitID] = exist
52+
return exist
53+
}

models/renderhelper/main_test.go

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Copyright 2024 The Gitea Authors. All rights reserved.
2+
// SPDX-License-Identifier: MIT
3+
4+
package renderhelper
5+
6+
import (
7+
"context"
8+
"testing"
9+
10+
"code.gitea.io/gitea/models/unittest"
11+
"code.gitea.io/gitea/modules/markup"
12+
)
13+
14+
func TestMain(m *testing.M) {
15+
unittest.MainTest(m, &unittest.TestOptions{
16+
FixtureFiles: []string{"repository.yml", "user.yml"},
17+
SetUp: func() error {
18+
markup.RenderBehaviorForTesting.DisableAdditionalAttributes = true
19+
markup.Init(&markup.RenderHelperFuncs{
20+
IsUsernameMentionable: func(ctx context.Context, username string) bool {
21+
return username == "user2"
22+
},
23+
})
24+
return nil
25+
},
26+
})
27+
}

models/renderhelper/repo_comment.go

+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
// Copyright 2024 The Gitea Authors. All rights reserved.
2+
// SPDX-License-Identifier: MIT
3+
4+
package renderhelper
5+
6+
import (
7+
"context"
8+
"fmt"
9+
10+
repo_model "code.gitea.io/gitea/models/repo"
11+
"code.gitea.io/gitea/modules/markup"
12+
"code.gitea.io/gitea/modules/util"
13+
)
14+
15+
type RepoComment struct {
16+
ctx *markup.RenderContext
17+
opts RepoCommentOptions
18+
19+
commitChecker *commitChecker
20+
repoLink string
21+
}
22+
23+
func (r *RepoComment) CleanUp() {
24+
_ = r.commitChecker.Close()
25+
}
26+
27+
func (r *RepoComment) IsCommitIDExisting(commitID string) bool {
28+
return r.commitChecker.IsCommitIDExisting(commitID)
29+
}
30+
31+
func (r *RepoComment) ResolveLink(link string, likeType markup.LinkType) (finalLink string) {
32+
switch likeType {
33+
case markup.LinkTypeApp:
34+
finalLink = r.ctx.ResolveLinkApp(link)
35+
default:
36+
finalLink = r.ctx.ResolveLinkRelative(r.repoLink, r.opts.CurrentRefPath, link)
37+
}
38+
return finalLink
39+
}
40+
41+
var _ markup.RenderHelper = (*RepoComment)(nil)
42+
43+
type RepoCommentOptions struct {
44+
DeprecatedRepoName string // it is only a patch for the non-standard "markup" api
45+
DeprecatedOwnerName string // it is only a patch for the non-standard "markup" api
46+
CurrentRefPath string // eg: "branch/main" or "commit/11223344"
47+
}
48+
49+
func NewRenderContextRepoComment(ctx context.Context, repo *repo_model.Repository, opts ...RepoCommentOptions) *markup.RenderContext {
50+
helper := &RepoComment{
51+
repoLink: repo.Link(),
52+
opts: util.OptionalArg(opts),
53+
}
54+
rctx := markup.NewRenderContext(ctx)
55+
helper.ctx = rctx
56+
if repo != nil {
57+
helper.repoLink = repo.Link()
58+
helper.commitChecker = newCommitChecker(ctx, repo)
59+
rctx = rctx.WithMetas(repo.ComposeMetas(ctx))
60+
} else {
61+
// this is almost dead code, only to pass the incorrect tests
62+
helper.repoLink = fmt.Sprintf("%s/%s", helper.opts.DeprecatedOwnerName, helper.opts.DeprecatedRepoName)
63+
rctx = rctx.WithMetas(map[string]string{
64+
"user": helper.opts.DeprecatedOwnerName,
65+
"repo": helper.opts.DeprecatedRepoName,
66+
67+
"markdownLineBreakStyle": "comment",
68+
"markupAllowShortIssuePattern": "true",
69+
})
70+
}
71+
rctx = rctx.WithHelper(helper)
72+
return rctx
73+
}
+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
// Copyright 2024 The Gitea Authors. All rights reserved.
2+
// SPDX-License-Identifier: MIT
3+
4+
package renderhelper
5+
6+
import (
7+
"context"
8+
"testing"
9+
10+
repo_model "code.gitea.io/gitea/models/repo"
11+
"code.gitea.io/gitea/models/unittest"
12+
"code.gitea.io/gitea/modules/markup"
13+
"code.gitea.io/gitea/modules/markup/markdown"
14+
15+
"github.com/stretchr/testify/assert"
16+
)
17+
18+
func TestRepoComment(t *testing.T) {
19+
unittest.PrepareTestEnv(t)
20+
21+
repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
22+
23+
t.Run("AutoLink", func(t *testing.T) {
24+
rctx := NewRenderContextRepoComment(context.Background(), repo1).WithMarkupType(markdown.MarkupName)
25+
rendered, err := markup.RenderString(rctx, `
26+
65f1bf27bc3bf70f64657658635e66094edbcb4d
27+
#1
28+
@user2
29+
`)
30+
assert.NoError(t, err)
31+
assert.Equal(t,
32+
`<p><a href="/user2/repo1/commit/65f1bf27bc3bf70f64657658635e66094edbcb4d" rel="nofollow"><code>65f1bf27bc</code></a><br/>
33+
<a href="/user2/repo1/issues/1" class="ref-issue" rel="nofollow">#1</a><br/>
34+
<a href="/user2" rel="nofollow">@user2</a></p>
35+
`, rendered)
36+
})
37+
38+
t.Run("AbsoluteAndRelative", func(t *testing.T) {
39+
rctx := NewRenderContextRepoComment(context.Background(), repo1).WithMarkupType(markdown.MarkupName)
40+
41+
// It is Gitea's old behavior, the relative path is resolved to the repo path
42+
// It is different from GitHub, GitHub resolves relative links to current page's path
43+
rendered, err := markup.RenderString(rctx, `
44+
[/test](/test)
45+
[./test](./test)
46+
![/image](/image)
47+
![./image](./image)
48+
`)
49+
assert.NoError(t, err)
50+
assert.Equal(t,
51+
`<p><a href="/user2/repo1/test" rel="nofollow">/test</a><br/>
52+
<a href="/user2/repo1/test" rel="nofollow">./test</a><br/>
53+
<a href="/user2/repo1/image" target="_blank" rel="nofollow noopener"><img src="/user2/repo1/image" alt="/image"/></a><br/>
54+
<a href="/user2/repo1/image" target="_blank" rel="nofollow noopener"><img src="/user2/repo1/image" alt="./image"/></a></p>
55+
`, rendered)
56+
})
57+
58+
t.Run("WithCurrentRefPath", func(t *testing.T) {
59+
rctx := NewRenderContextRepoComment(context.Background(), repo1, RepoCommentOptions{CurrentRefPath: "/commit/1234"}).
60+
WithMarkupType(markdown.MarkupName)
61+
62+
// the ref path is only used to render commit message: a commit message is rendered at the commit page with its commit ID path
63+
rendered, err := markup.RenderString(rctx, `
64+
[/test](/test)
65+
[./test](./test)
66+
![/image](/image)
67+
![./image](./image)
68+
`)
69+
assert.NoError(t, err)
70+
assert.Equal(t, `<p><a href="/user2/repo1/test" rel="nofollow">/test</a><br/>
71+
<a href="/user2/repo1/commit/1234/test" rel="nofollow">./test</a><br/>
72+
<a href="/user2/repo1/image" target="_blank" rel="nofollow noopener"><img src="/user2/repo1/image" alt="/image"/></a><br/>
73+
<a href="/user2/repo1/commit/1234/image" target="_blank" rel="nofollow noopener"><img src="/user2/repo1/commit/1234/image" alt="./image"/></a></p>
74+
`, rendered)
75+
})
76+
}

models/renderhelper/repo_file.go

+77
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
// Copyright 2024 The Gitea Authors. All rights reserved.
2+
// SPDX-License-Identifier: MIT
3+
4+
package renderhelper
5+
6+
import (
7+
"context"
8+
"fmt"
9+
"path"
10+
11+
repo_model "code.gitea.io/gitea/models/repo"
12+
"code.gitea.io/gitea/modules/markup"
13+
"code.gitea.io/gitea/modules/util"
14+
)
15+
16+
type RepoFile struct {
17+
ctx *markup.RenderContext
18+
opts RepoFileOptions
19+
20+
commitChecker *commitChecker
21+
repoLink string
22+
}
23+
24+
func (r *RepoFile) CleanUp() {
25+
_ = r.commitChecker.Close()
26+
}
27+
28+
func (r *RepoFile) IsCommitIDExisting(commitID string) bool {
29+
return r.commitChecker.IsCommitIDExisting(commitID)
30+
}
31+
32+
func (r *RepoFile) ResolveLink(link string, likeType markup.LinkType) string {
33+
finalLink := link
34+
switch likeType {
35+
case markup.LinkTypeApp:
36+
finalLink = r.ctx.ResolveLinkApp(link)
37+
case markup.LinkTypeDefault:
38+
finalLink = r.ctx.ResolveLinkRelative(path.Join(r.repoLink, "src", r.opts.CurrentRefPath), r.opts.CurrentTreePath, link)
39+
case markup.LinkTypeRaw:
40+
finalLink = r.ctx.ResolveLinkRelative(path.Join(r.repoLink, "raw", r.opts.CurrentRefPath), r.opts.CurrentTreePath, link)
41+
case markup.LinkTypeMedia:
42+
finalLink = r.ctx.ResolveLinkRelative(path.Join(r.repoLink, "media", r.opts.CurrentRefPath), r.opts.CurrentTreePath, link)
43+
}
44+
return finalLink
45+
}
46+
47+
var _ markup.RenderHelper = (*RepoFile)(nil)
48+
49+
type RepoFileOptions struct {
50+
DeprecatedRepoName string // it is only a patch for the non-standard "markup" api
51+
DeprecatedOwnerName string // it is only a patch for the non-standard "markup" api
52+
53+
CurrentRefPath string // eg: "branch/main"
54+
CurrentTreePath string // eg: "path/to/file" in the repo
55+
}
56+
57+
func NewRenderContextRepoFile(ctx context.Context, repo *repo_model.Repository, opts ...RepoFileOptions) *markup.RenderContext {
58+
helper := &RepoFile{opts: util.OptionalArg(opts)}
59+
rctx := markup.NewRenderContext(ctx)
60+
helper.ctx = rctx
61+
if repo != nil {
62+
helper.repoLink = repo.Link()
63+
helper.commitChecker = newCommitChecker(ctx, repo)
64+
rctx = rctx.WithMetas(repo.ComposeDocumentMetas(ctx))
65+
} else {
66+
// this is almost dead code, only to pass the incorrect tests
67+
helper.repoLink = fmt.Sprintf("%s/%s", helper.opts.DeprecatedOwnerName, helper.opts.DeprecatedRepoName)
68+
rctx = rctx.WithMetas(map[string]string{
69+
"user": helper.opts.DeprecatedOwnerName,
70+
"repo": helper.opts.DeprecatedRepoName,
71+
72+
"markdownLineBreakStyle": "document",
73+
})
74+
}
75+
rctx = rctx.WithHelper(helper)
76+
return rctx
77+
}

0 commit comments

Comments
 (0)