0
0
mirror of https://github.com/go-gitea/gitea.git synced 2026-05-22 21:45:24 +02:00

Merge branch 'go-gitea:main' into main

This commit is contained in:
Karthik Bhandary 2026-03-09 11:58:02 +05:30 committed by GitHub
commit ae7b1a1c2a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 2590 additions and 247 deletions

View File

@ -23,12 +23,12 @@ const (
// externalIssueLink an HTML link to an alphanumeric-style issue // externalIssueLink an HTML link to an alphanumeric-style issue
func externalIssueLink(baseURL, class, name string) string { func externalIssueLink(baseURL, class, name string) string {
return link(util.URLJoin(baseURL, name), class, name) return link(strings.TrimSuffix(baseURL, "/")+"/"+name, class, name)
} }
// numericLink an HTML to a numeric-style issue // numericLink an HTML to a numeric-style issue
func numericIssueLink(baseURL, class string, index int, marker string) string { func numericIssueLink(baseURL, class string, index int, marker string) string {
return link(util.URLJoin(baseURL, strconv.Itoa(index)), class, fmt.Sprintf("%s%d", marker, index)) return link(strings.TrimSuffix(baseURL, "/")+"/"+strconv.Itoa(index), class, fmt.Sprintf("%s%d", marker, index))
} }
// link an HTML link // link an HTML link
@ -116,7 +116,7 @@ func TestRender_IssueIndexPattern2(t *testing.T) {
links := make([]any, len(indices)) links := make([]any, len(indices))
for i, index := range indices { for i, index := range indices {
links[i] = numericIssueLink(util.URLJoin("/test-owner/test-repo", path), "ref-issue", index, marker) links[i] = numericIssueLink("/test-owner/test-repo/"+path, "ref-issue", index, marker)
} }
expectedNil := fmt.Sprintf(expectedFmt, links...) expectedNil := fmt.Sprintf(expectedFmt, links...)
testRenderIssueIndexPattern(t, s, expectedNil, NewTestRenderContext(TestAppURL, localMetas)) testRenderIssueIndexPattern(t, s, expectedNil, NewTestRenderContext(TestAppURL, localMetas))
@ -210,7 +210,7 @@ func TestRender_IssueIndexPattern5(t *testing.T) {
metas["regexp"] = pattern metas["regexp"] = pattern
links := make([]any, len(ids)) links := make([]any, len(ids))
for i, id := range ids { for i, id := range ids {
links[i] = link(util.URLJoin("https://someurl.com/someUser/someRepo/", id), "ref-issue ref-external-issue", names[i]) links[i] = link("https://someurl.com/someUser/someRepo/"+id, "ref-issue ref-external-issue", names[i])
} }
expected := fmt.Sprintf(expectedFmt, links...) expected := fmt.Sprintf(expectedFmt, links...)
@ -288,11 +288,11 @@ func TestRender_AutoLink(t *testing.T) {
} }
// render valid issue URLs // render valid issue URLs
test(util.URLJoin(TestRepoURL, "issues", "3333"), test(TestRepoURL+"issues/3333",
numericIssueLink(util.URLJoin(TestRepoURL, "issues"), "ref-issue", 3333, "#")) numericIssueLink(TestRepoURL+"issues", "ref-issue", 3333, "#"))
// render valid commit URLs // render valid commit URLs
tmp := util.URLJoin(TestRepoURL, "commit", "d8a994ef243349f321568f9e36d5c3f444b99cae") tmp := TestRepoURL + "commit/d8a994ef243349f321568f9e36d5c3f444b99cae"
test(tmp, "<a href=\""+tmp+"\" class=\"commit\"><code>d8a994ef24</code></a>") test(tmp, "<a href=\""+tmp+"\" class=\"commit\"><code>d8a994ef24</code></a>")
tmp += "#diff-2" tmp += "#diff-2"
test(tmp, "<a href=\""+tmp+"\" class=\"commit\"><code>d8a994ef24 (diff-2)</code></a>") test(tmp, "<a href=\""+tmp+"\" class=\"commit\"><code>d8a994ef24 (diff-2)</code></a>")

View File

@ -34,15 +34,15 @@ func TestRender_Commits(t *testing.T) {
sha := "65f1bf27bc3bf70f64657658635e66094edbcb4d" sha := "65f1bf27bc3bf70f64657658635e66094edbcb4d"
repo := markup.TestAppURL + testRepoOwnerName + "/" + testRepoName + "/" repo := markup.TestAppURL + testRepoOwnerName + "/" + testRepoName + "/"
commit := util.URLJoin(repo, "commit", sha) commit := repo + "commit/" + sha
commitPath := "/user13/repo11/commit/" + sha commitPath := "/user13/repo11/commit/" + sha
tree := util.URLJoin(repo, "tree", sha, "src") tree := repo + "tree/" + sha + "/src"
file := util.URLJoin(repo, "commit", sha, "example.txt") file := repo + "commit/" + sha + "/example.txt"
fileWithExtra := file + ":" fileWithExtra := file + ":"
fileWithHash := file + "#L2" fileWithHash := file + "#L2"
fileWithHasExtra := file + "#L2:" fileWithHasExtra := file + "#L2:"
commitCompare := util.URLJoin(repo, "compare", sha+"..."+sha) commitCompare := repo + "compare/" + sha + "..." + sha
commitCompareWithHash := commitCompare + "#L2" commitCompareWithHash := commitCompare + "#L2"
test(sha, `<p><a href="`+commitPath+`" rel="nofollow"><code>65f1bf27bc</code></a></p>`) test(sha, `<p><a href="`+commitPath+`" rel="nofollow"><code>65f1bf27bc</code></a></p>`)
@ -90,14 +90,14 @@ func TestRender_CrossReferences(t *testing.T) {
"/home/gitea/go-gitea/gitea#12345", "/home/gitea/go-gitea/gitea#12345",
`<p>/home/gitea/go-gitea/gitea#12345</p>`) `<p>/home/gitea/go-gitea/gitea#12345</p>`)
test( test(
util.URLJoin(markup.TestAppURL, "gogitea", "gitea", "issues", "12345"), markup.TestAppURL+"gogitea/gitea/issues/12345",
`<p><a href="`+util.URLJoin(markup.TestAppURL, "gogitea", "gitea", "issues", "12345")+`" class="ref-issue" rel="nofollow">gogitea/gitea#12345</a></p>`) `<p><a href="`+markup.TestAppURL+`gogitea/gitea/issues/12345" class="ref-issue" rel="nofollow">gogitea/gitea#12345</a></p>`)
test( test(
util.URLJoin(markup.TestAppURL, "go-gitea", "gitea", "issues", "12345"), markup.TestAppURL+"go-gitea/gitea/issues/12345",
`<p><a href="`+util.URLJoin(markup.TestAppURL, "go-gitea", "gitea", "issues", "12345")+`" class="ref-issue" rel="nofollow">go-gitea/gitea#12345</a></p>`) `<p><a href="`+markup.TestAppURL+`go-gitea/gitea/issues/12345" class="ref-issue" rel="nofollow">go-gitea/gitea#12345</a></p>`)
test( test(
util.URLJoin(markup.TestAppURL, "gogitea", "some-repo-name", "issues", "12345"), markup.TestAppURL+"gogitea/some-repo-name/issues/12345",
`<p><a href="`+util.URLJoin(markup.TestAppURL, "gogitea", "some-repo-name", "issues", "12345")+`" class="ref-issue" rel="nofollow">gogitea/some-repo-name#12345</a></p>`) `<p><a href="`+markup.TestAppURL+`gogitea/some-repo-name/issues/12345" class="ref-issue" rel="nofollow">gogitea/some-repo-name#12345</a></p>`)
inputURL := setting.AppURL + "a/b/commit/0123456789012345678901234567890123456789/foo.txt?a=b#L2-L3" inputURL := setting.AppURL + "a/b/commit/0123456789012345678901234567890123456789/foo.txt?a=b#L2-L3"
test( test(
@ -375,7 +375,7 @@ func TestRender_emoji(t *testing.T) {
func TestRender_ShortLinks(t *testing.T) { func TestRender_ShortLinks(t *testing.T) {
setting.AppURL = markup.TestAppURL setting.AppURL = markup.TestAppURL
tree := util.URLJoin(markup.TestRepoURL, "src", "master") tree := markup.TestRepoURL + "src/master"
test := func(input, expected string) { test := func(input, expected string) {
buffer, err := markdown.RenderString(markup.NewTestRenderContext(tree), input) buffer, err := markdown.RenderString(markup.NewTestRenderContext(tree), input)
@ -383,15 +383,15 @@ func TestRender_ShortLinks(t *testing.T) {
assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(string(buffer))) assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(string(buffer)))
} }
url := util.URLJoin(tree, "Link") url := tree + "/Link"
otherURL := util.URLJoin(tree, "Other-Link") otherURL := tree + "/Other-Link"
encodedURL := util.URLJoin(tree, "Link%3F") encodedURL := tree + "/Link%3F"
imgurl := util.URLJoin(tree, "Link.jpg") imgurl := tree + "/Link.jpg"
otherImgurl := util.URLJoin(tree, "Link+Other.jpg") otherImgurl := tree + "/Link+Other.jpg"
encodedImgurl := util.URLJoin(tree, "Link+%23.jpg") encodedImgurl := tree + "/Link+%23.jpg"
notencodedImgurl := util.URLJoin(tree, "some", "path", "Link%20#.jpg") notencodedImgurl := tree + "/some/path/Link%20#.jpg"
renderableFileURL := util.URLJoin(tree, "markdown_file.md") renderableFileURL := tree + "/markdown_file.md"
unrenderableFileURL := util.URLJoin(tree, "file.zip") unrenderableFileURL := tree + "/file.zip"
favicon := "http://google.com/favicon.ico" favicon := "http://google.com/favicon.ico"
test( test(

View File

@ -5,7 +5,6 @@ package util
import ( import (
"net/url" "net/url"
"path"
"strings" "strings"
) )
@ -19,29 +18,6 @@ func PathEscapeSegments(path string) string {
return escapedPath return escapedPath
} }
// URLJoin joins url components, like path.Join, but preserving contents
// Deprecated: it has unclear behaviors, should not be used anymore. It is only used in some tests.
// Need to be removed in the future.
func URLJoin(base string, elems ...string) string {
if !strings.HasSuffix(base, "/") {
base += "/"
}
baseURL, err := url.Parse(base)
if err != nil {
return ""
}
joinedPath := path.Join(elems...)
argURL, err := url.Parse(joinedPath)
if err != nil {
return ""
}
joinedURL := baseURL.ResolveReference(argURL).String()
if !baseURL.IsAbs() && !strings.HasPrefix(base, "/") {
return joinedURL[1:] // Removing leading '/' if needed
}
return joinedURL
}
func SanitizeURL(s string) (string, error) { func SanitizeURL(s string) (string, error) {
u, err := url.Parse(s) u, err := url.Parse(s)
if err != nil { if err != nil {

View File

@ -11,39 +11,6 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
func TestURLJoin(t *testing.T) {
type test struct {
Expected string
Base string
Elements []string
}
newTest := func(expected, base string, elements ...string) test {
return test{Expected: expected, Base: base, Elements: elements}
}
for _, test := range []test{
newTest("https://try.gitea.io/a/b/c",
"https://try.gitea.io", "a/b", "c"),
newTest("https://try.gitea.io/a/b/c",
"https://try.gitea.io/", "/a/b/", "/c/"),
newTest("https://try.gitea.io/a/c",
"https://try.gitea.io/", "/a/./b/", "../c/"),
newTest("a/b/c",
"a", "b/c/"),
newTest("a/b/d",
"a/", "b/c/", "/../d/"),
newTest("https://try.gitea.io/a/b/c#d",
"https://try.gitea.io", "a/b", "c#d"),
newTest("/a/b/d",
"/a/", "b/c/", "/../d/"),
newTest("/a/b/c",
"/a", "b/c/"),
newTest("/a/b/c#hash",
"/a", "b/c#hash"),
} {
assert.Equal(t, test.Expected, URLJoin(test.Base, test.Elements...))
}
}
func TestIsEmptyString(t *testing.T) { func TestIsEmptyString(t *testing.T) {
cases := []struct { cases := []struct {
s string s string

File diff suppressed because it is too large Load Diff

View File

@ -11,7 +11,6 @@ import (
"code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/models/unittest"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
api "code.gitea.io/gitea/modules/structs" api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/util"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@ -35,7 +34,7 @@ func TestToCommitMeta(t *testing.T) {
assert.NotNil(t, commitMeta) assert.NotNil(t, commitMeta)
assert.Equal(t, &api.CommitMeta{ assert.Equal(t, &api.CommitMeta{
SHA: sha1.EmptyObjectID().String(), SHA: sha1.EmptyObjectID().String(),
URL: util.URLJoin(headRepo.APIURL(), "git/commits", sha1.EmptyObjectID().String()), URL: headRepo.APIURL() + "/git/commits/" + sha1.EmptyObjectID().String(),
Created: time.Unix(0, 0), Created: time.Unix(0, 0),
}, commitMeta) }, commitMeta)
} }

View File

@ -20,7 +20,6 @@ import (
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
rpm_module "code.gitea.io/gitea/modules/packages/rpm" rpm_module "code.gitea.io/gitea/modules/packages/rpm"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util"
"code.gitea.io/gitea/tests" "code.gitea.io/gitea/tests"
"github.com/ProtonMail/go-crypto/openpgp" "github.com/ProtonMail/go-crypto/openpgp"
@ -99,7 +98,7 @@ gpgcheck=1
gpgkey=%sapi/packages/%s/rpm/repository.key`, gpgkey=%sapi/packages/%s/rpm/repository.key`,
strings.Join(append([]string{user.LowerName}, groupParts...), "-"), strings.Join(append([]string{user.LowerName}, groupParts...), "-"),
strings.Join(append([]string{user.Name, setting.AppName}, groupParts...), " - "), strings.Join(append([]string{user.Name, setting.AppName}, groupParts...), " - "),
util.URLJoin(setting.AppURL, groupURL), strings.TrimSuffix(setting.AppURL, "/")+groupURL,
setting.AppURL, setting.AppURL,
user.Name, user.Name,
) )

View File

@ -14,7 +14,6 @@ import (
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/gitrepo" "code.gitea.io/gitea/modules/gitrepo"
api "code.gitea.io/gitea/modules/structs" api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/util"
"code.gitea.io/gitea/tests" "code.gitea.io/gitea/tests"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
@ -58,7 +57,7 @@ func TestAPIGitTags(t *testing.T) {
assert.Equal(t, aTagMessage+"\n", tag.Message) assert.Equal(t, aTagMessage+"\n", tag.Message)
assert.Equal(t, user.Name, tag.Tagger.Name) assert.Equal(t, user.Name, tag.Tagger.Name)
assert.Equal(t, user.Email, tag.Tagger.Email) assert.Equal(t, user.Email, tag.Tagger.Email)
assert.Equal(t, util.URLJoin(repo.APIURL(), "git/tags", aTag.ID.String()), tag.URL) assert.Equal(t, repo.APIURL()+"/git/tags/"+aTag.ID.String(), tag.URL)
// Should NOT work for lightweight tags // Should NOT work for lightweight tags
badReq := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/git/tags/%s", user.Name, repo.Name, commit.ID.String()). badReq := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/git/tags/%s", user.Name, repo.Name, commit.ID.String()).

View File

@ -9,13 +9,13 @@ const viewedCheckboxSelector = '.viewed-file-form'; // Selector under which all
const expandFilesBtnSelector = '#expand-files-btn'; const expandFilesBtnSelector = '#expand-files-btn';
const collapseFilesBtnSelector = '#collapse-files-btn'; const collapseFilesBtnSelector = '#collapse-files-btn';
// Refreshes the summary of viewed files if present // Refreshes the summary of viewed files
// The data used will be window.config.pageData.prReview.numberOf{Viewed}Files // The data used will be window.config.pageData.prReview.numberOf{Viewed}Files
function refreshViewedFilesSummary() { function refreshViewedFilesSummary() {
const viewedFilesProgress = document.querySelector('#viewed-files-summary'); const viewedFilesProgress = document.querySelector('#viewed-files-summary')!;
viewedFilesProgress?.setAttribute('value', prReview.numberOfViewedFiles); viewedFilesProgress.setAttribute('value', prReview.numberOfViewedFiles);
const summaryLabel = document.querySelector('#viewed-files-summary-label')!; const summaryLabel = document.querySelector<HTMLElement>('#viewed-files-summary-label')!;
if (summaryLabel) summaryLabel.innerHTML = summaryLabel.getAttribute('data-text-changed-template')! summaryLabel.textContent = summaryLabel.getAttribute('data-text-changed-template')!
.replace('%[1]d', prReview.numberOfViewedFiles) .replace('%[1]d', prReview.numberOfViewedFiles)
.replace('%[2]d', prReview.numberOfFiles); .replace('%[2]d', prReview.numberOfFiles);
} }