Populate URL field of API commits (#3546)
* Populate URL field of API commits * fix orgmode_test
This commit is contained in:
		
							parent
							
								
									7b297808ce
								
							
						
					
					
						commit
						7b104f0cd0
					
				
					 11 changed files with 126 additions and 98 deletions
				
			
		|  | @ -15,8 +15,8 @@ import ( | |||
| 	"strings" | ||||
| 
 | ||||
| 	"code.gitea.io/gitea/modules/base" | ||||
| 	"code.gitea.io/gitea/modules/log" | ||||
| 	"code.gitea.io/gitea/modules/setting" | ||||
| 	"code.gitea.io/gitea/modules/util" | ||||
| 
 | ||||
| 	"github.com/Unknwon/com" | ||||
| 	"golang.org/x/net/html" | ||||
|  | @ -112,20 +112,6 @@ func cutoutVerbosePrefix(prefix string) string { | |||
| 	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
 | ||||
| type RenderIssueIndexPatternOptions struct { | ||||
| 	// 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 { | ||||
| 			buf.WriteString(`<a href="`) | ||||
| 			buf.WriteString(URLJoin( | ||||
| 			buf.WriteString(util.URLJoin( | ||||
| 				opts.URLPrefix, "issues", string(remainder[startIndex+1:endIndex]))) | ||||
| 			buf.WriteString(`">`) | ||||
| 			buf.Write(remainder[startIndex:endIndex]) | ||||
|  | @ -228,7 +214,7 @@ func renderFullSha1Pattern(rawBytes []byte, urlPrefix string) []byte { | |||
| 		path := protocol + "://" + paths | ||||
| 		author := string(m[3]) | ||||
| 		repoName := string(m[4]) | ||||
| 		path = URLJoin(path, author, repoName) | ||||
| 		path = util.URLJoin(path, author, repoName) | ||||
| 		ltype := "src" | ||||
| 		itemType := m[5] | ||||
| 		if IsSameDomain(paths) { | ||||
|  | @ -260,7 +246,7 @@ func renderFullSha1Pattern(rawBytes []byte, urlPrefix string) []byte { | |||
| 			text += ")" | ||||
| 		} | ||||
| 		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 | ||||
| } | ||||
|  | @ -399,9 +385,9 @@ func RenderShortLinks(rawBytes []byte, urlPrefix string, noLink bool, isWikiMark | |||
| 					urlPrefix = strings.Replace(urlPrefix, "/src/", "/raw/", 1) | ||||
| 				} | ||||
| 				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"] | ||||
| 			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) | ||||
| 		} else if !absoluteLink { | ||||
| 			if isWikiMarkdown { | ||||
| 				link = URLJoin("wiki", link) | ||||
| 				link = util.URLJoin("wiki", link) | ||||
| 			} | ||||
| 			link = URLJoin(urlPrefix, link) | ||||
| 			link = util.URLJoin(urlPrefix, link) | ||||
| 		} | ||||
| 		if noLink { | ||||
| 			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]) | ||||
| 		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) | ||||
| 	} | ||||
| 	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
 | ||||
| 		// as used by git and github for linking and thus we have to do similar.
 | ||||
| 		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 | ||||
| } | ||||
|  | @ -474,7 +460,7 @@ func RenderSpecialLink(rawBytes []byte, urlPrefix string, metas map[string]strin | |||
| 	for _, m := range ms { | ||||
| 		m = m[bytes.Index(m, []byte("@")):] | ||||
| 		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) | ||||
|  |  | |||
|  | @ -13,6 +13,7 @@ import ( | |||
| 	. "code.gitea.io/gitea/modules/markup" | ||||
| 	_ "code.gitea.io/gitea/modules/markup/markdown" | ||||
| 	"code.gitea.io/gitea/modules/setting" | ||||
| 	"code.gitea.io/gitea/modules/util" | ||||
| 
 | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| ) | ||||
|  | @ -37,12 +38,12 @@ var alphanumericMetas = map[string]string{ | |||
| 
 | ||||
| // numericLink an HTML to a numeric-style issue
 | ||||
| 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
 | ||||
| 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
 | ||||
|  | @ -63,31 +64,6 @@ func testRenderIssueIndexPattern(t *testing.T, input, expected string, opts Rend | |||
| 	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) { | ||||
| 	// numeric: render inputs without valid mentions
 | ||||
| 	test := func(s string) { | ||||
|  | @ -123,7 +99,7 @@ func TestRender_IssueIndexPattern2(t *testing.T) { | |||
| 	test := func(s, expectedFmt string, indices ...int) { | ||||
| 		links := make([]interface{}, len(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...) | ||||
| 		testRenderIssueIndexPattern(t, s, expectedNil, RenderIssueIndexPatternOptions{}) | ||||
|  | @ -228,8 +204,8 @@ func TestRender_AutoLink(t *testing.T) { | |||
| 	} | ||||
| 
 | ||||
| 	// 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
 | ||||
| 	for _, externalURL := range []string{ | ||||
|  | @ -240,7 +216,7 @@ func TestRender_AutoLink(t *testing.T) { | |||
| 	} | ||||
| 
 | ||||
| 	// render valid commit URLs
 | ||||
| 	tmp := URLJoin(AppSubURL, "commit", "d8a994ef243349f321568f9e36d5c3f444b99cae") | ||||
| 	tmp := util.URLJoin(AppSubURL, "commit", "d8a994ef243349f321568f9e36d5c3f444b99cae") | ||||
| 	test(tmp, "<a href=\""+tmp+"\">d8a994ef24</a>") | ||||
| 	tmp += "#diff-2" | ||||
| 	test(tmp, "<a href=\""+tmp+"\">d8a994ef24 (diff-2)</a>") | ||||
|  | @ -260,8 +236,8 @@ func TestRender_Commits(t *testing.T) { | |||
| 	} | ||||
| 
 | ||||
| 	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 src = strings.Replace(subtree, "/commit/", "/src/", -1) | ||||
| 
 | ||||
|  | @ -284,10 +260,10 @@ func TestRender_CrossReferences(t *testing.T) { | |||
| 
 | ||||
| 	test( | ||||
| 		"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( | ||||
| 		"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) { | ||||
|  | @ -482,7 +458,7 @@ func TestMisc_IsSameDomain(t *testing.T) { | |||
| 	setting.AppSubURL = AppSubURL | ||||
| 
 | ||||
| 	var sha = "b6dd6210eaebc915fd5be5579c58cce4da2e2579" | ||||
| 	var commit = URLJoin(AppSubURL, "commit", sha) | ||||
| 	var commit = util.URLJoin(AppSubURL, "commit", sha) | ||||
| 
 | ||||
| 	assert.True(t, IsSameDomain(commit)) | ||||
| 	assert.False(t, IsSameDomain("http://google.com/ncr")) | ||||
|  |  | |||
|  | @ -10,6 +10,7 @@ import ( | |||
| 
 | ||||
| 	"code.gitea.io/gitea/modules/markup" | ||||
| 	"code.gitea.io/gitea/modules/setting" | ||||
| 	"code.gitea.io/gitea/modules/util" | ||||
| 
 | ||||
| 	"github.com/russross/blackfriday" | ||||
| ) | ||||
|  | @ -27,9 +28,9 @@ func (r *Renderer) Link(out *bytes.Buffer, link []byte, title []byte, content [] | |||
| 		if link[0] != '#' { | ||||
| 			lnk := string(link) | ||||
| 			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) | ||||
| 		} | ||||
| 	} | ||||
|  | @ -97,7 +98,7 @@ var ( | |||
| func (r *Renderer) Image(out *bytes.Buffer, link []byte, title []byte, alt []byte) { | ||||
| 	prefix := r.URLPrefix | ||||
| 	if r.IsWiki { | ||||
| 		prefix = markup.URLJoin(prefix, "wiki", "src") | ||||
| 		prefix = util.URLJoin(prefix, "wiki", "src") | ||||
| 	} | ||||
| 	prefix = strings.Replace(prefix, "/src/", "/raw/", 1) | ||||
| 	if len(link) > 0 { | ||||
|  | @ -110,7 +111,7 @@ func (r *Renderer) Image(out *bytes.Buffer, link []byte, title []byte, alt []byt | |||
| 			} | ||||
| 		} else { | ||||
| 			lnk := string(link) | ||||
| 			lnk = markup.URLJoin(prefix, lnk) | ||||
| 			lnk = util.URLJoin(prefix, lnk) | ||||
| 			lnk = strings.Replace(lnk, " ", "+", -1) | ||||
| 			link = []byte(lnk) | ||||
| 		} | ||||
|  |  | |||
|  | @ -11,6 +11,7 @@ import ( | |||
| 	"code.gitea.io/gitea/modules/markup" | ||||
| 	. "code.gitea.io/gitea/modules/markup/markdown" | ||||
| 	"code.gitea.io/gitea/modules/setting" | ||||
| 	"code.gitea.io/gitea/modules/util" | ||||
| 
 | ||||
| 	"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>` | ||||
| 	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)", | ||||
| 		`<p><a href="`+lnk+`" 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) { | ||||
| 	setting.AppURL = AppURL | ||||
| 	setting.AppSubURL = AppSubURL | ||||
| 	tree := markup.URLJoin(AppSubURL, "src", "master") | ||||
| 	tree := util.URLJoin(AppSubURL, "src", "master") | ||||
| 
 | ||||
| 	test := func(input, expected, expectedWiki string) { | ||||
| 		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))) | ||||
| 	} | ||||
| 
 | ||||
| 	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" | ||||
| 
 | ||||
| 	test( | ||||
|  | @ -136,7 +137,7 @@ func TestRender_Images(t *testing.T) { | |||
| 
 | ||||
| 	url := "../../.images/src/02/train.jpg" | ||||
| 	title := "Train" | ||||
| 	result := markup.URLJoin(AppSubURL, url) | ||||
| 	result := util.URLJoin(AppSubURL, url) | ||||
| 
 | ||||
| 	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) { | ||||
| 	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++ { | ||||
| 		line := RenderWiki([]byte(sameCases[i]), AppSubURL, nil) | ||||
|  | @ -286,10 +287,10 @@ func TestTotal_RenderWiki(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++ { | ||||
| 		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) | ||||
| 	} | ||||
| 
 | ||||
|  |  | |||
|  | @ -8,8 +8,8 @@ import ( | |||
| 	"strings" | ||||
| 	"testing" | ||||
| 
 | ||||
| 	"code.gitea.io/gitea/modules/markup" | ||||
| 	"code.gitea.io/gitea/modules/setting" | ||||
| 	"code.gitea.io/gitea/modules/util" | ||||
| 
 | ||||
| 	"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>` | ||||
| 	test("[[https://google.com/]]", googleRendered) | ||||
| 
 | ||||
| 	lnk := markup.URLJoin(AppSubURL, "WikiPage") | ||||
| 	lnk := util.URLJoin(AppSubURL, "WikiPage") | ||||
| 	test("[[WikiPage][WikiPage]]", | ||||
| 		`<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" | ||||
| 	title := "Train" | ||||
| 	result := markup.URLJoin(AppSubURL, url) | ||||
| 	result := util.URLJoin(AppSubURL, url) | ||||
| 
 | ||||
| 	test( | ||||
| 		"[[file:"+url+"]["+title+"]]", | ||||
|  |  | |||
|  | @ -4,6 +4,13 @@ | |||
| 
 | ||||
| package util | ||||
| 
 | ||||
| import ( | ||||
| 	"net/url" | ||||
| 	"path" | ||||
| 
 | ||||
| 	"code.gitea.io/gitea/modules/log" | ||||
| ) | ||||
| 
 | ||||
| // OptionalBool a boolean that can be "null"
 | ||||
| type OptionalBool byte | ||||
| 
 | ||||
|  | @ -47,6 +54,20 @@ func Max(a, b int) int { | |||
| 	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
 | ||||
| func Min(a, b int) int { | ||||
| 	if a > b { | ||||
|  |  | |||
							
								
								
									
										36
									
								
								modules/util/util_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								modules/util/util_test.go
									
									
									
									
									
										Normal file
									
								
							|  | @ -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/gitea/models" | ||||
| 	"code.gitea.io/gitea/modules/log" | ||||
| 	"code.gitea.io/gitea/modules/util" | ||||
| ) | ||||
| 
 | ||||
| // 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
 | ||||
| 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{ | ||||
| 		Name:   b.Name, | ||||
| 		Commit: ToCommit(c), | ||||
| 		Commit: ToCommit(repo, c), | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // 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 := "" | ||||
| 	author, err := models.GetUserByEmail(c.Author.Email) | ||||
| 	if err == nil { | ||||
| 	if author, err := models.GetUserByEmail(c.Author.Email); err == nil { | ||||
| 		authorUsername = author.Name | ||||
| 	} else if !models.IsErrUserNotExist(err) { | ||||
| 		log.Error(4, "GetUserByEmail: %v", err) | ||||
| 	} | ||||
| 
 | ||||
| 	committerUsername := "" | ||||
| 	committer, err := models.GetUserByEmail(c.Committer.Email) | ||||
| 	if err == nil { | ||||
| 	if committer, err := models.GetUserByEmail(c.Committer.Email); err == nil { | ||||
| 		committerUsername = committer.Name | ||||
| 	} else if !models.IsErrUserNotExist(err) { | ||||
| 		log.Error(4, "GetUserByEmail: %v", err) | ||||
| 	} | ||||
| 
 | ||||
| 	verif := models.ParseCommitWithSignature(c) | ||||
| 	var signature, payload string | ||||
| 	if c.Signature != nil { | ||||
| 		signature = c.Signature.Signature | ||||
| 		payload = c.Signature.Payload | ||||
| 	} | ||||
| 
 | ||||
| 	return &api.PayloadCommit{ | ||||
| 		ID:      c.ID.String(), | ||||
| 		Message: c.Message(), | ||||
| 		URL:     "Not implemented", | ||||
| 		URL:     util.URLJoin(repo.Link(), "commit", c.ID.String()), | ||||
| 		Author: &api.PayloadUser{ | ||||
| 			Name:     c.Author.Name, | ||||
| 			Email:    c.Author.Email, | ||||
|  |  | |||
|  | @ -8,9 +8,9 @@ import ( | |||
| 	api "code.gitea.io/sdk/gitea" | ||||
| 
 | ||||
| 	"code.gitea.io/gitea/modules/context" | ||||
| 	"code.gitea.io/gitea/modules/markup" | ||||
| 	"code.gitea.io/gitea/modules/markup/markdown" | ||||
| 	"code.gitea.io/gitea/modules/setting" | ||||
| 	"code.gitea.io/gitea/modules/util" | ||||
| ) | ||||
| 
 | ||||
| // Markdown render markdown document to HTML
 | ||||
|  | @ -45,7 +45,7 @@ func Markdown(ctx *context.APIContext, form api.MarkdownOption) { | |||
| 	switch form.Mode { | ||||
| 	case "gfm": | ||||
| 		md := []byte(form.Text) | ||||
| 		context := markup.URLJoin(setting.AppURL, form.Context) | ||||
| 		context := util.URLJoin(setting.AppURL, form.Context) | ||||
| 		if form.Wiki { | ||||
| 			ctx.Write([]byte(markdown.RenderWiki(md, context, nil))) | ||||
| 		} else { | ||||
|  |  | |||
|  | @ -9,8 +9,8 @@ import ( | |||
| 	"testing" | ||||
| 
 | ||||
| 	"code.gitea.io/gitea/modules/context" | ||||
| 	"code.gitea.io/gitea/modules/markup" | ||||
| 	"code.gitea.io/gitea/modules/setting" | ||||
| 	"code.gitea.io/gitea/modules/util" | ||||
| 	api "code.gitea.io/sdk/gitea" | ||||
| 
 | ||||
| 	"github.com/go-macaron/inject" | ||||
|  | @ -53,7 +53,7 @@ func TestAPI_RenderGFM(t *testing.T) { | |||
| 		Context: Repo, | ||||
| 		Wiki:    true, | ||||
| 	} | ||||
| 	requrl, _ := url.Parse(markup.URLJoin(AppURL, "api", "v1", "markdown")) | ||||
| 	requrl, _ := url.Parse(util.URLJoin(AppURL, "api", "v1", "markdown")) | ||||
| 	req := &http.Request{ | ||||
| 		Method: "POST", | ||||
| 		URL:    requrl, | ||||
|  | @ -147,7 +147,7 @@ func TestAPI_RenderSimple(t *testing.T) { | |||
| 		Text:    "", | ||||
| 		Context: Repo, | ||||
| 	} | ||||
| 	requrl, _ := url.Parse(markup.URLJoin(AppURL, "api", "v1", "markdown")) | ||||
| 	requrl, _ := url.Parse(util.URLJoin(AppURL, "api", "v1", "markdown")) | ||||
| 	req := &http.Request{ | ||||
| 		Method: "POST", | ||||
| 		URL:    requrl, | ||||
|  | @ -166,7 +166,7 @@ func TestAPI_RenderSimple(t *testing.T) { | |||
| func TestAPI_RenderRaw(t *testing.T) { | ||||
| 	setting.AppURL = AppURL | ||||
| 
 | ||||
| 	requrl, _ := url.Parse(markup.URLJoin(AppURL, "api", "v1", "markdown")) | ||||
| 	requrl, _ := url.Parse(util.URLJoin(AppURL, "api", "v1", "markdown")) | ||||
| 	req := &http.Request{ | ||||
| 		Method: "POST", | ||||
| 		URL:    requrl, | ||||
|  |  | |||
|  | @ -61,7 +61,7 @@ func GetBranch(ctx *context.APIContext) { | |||
| 		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
 | ||||
|  | @ -98,7 +98,7 @@ func ListBranches(ctx *context.APIContext) { | |||
| 			ctx.Error(500, "GetCommit", err) | ||||
| 			return | ||||
| 		} | ||||
| 		apiBranches[i] = convert.ToBranch(branches[i], c) | ||||
| 		apiBranches[i] = convert.ToBranch(ctx.Repo.Repository, branches[i], c) | ||||
| 	} | ||||
| 
 | ||||
| 	ctx.JSON(200, &apiBranches) | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue