* Populate URL field of API commits * fix orgmode_testtags/v1.5.0-dev
@@ -15,8 +15,8 @@ import ( | |||||
"strings" | "strings" | ||||
"code.gitea.io/gitea/modules/base" | "code.gitea.io/gitea/modules/base" | ||||
"code.gitea.io/gitea/modules/log" | |||||
"code.gitea.io/gitea/modules/setting" | "code.gitea.io/gitea/modules/setting" | ||||
"code.gitea.io/gitea/modules/util" | |||||
"github.com/Unknwon/com" | "github.com/Unknwon/com" | ||||
"golang.org/x/net/html" | "golang.org/x/net/html" | ||||
@@ -112,20 +112,6 @@ func cutoutVerbosePrefix(prefix string) string { | |||||
return prefix | return prefix | ||||
} | } | ||||
// URLJoin joins url components, like path.Join, but preserving contents | |||||
func URLJoin(base string, elems ...string) string { | |||||
u, err := url.Parse(base) | |||||
if err != nil { | |||||
log.Error(4, "URLJoin: Invalid base URL %s", base) | |||||
return "" | |||||
} | |||||
joinArgs := make([]string, 0, len(elems)+1) | |||||
joinArgs = append(joinArgs, u.Path) | |||||
joinArgs = append(joinArgs, elems...) | |||||
u.Path = path.Join(joinArgs...) | |||||
return u.String() | |||||
} | |||||
// RenderIssueIndexPatternOptions options for RenderIssueIndexPattern function | // RenderIssueIndexPatternOptions options for RenderIssueIndexPattern function | ||||
type RenderIssueIndexPatternOptions struct { | type RenderIssueIndexPatternOptions struct { | ||||
// url to which non-special formatting should be linked. If empty, | // url to which non-special formatting should be linked. If empty, | ||||
@@ -177,7 +163,7 @@ func RenderIssueIndexPattern(rawBytes []byte, opts RenderIssueIndexPatternOption | |||||
} | } | ||||
if opts.Metas == nil { | if opts.Metas == nil { | ||||
buf.WriteString(`<a href="`) | buf.WriteString(`<a href="`) | ||||
buf.WriteString(URLJoin( | |||||
buf.WriteString(util.URLJoin( | |||||
opts.URLPrefix, "issues", string(remainder[startIndex+1:endIndex]))) | opts.URLPrefix, "issues", string(remainder[startIndex+1:endIndex]))) | ||||
buf.WriteString(`">`) | buf.WriteString(`">`) | ||||
buf.Write(remainder[startIndex:endIndex]) | buf.Write(remainder[startIndex:endIndex]) | ||||
@@ -228,7 +214,7 @@ func renderFullSha1Pattern(rawBytes []byte, urlPrefix string) []byte { | |||||
path := protocol + "://" + paths | path := protocol + "://" + paths | ||||
author := string(m[3]) | author := string(m[3]) | ||||
repoName := string(m[4]) | repoName := string(m[4]) | ||||
path = URLJoin(path, author, repoName) | |||||
path = util.URLJoin(path, author, repoName) | |||||
ltype := "src" | ltype := "src" | ||||
itemType := m[5] | itemType := m[5] | ||||
if IsSameDomain(paths) { | if IsSameDomain(paths) { | ||||
@@ -260,7 +246,7 @@ func renderFullSha1Pattern(rawBytes []byte, urlPrefix string) []byte { | |||||
text += ")" | text += ")" | ||||
} | } | ||||
rawBytes = bytes.Replace(rawBytes, all, []byte(fmt.Sprintf( | rawBytes = bytes.Replace(rawBytes, all, []byte(fmt.Sprintf( | ||||
`<a href="%s">%s</a>`, URLJoin(path, ltype, string(sha))+urlSuffix, text)), -1) | |||||
`<a href="%s">%s</a>`, util.URLJoin(path, ltype, string(sha))+urlSuffix, text)), -1) | |||||
} | } | ||||
return rawBytes | return rawBytes | ||||
} | } | ||||
@@ -399,9 +385,9 @@ func RenderShortLinks(rawBytes []byte, urlPrefix string, noLink bool, isWikiMark | |||||
urlPrefix = strings.Replace(urlPrefix, "/src/", "/raw/", 1) | urlPrefix = strings.Replace(urlPrefix, "/src/", "/raw/", 1) | ||||
} | } | ||||
if isWikiMarkdown { | if isWikiMarkdown { | ||||
link = URLJoin("wiki", "raw", link) | |||||
link = util.URLJoin("wiki", "raw", link) | |||||
} | } | ||||
link = URLJoin(urlPrefix, link) | |||||
link = util.URLJoin(urlPrefix, link) | |||||
} | } | ||||
title := props["title"] | title := props["title"] | ||||
if title == "" { | if title == "" { | ||||
@@ -420,9 +406,9 @@ func RenderShortLinks(rawBytes []byte, urlPrefix string, noLink bool, isWikiMark | |||||
name = fmt.Sprintf(`<img src="%s" %s title="%s" />`, link, alt, title) | name = fmt.Sprintf(`<img src="%s" %s title="%s" />`, link, alt, title) | ||||
} else if !absoluteLink { | } else if !absoluteLink { | ||||
if isWikiMarkdown { | if isWikiMarkdown { | ||||
link = URLJoin("wiki", link) | |||||
link = util.URLJoin("wiki", link) | |||||
} | } | ||||
link = URLJoin(urlPrefix, link) | |||||
link = util.URLJoin(urlPrefix, link) | |||||
} | } | ||||
if noLink { | if noLink { | ||||
rawBytes = bytes.Replace(rawBytes, orig, []byte(name), -1) | rawBytes = bytes.Replace(rawBytes, orig, []byte(name), -1) | ||||
@@ -445,7 +431,7 @@ func RenderCrossReferenceIssueIndexPattern(rawBytes []byte, urlPrefix string, me | |||||
repo := string(bytes.Split(m, []byte("#"))[0]) | repo := string(bytes.Split(m, []byte("#"))[0]) | ||||
issue := string(bytes.Split(m, []byte("#"))[1]) | issue := string(bytes.Split(m, []byte("#"))[1]) | ||||
link := fmt.Sprintf(`<a href="%s">%s</a>`, URLJoin(setting.AppURL, repo, "issues", issue), m) | |||||
link := fmt.Sprintf(`<a href="%s">%s</a>`, util.URLJoin(setting.AppURL, repo, "issues", issue), m) | |||||
rawBytes = bytes.Replace(rawBytes, m, []byte(link), 1) | rawBytes = bytes.Replace(rawBytes, m, []byte(link), 1) | ||||
} | } | ||||
return rawBytes | return rawBytes | ||||
@@ -463,7 +449,7 @@ func renderSha1CurrentPattern(rawBytes []byte, urlPrefix string) []byte { | |||||
// Although unlikely, deadbeef and 1234567 are valid short forms of SHA1 hash | // Although unlikely, deadbeef and 1234567 are valid short forms of SHA1 hash | ||||
// as used by git and github for linking and thus we have to do similar. | // as used by git and github for linking and thus we have to do similar. | ||||
rawBytes = bytes.Replace(rawBytes, hash, []byte(fmt.Sprintf( | rawBytes = bytes.Replace(rawBytes, hash, []byte(fmt.Sprintf( | ||||
`<a href="%s">%s</a>`, URLJoin(urlPrefix, "commit", string(hash)), base.ShortSha(string(hash)))), -1) | |||||
`<a href="%s">%s</a>`, util.URLJoin(urlPrefix, "commit", string(hash)), base.ShortSha(string(hash)))), -1) | |||||
} | } | ||||
return rawBytes | return rawBytes | ||||
} | } | ||||
@@ -474,7 +460,7 @@ func RenderSpecialLink(rawBytes []byte, urlPrefix string, metas map[string]strin | |||||
for _, m := range ms { | for _, m := range ms { | ||||
m = m[bytes.Index(m, []byte("@")):] | m = m[bytes.Index(m, []byte("@")):] | ||||
rawBytes = bytes.Replace(rawBytes, m, | rawBytes = bytes.Replace(rawBytes, m, | ||||
[]byte(fmt.Sprintf(`<a href="%s">%s</a>`, URLJoin(setting.AppURL, string(m[1:])), m)), -1) | |||||
[]byte(fmt.Sprintf(`<a href="%s">%s</a>`, util.URLJoin(setting.AppURL, string(m[1:])), m)), -1) | |||||
} | } | ||||
rawBytes = RenderFullIssuePattern(rawBytes) | rawBytes = RenderFullIssuePattern(rawBytes) | ||||
@@ -13,6 +13,7 @@ import ( | |||||
. "code.gitea.io/gitea/modules/markup" | . "code.gitea.io/gitea/modules/markup" | ||||
_ "code.gitea.io/gitea/modules/markup/markdown" | _ "code.gitea.io/gitea/modules/markup/markdown" | ||||
"code.gitea.io/gitea/modules/setting" | "code.gitea.io/gitea/modules/setting" | ||||
"code.gitea.io/gitea/modules/util" | |||||
"github.com/stretchr/testify/assert" | "github.com/stretchr/testify/assert" | ||||
) | ) | ||||
@@ -37,12 +38,12 @@ var alphanumericMetas = map[string]string{ | |||||
// numericLink an HTML to a numeric-style issue | // numericLink an HTML to a numeric-style issue | ||||
func numericIssueLink(baseURL string, index int) string { | func numericIssueLink(baseURL string, index int) string { | ||||
return link(URLJoin(baseURL, strconv.Itoa(index)), fmt.Sprintf("#%d", index)) | |||||
return link(util.URLJoin(baseURL, strconv.Itoa(index)), fmt.Sprintf("#%d", index)) | |||||
} | } | ||||
// alphanumLink an HTML link to an alphanumeric-style issue | // alphanumLink an HTML link to an alphanumeric-style issue | ||||
func alphanumIssueLink(baseURL string, name string) string { | func alphanumIssueLink(baseURL string, name string) string { | ||||
return link(URLJoin(baseURL, name), name) | |||||
return link(util.URLJoin(baseURL, name), name) | |||||
} | } | ||||
// urlContentsLink an HTML link whose contents is the target URL | // urlContentsLink an HTML link whose contents is the target URL | ||||
@@ -63,31 +64,6 @@ func testRenderIssueIndexPattern(t *testing.T, input, expected string, opts Rend | |||||
assert.Equal(t, expected, actual) | assert.Equal(t, expected, actual) | ||||
} | } | ||||
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/"), | |||||
} { | |||||
assert.Equal(t, test.Expected, URLJoin(test.Base, test.Elements...)) | |||||
} | |||||
} | |||||
func TestRender_IssueIndexPattern(t *testing.T) { | func TestRender_IssueIndexPattern(t *testing.T) { | ||||
// numeric: render inputs without valid mentions | // numeric: render inputs without valid mentions | ||||
test := func(s string) { | test := func(s string) { | ||||
@@ -123,7 +99,7 @@ func TestRender_IssueIndexPattern2(t *testing.T) { | |||||
test := func(s, expectedFmt string, indices ...int) { | test := func(s, expectedFmt string, indices ...int) { | ||||
links := make([]interface{}, len(indices)) | links := make([]interface{}, len(indices)) | ||||
for i, index := range indices { | for i, index := range indices { | ||||
links[i] = numericIssueLink(URLJoin(setting.AppSubURL, "issues"), index) | |||||
links[i] = numericIssueLink(util.URLJoin(setting.AppSubURL, "issues"), index) | |||||
} | } | ||||
expectedNil := fmt.Sprintf(expectedFmt, links...) | expectedNil := fmt.Sprintf(expectedFmt, links...) | ||||
testRenderIssueIndexPattern(t, s, expectedNil, RenderIssueIndexPatternOptions{}) | testRenderIssueIndexPattern(t, s, expectedNil, RenderIssueIndexPatternOptions{}) | ||||
@@ -228,8 +204,8 @@ func TestRender_AutoLink(t *testing.T) { | |||||
} | } | ||||
// render valid issue URLs | // render valid issue URLs | ||||
test(URLJoin(setting.AppSubURL, "issues", "3333"), | |||||
numericIssueLink(URLJoin(setting.AppSubURL, "issues"), 3333)) | |||||
test(util.URLJoin(setting.AppSubURL, "issues", "3333"), | |||||
numericIssueLink(util.URLJoin(setting.AppSubURL, "issues"), 3333)) | |||||
// render external issue URLs | // render external issue URLs | ||||
for _, externalURL := range []string{ | for _, externalURL := range []string{ | ||||
@@ -240,7 +216,7 @@ func TestRender_AutoLink(t *testing.T) { | |||||
} | } | ||||
// render valid commit URLs | // render valid commit URLs | ||||
tmp := URLJoin(AppSubURL, "commit", "d8a994ef243349f321568f9e36d5c3f444b99cae") | |||||
tmp := util.URLJoin(AppSubURL, "commit", "d8a994ef243349f321568f9e36d5c3f444b99cae") | |||||
test(tmp, "<a href=\""+tmp+"\">d8a994ef24</a>") | test(tmp, "<a href=\""+tmp+"\">d8a994ef24</a>") | ||||
tmp += "#diff-2" | tmp += "#diff-2" | ||||
test(tmp, "<a href=\""+tmp+"\">d8a994ef24 (diff-2)</a>") | test(tmp, "<a href=\""+tmp+"\">d8a994ef24 (diff-2)</a>") | ||||
@@ -260,8 +236,8 @@ func TestRender_Commits(t *testing.T) { | |||||
} | } | ||||
var sha = "b6dd6210eaebc915fd5be5579c58cce4da2e2579" | var sha = "b6dd6210eaebc915fd5be5579c58cce4da2e2579" | ||||
var commit = URLJoin(AppSubURL, "commit", sha) | |||||
var subtree = URLJoin(commit, "src") | |||||
var commit = util.URLJoin(AppSubURL, "commit", sha) | |||||
var subtree = util.URLJoin(commit, "src") | |||||
var tree = strings.Replace(subtree, "/commit/", "/tree/", -1) | var tree = strings.Replace(subtree, "/commit/", "/tree/", -1) | ||||
var src = strings.Replace(subtree, "/commit/", "/src/", -1) | var src = strings.Replace(subtree, "/commit/", "/src/", -1) | ||||
@@ -284,10 +260,10 @@ func TestRender_CrossReferences(t *testing.T) { | |||||
test( | test( | ||||
"gogits/gogs#12345", | "gogits/gogs#12345", | ||||
`<p><a href="`+URLJoin(AppURL, "gogits", "gogs", "issues", "12345")+`" rel="nofollow">gogits/gogs#12345</a></p>`) | |||||
`<p><a href="`+util.URLJoin(AppURL, "gogits", "gogs", "issues", "12345")+`" rel="nofollow">gogits/gogs#12345</a></p>`) | |||||
test( | test( | ||||
"go-gitea/gitea#12345", | "go-gitea/gitea#12345", | ||||
`<p><a href="`+URLJoin(AppURL, "go-gitea", "gitea", "issues", "12345")+`" rel="nofollow">go-gitea/gitea#12345</a></p>`) | |||||
`<p><a href="`+util.URLJoin(AppURL, "go-gitea", "gitea", "issues", "12345")+`" rel="nofollow">go-gitea/gitea#12345</a></p>`) | |||||
} | } | ||||
func TestRender_FullIssueURLs(t *testing.T) { | func TestRender_FullIssueURLs(t *testing.T) { | ||||
@@ -482,7 +458,7 @@ func TestMisc_IsSameDomain(t *testing.T) { | |||||
setting.AppSubURL = AppSubURL | setting.AppSubURL = AppSubURL | ||||
var sha = "b6dd6210eaebc915fd5be5579c58cce4da2e2579" | var sha = "b6dd6210eaebc915fd5be5579c58cce4da2e2579" | ||||
var commit = URLJoin(AppSubURL, "commit", sha) | |||||
var commit = util.URLJoin(AppSubURL, "commit", sha) | |||||
assert.True(t, IsSameDomain(commit)) | assert.True(t, IsSameDomain(commit)) | ||||
assert.False(t, IsSameDomain("http://google.com/ncr")) | assert.False(t, IsSameDomain("http://google.com/ncr")) | ||||
@@ -10,6 +10,7 @@ import ( | |||||
"code.gitea.io/gitea/modules/markup" | "code.gitea.io/gitea/modules/markup" | ||||
"code.gitea.io/gitea/modules/setting" | "code.gitea.io/gitea/modules/setting" | ||||
"code.gitea.io/gitea/modules/util" | |||||
"github.com/russross/blackfriday" | "github.com/russross/blackfriday" | ||||
) | ) | ||||
@@ -27,9 +28,9 @@ func (r *Renderer) Link(out *bytes.Buffer, link []byte, title []byte, content [] | |||||
if link[0] != '#' { | if link[0] != '#' { | ||||
lnk := string(link) | lnk := string(link) | ||||
if r.IsWiki { | if r.IsWiki { | ||||
lnk = markup.URLJoin("wiki", lnk) | |||||
lnk = util.URLJoin("wiki", lnk) | |||||
} | } | ||||
mLink := markup.URLJoin(r.URLPrefix, lnk) | |||||
mLink := util.URLJoin(r.URLPrefix, lnk) | |||||
link = []byte(mLink) | link = []byte(mLink) | ||||
} | } | ||||
} | } | ||||
@@ -97,7 +98,7 @@ var ( | |||||
func (r *Renderer) Image(out *bytes.Buffer, link []byte, title []byte, alt []byte) { | func (r *Renderer) Image(out *bytes.Buffer, link []byte, title []byte, alt []byte) { | ||||
prefix := r.URLPrefix | prefix := r.URLPrefix | ||||
if r.IsWiki { | if r.IsWiki { | ||||
prefix = markup.URLJoin(prefix, "wiki", "src") | |||||
prefix = util.URLJoin(prefix, "wiki", "src") | |||||
} | } | ||||
prefix = strings.Replace(prefix, "/src/", "/raw/", 1) | prefix = strings.Replace(prefix, "/src/", "/raw/", 1) | ||||
if len(link) > 0 { | if len(link) > 0 { | ||||
@@ -110,7 +111,7 @@ func (r *Renderer) Image(out *bytes.Buffer, link []byte, title []byte, alt []byt | |||||
} | } | ||||
} else { | } else { | ||||
lnk := string(link) | lnk := string(link) | ||||
lnk = markup.URLJoin(prefix, lnk) | |||||
lnk = util.URLJoin(prefix, lnk) | |||||
lnk = strings.Replace(lnk, " ", "+", -1) | lnk = strings.Replace(lnk, " ", "+", -1) | ||||
link = []byte(lnk) | link = []byte(lnk) | ||||
} | } | ||||
@@ -11,6 +11,7 @@ import ( | |||||
"code.gitea.io/gitea/modules/markup" | "code.gitea.io/gitea/modules/markup" | ||||
. "code.gitea.io/gitea/modules/markup/markdown" | . "code.gitea.io/gitea/modules/markup/markdown" | ||||
"code.gitea.io/gitea/modules/setting" | "code.gitea.io/gitea/modules/setting" | ||||
"code.gitea.io/gitea/modules/util" | |||||
"github.com/stretchr/testify/assert" | "github.com/stretchr/testify/assert" | ||||
) | ) | ||||
@@ -33,8 +34,8 @@ func TestRender_StandardLinks(t *testing.T) { | |||||
googleRendered := `<p><a href="https://google.com/" rel="nofollow">https://google.com/</a></p>` | googleRendered := `<p><a href="https://google.com/" rel="nofollow">https://google.com/</a></p>` | ||||
test("<https://google.com/>", googleRendered, googleRendered) | test("<https://google.com/>", googleRendered, googleRendered) | ||||
lnk := markup.URLJoin(AppSubURL, "WikiPage") | |||||
lnkWiki := markup.URLJoin(AppSubURL, "wiki", "WikiPage") | |||||
lnk := util.URLJoin(AppSubURL, "WikiPage") | |||||
lnkWiki := util.URLJoin(AppSubURL, "wiki", "WikiPage") | |||||
test("[WikiPage](WikiPage)", | test("[WikiPage](WikiPage)", | ||||
`<p><a href="`+lnk+`" rel="nofollow">WikiPage</a></p>`, | `<p><a href="`+lnk+`" rel="nofollow">WikiPage</a></p>`, | ||||
`<p><a href="`+lnkWiki+`" rel="nofollow">WikiPage</a></p>`) | `<p><a href="`+lnkWiki+`" rel="nofollow">WikiPage</a></p>`) | ||||
@@ -43,7 +44,7 @@ func TestRender_StandardLinks(t *testing.T) { | |||||
func TestRender_ShortLinks(t *testing.T) { | func TestRender_ShortLinks(t *testing.T) { | ||||
setting.AppURL = AppURL | setting.AppURL = AppURL | ||||
setting.AppSubURL = AppSubURL | setting.AppSubURL = AppSubURL | ||||
tree := markup.URLJoin(AppSubURL, "src", "master") | |||||
tree := util.URLJoin(AppSubURL, "src", "master") | |||||
test := func(input, expected, expectedWiki string) { | test := func(input, expected, expectedWiki string) { | ||||
buffer := RenderString(input, tree, nil) | buffer := RenderString(input, tree, nil) | ||||
@@ -52,13 +53,13 @@ func TestRender_ShortLinks(t *testing.T) { | |||||
assert.Equal(t, strings.TrimSpace(expectedWiki), strings.TrimSpace(string(buffer))) | assert.Equal(t, strings.TrimSpace(expectedWiki), strings.TrimSpace(string(buffer))) | ||||
} | } | ||||
rawtree := markup.URLJoin(AppSubURL, "raw", "master") | |||||
url := markup.URLJoin(tree, "Link") | |||||
otherUrl := markup.URLJoin(tree, "OtherLink") | |||||
imgurl := markup.URLJoin(rawtree, "Link.jpg") | |||||
urlWiki := markup.URLJoin(AppSubURL, "wiki", "Link") | |||||
otherUrlWiki := markup.URLJoin(AppSubURL, "wiki", "OtherLink") | |||||
imgurlWiki := markup.URLJoin(AppSubURL, "wiki", "raw", "Link.jpg") | |||||
rawtree := util.URLJoin(AppSubURL, "raw", "master") | |||||
url := util.URLJoin(tree, "Link") | |||||
otherUrl := util.URLJoin(tree, "OtherLink") | |||||
imgurl := util.URLJoin(rawtree, "Link.jpg") | |||||
urlWiki := util.URLJoin(AppSubURL, "wiki", "Link") | |||||
otherUrlWiki := util.URLJoin(AppSubURL, "wiki", "OtherLink") | |||||
imgurlWiki := util.URLJoin(AppSubURL, "wiki", "raw", "Link.jpg") | |||||
favicon := "http://google.com/favicon.ico" | favicon := "http://google.com/favicon.ico" | ||||
test( | test( | ||||
@@ -136,7 +137,7 @@ func TestRender_Images(t *testing.T) { | |||||
url := "../../.images/src/02/train.jpg" | url := "../../.images/src/02/train.jpg" | ||||
title := "Train" | title := "Train" | ||||
result := markup.URLJoin(AppSubURL, url) | |||||
result := util.URLJoin(AppSubURL, url) | |||||
test( | test( | ||||
"", | "", | ||||
@@ -259,7 +260,7 @@ Here are some links to the most important topics. You can find the full list of | |||||
} | } | ||||
func TestTotal_RenderWiki(t *testing.T) { | func TestTotal_RenderWiki(t *testing.T) { | ||||
answers := testAnswers(markup.URLJoin(AppSubURL, "wiki/"), markup.URLJoin(AppSubURL, "wiki", "raw/")) | |||||
answers := testAnswers(util.URLJoin(AppSubURL, "wiki/"), util.URLJoin(AppSubURL, "wiki", "raw/")) | |||||
for i := 0; i < len(sameCases); i++ { | for i := 0; i < len(sameCases); i++ { | ||||
line := RenderWiki([]byte(sameCases[i]), AppSubURL, nil) | line := RenderWiki([]byte(sameCases[i]), AppSubURL, nil) | ||||
@@ -286,10 +287,10 @@ func TestTotal_RenderWiki(t *testing.T) { | |||||
} | } | ||||
func TestTotal_RenderString(t *testing.T) { | func TestTotal_RenderString(t *testing.T) { | ||||
answers := testAnswers(markup.URLJoin(AppSubURL, "src", "master/"), markup.URLJoin(AppSubURL, "raw", "master/")) | |||||
answers := testAnswers(util.URLJoin(AppSubURL, "src", "master/"), util.URLJoin(AppSubURL, "raw", "master/")) | |||||
for i := 0; i < len(sameCases); i++ { | for i := 0; i < len(sameCases); i++ { | ||||
line := RenderString(sameCases[i], markup.URLJoin(AppSubURL, "src", "master/"), nil) | |||||
line := RenderString(sameCases[i], util.URLJoin(AppSubURL, "src", "master/"), nil) | |||||
assert.Equal(t, answers[i], line) | assert.Equal(t, answers[i], line) | ||||
} | } | ||||
@@ -8,8 +8,8 @@ import ( | |||||
"strings" | "strings" | ||||
"testing" | "testing" | ||||
"code.gitea.io/gitea/modules/markup" | |||||
"code.gitea.io/gitea/modules/setting" | "code.gitea.io/gitea/modules/setting" | ||||
"code.gitea.io/gitea/modules/util" | |||||
"github.com/stretchr/testify/assert" | "github.com/stretchr/testify/assert" | ||||
) | ) | ||||
@@ -30,7 +30,7 @@ func TestRender_StandardLinks(t *testing.T) { | |||||
googleRendered := `<p><a href="https://google.com/" title="https://google.com/">https://google.com/</a></p>` | googleRendered := `<p><a href="https://google.com/" title="https://google.com/">https://google.com/</a></p>` | ||||
test("[[https://google.com/]]", googleRendered) | test("[[https://google.com/]]", googleRendered) | ||||
lnk := markup.URLJoin(AppSubURL, "WikiPage") | |||||
lnk := util.URLJoin(AppSubURL, "WikiPage") | |||||
test("[[WikiPage][WikiPage]]", | test("[[WikiPage][WikiPage]]", | ||||
`<p><a href="`+lnk+`" title="WikiPage">WikiPage</a></p>`) | `<p><a href="`+lnk+`" title="WikiPage">WikiPage</a></p>`) | ||||
} | } | ||||
@@ -46,7 +46,7 @@ func TestRender_Images(t *testing.T) { | |||||
url := "../../.images/src/02/train.jpg" | url := "../../.images/src/02/train.jpg" | ||||
title := "Train" | title := "Train" | ||||
result := markup.URLJoin(AppSubURL, url) | |||||
result := util.URLJoin(AppSubURL, url) | |||||
test( | test( | ||||
"[[file:"+url+"]["+title+"]]", | "[[file:"+url+"]["+title+"]]", | ||||
@@ -4,6 +4,13 @@ | |||||
package util | package util | ||||
import ( | |||||
"net/url" | |||||
"path" | |||||
"code.gitea.io/gitea/modules/log" | |||||
) | |||||
// OptionalBool a boolean that can be "null" | // OptionalBool a boolean that can be "null" | ||||
type OptionalBool byte | type OptionalBool byte | ||||
@@ -47,6 +54,20 @@ func Max(a, b int) int { | |||||
return a | return a | ||||
} | } | ||||
// URLJoin joins url components, like path.Join, but preserving contents | |||||
func URLJoin(base string, elems ...string) string { | |||||
u, err := url.Parse(base) | |||||
if err != nil { | |||||
log.Error(4, "URLJoin: Invalid base URL %s", base) | |||||
return "" | |||||
} | |||||
joinArgs := make([]string, 0, len(elems)+1) | |||||
joinArgs = append(joinArgs, u.Path) | |||||
joinArgs = append(joinArgs, elems...) | |||||
u.Path = path.Join(joinArgs...) | |||||
return u.String() | |||||
} | |||||
// Min min of two ints | // Min min of two ints | ||||
func Min(a, b int) int { | func Min(a, b int) int { | ||||
if a > b { | if a > b { | ||||
@@ -0,0 +1,36 @@ | |||||
// Copyright 2018 The Gitea Authors. All rights reserved. | |||||
// Use of this source code is governed by a MIT-style | |||||
// license that can be found in the LICENSE file. | |||||
package util | |||||
import ( | |||||
"testing" | |||||
"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/"), | |||||
} { | |||||
assert.Equal(t, test.Expected, URLJoin(test.Base, test.Elements...)) | |||||
} | |||||
} |
@@ -13,6 +13,8 @@ import ( | |||||
"code.gitea.io/git" | "code.gitea.io/git" | ||||
"code.gitea.io/gitea/models" | "code.gitea.io/gitea/models" | ||||
"code.gitea.io/gitea/modules/log" | |||||
"code.gitea.io/gitea/modules/util" | |||||
) | ) | ||||
// ToEmail convert models.EmailAddress to api.Email | // ToEmail convert models.EmailAddress to api.Email | ||||
@@ -25,35 +27,40 @@ func ToEmail(email *models.EmailAddress) *api.Email { | |||||
} | } | ||||
// ToBranch convert a commit and branch to an api.Branch | // ToBranch convert a commit and branch to an api.Branch | ||||
func ToBranch(b *models.Branch, c *git.Commit) *api.Branch { | |||||
func ToBranch(repo *models.Repository, b *models.Branch, c *git.Commit) *api.Branch { | |||||
return &api.Branch{ | return &api.Branch{ | ||||
Name: b.Name, | Name: b.Name, | ||||
Commit: ToCommit(c), | |||||
Commit: ToCommit(repo, c), | |||||
} | } | ||||
} | } | ||||
// ToCommit convert a commit to api.PayloadCommit | // ToCommit convert a commit to api.PayloadCommit | ||||
func ToCommit(c *git.Commit) *api.PayloadCommit { | |||||
func ToCommit(repo *models.Repository, c *git.Commit) *api.PayloadCommit { | |||||
authorUsername := "" | authorUsername := "" | ||||
author, err := models.GetUserByEmail(c.Author.Email) | |||||
if err == nil { | |||||
if author, err := models.GetUserByEmail(c.Author.Email); err == nil { | |||||
authorUsername = author.Name | authorUsername = author.Name | ||||
} else if !models.IsErrUserNotExist(err) { | |||||
log.Error(4, "GetUserByEmail: %v", err) | |||||
} | } | ||||
committerUsername := "" | committerUsername := "" | ||||
committer, err := models.GetUserByEmail(c.Committer.Email) | |||||
if err == nil { | |||||
if committer, err := models.GetUserByEmail(c.Committer.Email); err == nil { | |||||
committerUsername = committer.Name | committerUsername = committer.Name | ||||
} else if !models.IsErrUserNotExist(err) { | |||||
log.Error(4, "GetUserByEmail: %v", err) | |||||
} | } | ||||
verif := models.ParseCommitWithSignature(c) | verif := models.ParseCommitWithSignature(c) | ||||
var signature, payload string | var signature, payload string | ||||
if c.Signature != nil { | if c.Signature != nil { | ||||
signature = c.Signature.Signature | signature = c.Signature.Signature | ||||
payload = c.Signature.Payload | payload = c.Signature.Payload | ||||
} | } | ||||
return &api.PayloadCommit{ | return &api.PayloadCommit{ | ||||
ID: c.ID.String(), | ID: c.ID.String(), | ||||
Message: c.Message(), | Message: c.Message(), | ||||
URL: "Not implemented", | |||||
URL: util.URLJoin(repo.Link(), "commit", c.ID.String()), | |||||
Author: &api.PayloadUser{ | Author: &api.PayloadUser{ | ||||
Name: c.Author.Name, | Name: c.Author.Name, | ||||
Email: c.Author.Email, | Email: c.Author.Email, | ||||
@@ -8,9 +8,9 @@ import ( | |||||
api "code.gitea.io/sdk/gitea" | api "code.gitea.io/sdk/gitea" | ||||
"code.gitea.io/gitea/modules/context" | "code.gitea.io/gitea/modules/context" | ||||
"code.gitea.io/gitea/modules/markup" | |||||
"code.gitea.io/gitea/modules/markup/markdown" | "code.gitea.io/gitea/modules/markup/markdown" | ||||
"code.gitea.io/gitea/modules/setting" | "code.gitea.io/gitea/modules/setting" | ||||
"code.gitea.io/gitea/modules/util" | |||||
) | ) | ||||
// Markdown render markdown document to HTML | // Markdown render markdown document to HTML | ||||
@@ -45,7 +45,7 @@ func Markdown(ctx *context.APIContext, form api.MarkdownOption) { | |||||
switch form.Mode { | switch form.Mode { | ||||
case "gfm": | case "gfm": | ||||
md := []byte(form.Text) | md := []byte(form.Text) | ||||
context := markup.URLJoin(setting.AppURL, form.Context) | |||||
context := util.URLJoin(setting.AppURL, form.Context) | |||||
if form.Wiki { | if form.Wiki { | ||||
ctx.Write([]byte(markdown.RenderWiki(md, context, nil))) | ctx.Write([]byte(markdown.RenderWiki(md, context, nil))) | ||||
} else { | } else { | ||||
@@ -9,8 +9,8 @@ import ( | |||||
"testing" | "testing" | ||||
"code.gitea.io/gitea/modules/context" | "code.gitea.io/gitea/modules/context" | ||||
"code.gitea.io/gitea/modules/markup" | |||||
"code.gitea.io/gitea/modules/setting" | "code.gitea.io/gitea/modules/setting" | ||||
"code.gitea.io/gitea/modules/util" | |||||
api "code.gitea.io/sdk/gitea" | api "code.gitea.io/sdk/gitea" | ||||
"github.com/go-macaron/inject" | "github.com/go-macaron/inject" | ||||
@@ -53,7 +53,7 @@ func TestAPI_RenderGFM(t *testing.T) { | |||||
Context: Repo, | Context: Repo, | ||||
Wiki: true, | Wiki: true, | ||||
} | } | ||||
requrl, _ := url.Parse(markup.URLJoin(AppURL, "api", "v1", "markdown")) | |||||
requrl, _ := url.Parse(util.URLJoin(AppURL, "api", "v1", "markdown")) | |||||
req := &http.Request{ | req := &http.Request{ | ||||
Method: "POST", | Method: "POST", | ||||
URL: requrl, | URL: requrl, | ||||
@@ -147,7 +147,7 @@ func TestAPI_RenderSimple(t *testing.T) { | |||||
Text: "", | Text: "", | ||||
Context: Repo, | Context: Repo, | ||||
} | } | ||||
requrl, _ := url.Parse(markup.URLJoin(AppURL, "api", "v1", "markdown")) | |||||
requrl, _ := url.Parse(util.URLJoin(AppURL, "api", "v1", "markdown")) | |||||
req := &http.Request{ | req := &http.Request{ | ||||
Method: "POST", | Method: "POST", | ||||
URL: requrl, | URL: requrl, | ||||
@@ -166,7 +166,7 @@ func TestAPI_RenderSimple(t *testing.T) { | |||||
func TestAPI_RenderRaw(t *testing.T) { | func TestAPI_RenderRaw(t *testing.T) { | ||||
setting.AppURL = AppURL | setting.AppURL = AppURL | ||||
requrl, _ := url.Parse(markup.URLJoin(AppURL, "api", "v1", "markdown")) | |||||
requrl, _ := url.Parse(util.URLJoin(AppURL, "api", "v1", "markdown")) | |||||
req := &http.Request{ | req := &http.Request{ | ||||
Method: "POST", | Method: "POST", | ||||
URL: requrl, | URL: requrl, | ||||
@@ -61,7 +61,7 @@ func GetBranch(ctx *context.APIContext) { | |||||
return | return | ||||
} | } | ||||
ctx.JSON(200, convert.ToBranch(branch, c)) | |||||
ctx.JSON(200, convert.ToBranch(ctx.Repo.Repository, branch, c)) | |||||
} | } | ||||
// ListBranches list all the branches of a repository | // ListBranches list all the branches of a repository | ||||
@@ -98,7 +98,7 @@ func ListBranches(ctx *context.APIContext) { | |||||
ctx.Error(500, "GetCommit", err) | ctx.Error(500, "GetCommit", err) | ||||
return | return | ||||
} | } | ||||
apiBranches[i] = convert.ToBranch(branches[i], c) | |||||
apiBranches[i] = convert.ToBranch(ctx.Repo.Repository, branches[i], c) | |||||
} | } | ||||
ctx.JSON(200, &apiBranches) | ctx.JSON(200, &apiBranches) | ||||