Skip to content

Commit 444ebe9

Browse files
committed
Merge remote-tracking branch 'giteaofficial/main'
* giteaofficial/main: Refactor markup render system (go-gitea#32612) Add vue-tsc (go-gitea#32601)
2 parents 9cd5b44 + 633785a commit 444ebe9

Some content is hidden

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

68 files changed

+1242
-1197
lines changed

Makefile

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -377,12 +377,12 @@ lint-backend-fix: lint-go-fix lint-go-vet lint-editorconfig
377377
.PHONY: lint-js
378378
lint-js: node_modules
379379
npx eslint --color --max-warnings=0 --ext js,ts,vue $(ESLINT_FILES)
380-
# npx tsc
380+
# npx vue-tsc
381381

382382
.PHONY: lint-js-fix
383383
lint-js-fix: node_modules
384384
npx eslint --color --max-warnings=0 --ext js,ts,vue $(ESLINT_FILES) --fix
385-
# npx tsc
385+
# npx vue-tsc
386386

387387
.PHONY: lint-css
388388
lint-css: node_modules
@@ -451,6 +451,10 @@ lint-templates: .venv node_modules
451451
lint-yaml: .venv
452452
@poetry run yamllint .
453453

454+
.PHONY: tsc
455+
tsc:
456+
npx vue-tsc
457+
454458
.PHONY: watch
455459
watch:
456460
@bash tools/watch.sh

assets/go-licenses.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

models/activities/action.go

Lines changed: 4 additions & 4 deletions
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

Lines changed: 3 additions & 7 deletions
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
}
Lines changed: 53 additions & 0 deletions
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

Lines changed: 27 additions & 0 deletions
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+
}
Lines changed: 73 additions & 0 deletions
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+
}
Lines changed: 76 additions & 0 deletions
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+
}

0 commit comments

Comments
 (0)