1
0
mirror of https://github.com/go-gitea/gitea.git synced 2024-09-27 02:56:01 -04:00

Compare commits

...

7 Commits

Author SHA1 Message Date
wxiaoguang
583b859661
Merge branch 'main' into fix-natural-sort 2024-06-17 14:17:25 +08:00
Brecht Van Lommel
597d1da96b
Fix missing images in editor preview due to wrong links (#31299)
Parse base path and tree path so that media links can be correctly
created with /media/.

Resolves #31294

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2024-06-17 14:16:14 +08:00
wxiaoguang
9d1c753a0e
Merge branch 'main' into fix-natural-sort 2024-06-17 13:29:58 +08:00
wxiaoguang
f5dfd7d73c
Add a simple test for AdoptRepository (#31391)
Follow #31333
2024-06-17 01:18:35 +00:00
GiteaBot
129206da45 [skip ci] Updated licenses and gitignores 2024-06-17 00:27:39 +00:00
wxiaoguang
f446e3b4ab
Fix JS error when creating new issue (#31383)
Fix #31336
2024-06-16 02:07:21 +00:00
GiteaBot
c70d4f03c9 [skip ci] Updated translations via Crowdin 2024-06-16 00:28:50 +00:00
11 changed files with 168 additions and 89 deletions

View File

@ -86,10 +86,10 @@ type RenderContext struct {
}
type Links struct {
AbsolutePrefix bool
Base string
BranchPath string
TreePath string
AbsolutePrefix bool // add absolute URL prefix to auto-resolved links like "#issue", but not for pre-provided links and medias
Base string // base prefix for pre-provided links and medias (images, videos)
BranchPath string // actually it is the ref path, eg: "branch/features/feat-12", "tag/v1.0"
TreePath string // the dir of the file, eg: "doc" if the file "doc/CHANGE.md" is being rendered
}
func (l *Links) Prefix() string {

View File

@ -25,7 +25,8 @@ type MarkupOption struct {
//
// in: body
Mode string
// Context to render
// URL path for rendering issue, media and file links
// Expected format: /subpath/{user}/{repo}/src/{branch, commit, tag}/{identifier/path}/{file/dir}
//
// in: body
Context string
@ -53,7 +54,8 @@ type MarkdownOption struct {
//
// in: body
Mode string
// Context to render
// URL path for rendering issue, media and file links
// Expected format: /subpath/{user}/{repo}/src/{branch, commit, tag}/{identifier/path}/{file/dir}
//
// in: body
Context string

47
options/gitignore/IAR Normal file
View File

@ -0,0 +1,47 @@
# Compiled binaries
*.o
*.bin
*.elf
*.hex
*.map
*.out
*.obj
# Trash
*.bak
thumbs.db
*.~*
# IAR Settings
**/settings/*.crun
**/settings/*.dbgdt
**/settings/*.cspy
**/settings/*.cspy.*
**/settings/*.xcl
**/settings/*.dni
**/settings/*.wsdt
**/settings/*.wspos
# IAR Debug Exe
**/Exe/*.sim
# IAR Debug Obj
**/Obj/*.pbd
**/Obj/*.pbd.*
**/Obj/*.pbi
**/Obj/*.pbi.*
# IAR project "Debug" directory
Debug/
# IAR project "Release" directory
Release/
# IAR project settings directory
settings/
# IAR backup files
Backup*
# IAR .dep files
*.dep

View File

@ -42,10 +42,3 @@ fastlane/report.xml
fastlane/Preview.html
fastlane/screenshots/**/*.png
fastlane/test_output
# Code Injection
#
# After new code Injection tools there's a generated folder /iOSInjectionProject
# https://github.com/johnno1962/injectionforxcode
iOSInjectionProject/

View File

@ -35,6 +35,3 @@ override.tf.json
# Ignore CLI configuration files
.terraformrc
terraform.rc
# Ignore hcl file
.terraform.lock.hcl

View File

@ -1238,6 +1238,7 @@ file_view_rendered=レンダリング表示
file_view_raw=Rawデータを見る
file_permalink=パーマリンク
file_too_large=このファイルは大きすぎるため、表示できません。
file_is_empty=ファイルは空です。
code_preview_line_from_to=%[1]d 行目から %[2]d 行目 in %[3]s
code_preview_line_in=%[1]d 行目 in %[2]s
invisible_runes_header=このファイルには不可視のUnicode文字が含まれています
@ -1442,6 +1443,7 @@ issues.new.clear_assignees=担当者をクリア
issues.new.no_assignees=担当者なし
issues.new.no_reviewers=レビューアなし
issues.new.blocked_user=リポジトリのオーナーがあなたをブロックしているため、イシューを作成できません。
issues.edit.already_changed=イシューの変更を保存できません。 他のユーザーによって内容がすでに変更されているようです。 変更を上書きしないようにするため、ページを更新してからもう一度編集してください
issues.edit.blocked_user=投稿者またはリポジトリのオーナーがあなたをブロックしているため、内容を編集できません。
issues.choose.get_started=始める
issues.choose.open_external_link=オープン
@ -1757,6 +1759,7 @@ compare.compare_head=比較
pulls.desc=プルリクエストとコードレビューの有効化。
pulls.new=新しいプルリクエスト
pulls.new.blocked_user=リポジトリのオーナーがあなたをブロックしているため、プルリクエストを作成できません。
pulls.edit.already_changed=プルリクエストの変更を保存できません。 他のユーザーによって内容がすでに変更されているようです。 変更を上書きしないようにするため、ページを更新してからもう一度編集してください
pulls.view=プルリクエストを表示
pulls.compare_changes=新規プルリクエスト
pulls.allow_edits_from_maintainers=メンテナーからの編集を許可する
@ -1902,6 +1905,7 @@ pulls.recently_pushed_new_branches=%[2]s 、あなたはブランチ <strong>%[1
pull.deleted_branch=(削除済み):%s
comments.edit.already_changed=コメントの変更を保存できません。 他のユーザーによって内容がすでに変更されているようです。 変更を上書きしないようにするため、ページを更新してからもう一度編集してください
milestones.new=新しいマイルストーン
milestones.closed=%s にクローズ

View File

@ -7,6 +7,7 @@ import (
go_context "context"
"io"
"net/http"
"path"
"strings"
"testing"
@ -19,36 +20,40 @@ import (
"github.com/stretchr/testify/assert"
)
const (
AppURL = "http://localhost:3000/"
Repo = "gogits/gogs"
FullURL = AppURL + Repo + "/"
)
const AppURL = "http://localhost:3000/"
func testRenderMarkup(t *testing.T, mode, filePath, text, responseBody string, responseCode int) {
func testRenderMarkup(t *testing.T, mode string, wiki bool, filePath, text, expectedBody string, expectedCode int) {
setting.AppURL = AppURL
context := "/gogits/gogs"
if !wiki {
context += path.Join("/src/branch/main", path.Dir(filePath))
}
options := api.MarkupOption{
Mode: mode,
Text: text,
Context: Repo,
Wiki: true,
Context: context,
Wiki: wiki,
FilePath: filePath,
}
ctx, resp := contexttest.MockAPIContext(t, "POST /api/v1/markup")
web.SetForm(ctx, &options)
Markup(ctx)
assert.Equal(t, responseBody, resp.Body.String())
assert.Equal(t, responseCode, resp.Code)
assert.Equal(t, expectedBody, resp.Body.String())
assert.Equal(t, expectedCode, resp.Code)
resp.Body.Reset()
}
func testRenderMarkdown(t *testing.T, mode, text, responseBody string, responseCode int) {
func testRenderMarkdown(t *testing.T, mode string, wiki bool, text, responseBody string, responseCode int) {
setting.AppURL = AppURL
context := "/gogits/gogs"
if !wiki {
context += "/src/branch/main"
}
options := api.MarkdownOption{
Mode: mode,
Text: text,
Context: Repo,
Wiki: true,
Context: context,
Wiki: wiki,
}
ctx, resp := contexttest.MockAPIContext(t, "POST /api/v1/markdown")
web.SetForm(ctx, &options)
@ -65,7 +70,7 @@ func TestAPI_RenderGFM(t *testing.T) {
},
})
testCasesCommon := []string{
testCasesWiki := []string{
// dear imgui wiki markdown extract: special wiki syntax
`Wiki! Enjoy :)
- [[Links, Language bindings, Engine bindings|Links]]
@ -74,20 +79,20 @@ func TestAPI_RenderGFM(t *testing.T) {
// rendered
`<p>Wiki! Enjoy :)</p>
<ul>
<li><a href="` + FullURL + `wiki/Links" rel="nofollow">Links, Language bindings, Engine bindings</a></li>
<li><a href="` + FullURL + `wiki/Tips" rel="nofollow">Tips</a></li>
<li>Bezier widget (by <a href="` + AppURL + `r-lyeh" rel="nofollow">@r-lyeh</a>) <a href="https://github.com/ocornut/imgui/issues/786" rel="nofollow">https://github.com/ocornut/imgui/issues/786</a></li>
<li><a href="http://localhost:3000/gogits/gogs/wiki/Links" rel="nofollow">Links, Language bindings, Engine bindings</a></li>
<li><a href="http://localhost:3000/gogits/gogs/wiki/Tips" rel="nofollow">Tips</a></li>
<li>Bezier widget (by <a href="http://localhost:3000/r-lyeh" rel="nofollow">@r-lyeh</a>) <a href="https://github.com/ocornut/imgui/issues/786" rel="nofollow">https://github.com/ocornut/imgui/issues/786</a></li>
</ul>
`,
// Guard wiki sidebar: special syntax
`[[Guardfile-DSL / Configuring-Guard|Guardfile-DSL---Configuring-Guard]]`,
// rendered
`<p><a href="` + FullURL + `wiki/Guardfile-DSL---Configuring-Guard" rel="nofollow">Guardfile-DSL / Configuring-Guard</a></p>
`<p><a href="http://localhost:3000/gogits/gogs/wiki/Guardfile-DSL---Configuring-Guard" rel="nofollow">Guardfile-DSL / Configuring-Guard</a></p>
`,
// special syntax
`[[Name|Link]]`,
// rendered
`<p><a href="` + FullURL + `wiki/Link" rel="nofollow">Name</a></p>
`<p><a href="http://localhost:3000/gogits/gogs/wiki/Link" rel="nofollow">Name</a></p>
`,
// empty
``,
@ -95,7 +100,7 @@ func TestAPI_RenderGFM(t *testing.T) {
``,
}
testCasesDocument := []string{
testCasesWikiDocument := []string{
// wine-staging wiki home extract: special wiki syntax, images
`## What is Wine Staging?
**Wine Staging** on website [wine-staging.com](http://wine-staging.com).
@ -111,31 +116,48 @@ Here are some links to the most important topics. You can find the full list of
<p><strong>Wine Staging</strong> on website <a href="http://wine-staging.com" rel="nofollow">wine-staging.com</a>.</p>
<h2 id="user-content-quick-links">Quick Links</h2>
<p>Here are some links to the most important topics. You can find the full list of pages at the sidebar.</p>
<p><a href="` + FullURL + `wiki/Configuration" rel="nofollow">Configuration</a>
<a href="` + FullURL + `wiki/raw/images/icon-bug.png" rel="nofollow"><img src="` + FullURL + `wiki/raw/images/icon-bug.png" title="icon-bug.png" alt="images/icon-bug.png"/></a></p>
<p><a href="http://localhost:3000/gogits/gogs/wiki/Configuration" rel="nofollow">Configuration</a>
<a href="http://localhost:3000/gogits/gogs/wiki/raw/images/icon-bug.png" rel="nofollow"><img src="http://localhost:3000/gogits/gogs/wiki/raw/images/icon-bug.png" title="icon-bug.png" alt="images/icon-bug.png"/></a></p>
`,
}
for i := 0; i < len(testCasesCommon); i += 2 {
text := testCasesCommon[i]
response := testCasesCommon[i+1]
testRenderMarkdown(t, "gfm", text, response, http.StatusOK)
testRenderMarkup(t, "gfm", "", text, response, http.StatusOK)
testRenderMarkdown(t, "comment", text, response, http.StatusOK)
testRenderMarkup(t, "comment", "", text, response, http.StatusOK)
testRenderMarkup(t, "file", "path/test.md", text, response, http.StatusOK)
for i := 0; i < len(testCasesWiki); i += 2 {
text := testCasesWiki[i]
response := testCasesWiki[i+1]
testRenderMarkdown(t, "gfm", true, text, response, http.StatusOK)
testRenderMarkup(t, "gfm", true, "", text, response, http.StatusOK)
testRenderMarkdown(t, "comment", true, text, response, http.StatusOK)
testRenderMarkup(t, "comment", true, "", text, response, http.StatusOK)
testRenderMarkup(t, "file", true, "path/test.md", text, response, http.StatusOK)
}
for i := 0; i < len(testCasesDocument); i += 2 {
text := testCasesDocument[i]
response := testCasesDocument[i+1]
testRenderMarkdown(t, "gfm", text, response, http.StatusOK)
testRenderMarkup(t, "gfm", "", text, response, http.StatusOK)
testRenderMarkup(t, "file", "path/test.md", text, response, http.StatusOK)
for i := 0; i < len(testCasesWikiDocument); i += 2 {
text := testCasesWikiDocument[i]
response := testCasesWikiDocument[i+1]
testRenderMarkdown(t, "gfm", true, text, response, http.StatusOK)
testRenderMarkup(t, "gfm", true, "", text, response, http.StatusOK)
testRenderMarkup(t, "file", true, "path/test.md", text, response, http.StatusOK)
}
testRenderMarkup(t, "file", "path/test.unknown", "## Test", "Unsupported render extension: .unknown\n", http.StatusUnprocessableEntity)
testRenderMarkup(t, "unknown", "", "## Test", "Unknown mode: unknown\n", http.StatusUnprocessableEntity)
input := "[Link](test.md)\n![Image](image.png)"
testRenderMarkdown(t, "gfm", false, input, `<p><a href="http://localhost:3000/gogits/gogs/src/branch/main/test.md" rel="nofollow">Link</a>
<a href="http://localhost:3000/gogits/gogs/media/branch/main/image.png" target="_blank" rel="nofollow noopener"><img src="http://localhost:3000/gogits/gogs/media/branch/main/image.png" alt="Image"/></a></p>
`, http.StatusOK)
testRenderMarkdown(t, "gfm", false, input, `<p><a href="http://localhost:3000/gogits/gogs/src/branch/main/test.md" rel="nofollow">Link</a>
<a href="http://localhost:3000/gogits/gogs/media/branch/main/image.png" target="_blank" rel="nofollow noopener"><img src="http://localhost:3000/gogits/gogs/media/branch/main/image.png" alt="Image"/></a></p>
`, http.StatusOK)
testRenderMarkup(t, "gfm", false, "", input, `<p><a href="http://localhost:3000/gogits/gogs/src/branch/main/test.md" rel="nofollow">Link</a>
<a href="http://localhost:3000/gogits/gogs/media/branch/main/image.png" target="_blank" rel="nofollow noopener"><img src="http://localhost:3000/gogits/gogs/media/branch/main/image.png" alt="Image"/></a></p>
`, http.StatusOK)
testRenderMarkup(t, "file", false, "path/new-file.md", input, `<p><a href="http://localhost:3000/gogits/gogs/src/branch/main/path/test.md" rel="nofollow">Link</a>
<a href="http://localhost:3000/gogits/gogs/media/branch/main/path/image.png" target="_blank" rel="nofollow noopener"><img src="http://localhost:3000/gogits/gogs/media/branch/main/path/image.png" alt="Image"/></a></p>
`, http.StatusOK)
testRenderMarkup(t, "file", true, "path/test.unknown", "## Test", "Unsupported render extension: .unknown\n", http.StatusUnprocessableEntity)
testRenderMarkup(t, "unknown", true, "", "## Test", "Unknown mode: unknown\n", http.StatusUnprocessableEntity)
}
var simpleCases = []string{
@ -160,7 +182,7 @@ func TestAPI_RenderSimple(t *testing.T) {
options := api.MarkdownOption{
Mode: "markdown",
Text: "",
Context: Repo,
Context: "/gogits/gogs",
}
ctx, resp := contexttest.MockAPIContext(t, "POST /api/v1/markdown")
for i := 0; i < len(simpleCases); i += 2 {

View File

@ -7,63 +7,67 @@ package common
import (
"fmt"
"net/http"
"path"
"strings"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/modules/httplib"
"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"
"code.gitea.io/gitea/services/context"
"mvdan.cc/xurls/v2"
)
// RenderMarkup renders markup text for the /markup and /markdown endpoints
func RenderMarkup(ctx *context.Base, repo *context.Repository, mode, text, urlPrefix, filePath string, wiki bool) {
var markupType string
relativePath := ""
func RenderMarkup(ctx *context.Base, repo *context.Repository, mode, text, urlPathContext, filePath string, wiki bool) {
// urlPathContext format is "/subpath/{user}/{repo}/src/{branch, commit, tag}/{identifier/path}/{file/dir}"
// filePath is the path of the file to render if the end user is trying to preview a repo file (mode == "file")
// filePath will be used as RenderContext.RelativePath
if len(text) == 0 {
_, _ = ctx.Write([]byte(""))
return
// for example, when previewing file "/gitea/owner/repo/src/branch/features/feat-123/doc/CHANGE.md", then filePath is "doc/CHANGE.md"
// and the urlPathContext is "/gitea/owner/repo/src/branch/features/feat-123/doc"
var markupType, relativePath string
links := markup.Links{AbsolutePrefix: true}
if urlPathContext != "" {
links.Base = fmt.Sprintf("%s%s", httplib.GuessCurrentHostURL(ctx), urlPathContext)
}
switch mode {
case "markdown":
// Raw markdown
if err := markdown.RenderRaw(&markup.RenderContext{
Ctx: ctx,
Links: markup.Links{
AbsolutePrefix: true,
Base: urlPrefix,
},
Ctx: ctx,
Links: links,
}, strings.NewReader(text), ctx.Resp); err != nil {
ctx.Error(http.StatusInternalServerError, err.Error())
}
return
case "comment":
// Comment as markdown
// Issue & comment content
markupType = markdown.MarkupName
case "gfm":
// Github Flavored Markdown as document
// GitHub Flavored Markdown
markupType = markdown.MarkupName
case "file":
// File as document based on file extension
markupType = ""
markupType = "" // render the repo file content by its extension
relativePath = filePath
default:
ctx.Error(http.StatusUnprocessableEntity, fmt.Sprintf("Unknown mode: %s", mode))
return
}
if !strings.HasPrefix(setting.AppSubURL+"/", urlPrefix) {
// check if urlPrefix is already set to a URL
linkRegex, _ := xurls.StrictMatchingScheme("https?://")
m := linkRegex.FindStringIndex(urlPrefix)
if m == nil {
urlPrefix = util.URLJoin(setting.AppURL, urlPrefix)
}
fields := strings.SplitN(strings.TrimPrefix(urlPathContext, setting.AppSubURL+"/"), "/", 5)
if len(fields) == 5 && fields[2] == "src" && (fields[3] == "branch" || fields[3] == "commit" || fields[3] == "tag") {
// absolute base prefix is something like "https://host/subpath/{user}/{repo}"
absoluteBasePrefix := fmt.Sprintf("%s%s/%s", httplib.GuessCurrentAppURL(ctx), fields[0], fields[1])
fileDir := path.Dir(filePath) // it is "doc" if filePath is "doc/CHANGE.md"
refPath := strings.Join(fields[3:], "/") // it is "branch/features/feat-12/doc"
refPath = strings.TrimSuffix(refPath, "/"+fileDir) // now we get the correct branch path: "branch/features/feat-12"
links = markup.Links{AbsolutePrefix: true, Base: absoluteBasePrefix, BranchPath: refPath, TreePath: fileDir}
}
meta := map[string]string{}
@ -81,12 +85,9 @@ func RenderMarkup(ctx *context.Base, repo *context.Repository, mode, text, urlPr
}
if err := markup.Render(&markup.RenderContext{
Ctx: ctx,
Repo: repoCtx,
Links: markup.Links{
AbsolutePrefix: true,
Base: urlPrefix,
},
Ctx: ctx,
Repo: repoCtx,
Links: links,
Metas: meta,
IsWiki: wiki,
Type: markupType,

View File

@ -6,10 +6,13 @@ package repository
import (
"os"
"path"
"path/filepath"
"testing"
"code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/setting"
"github.com/stretchr/testify/assert"
@ -83,3 +86,13 @@ func TestListUnadoptedRepositories_ListOptions(t *testing.T) {
assert.Equal(t, 2, count)
assert.Equal(t, unadoptedList[1], repoNames[0])
}
func TestAdoptRepository(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
assert.NoError(t, unittest.CopyDir(filepath.Join(setting.RepoRootPath, "user2", "repo1.git"), filepath.Join(setting.RepoRootPath, "user2", "test-adopt.git")))
user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
_, err := AdoptRepository(db.DefaultContext, user2, user2, CreateRepoOptions{Name: "test-adopt"})
assert.NoError(t, err)
repoTestAdopt := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{Name: "test-adopt"})
assert.Equal(t, "sha1", repoTestAdopt.ObjectFormatName)
}

View File

@ -22404,7 +22404,7 @@
"type": "object",
"properties": {
"Context": {
"description": "Context to render\n\nin: body",
"description": "URL path for rendering issue, media and file links\nExpected format: /subpath/{user}/{repo}/src/{branch, commit, tag}/{identifier/path}/{file/dir}\n\nin: body",
"type": "string"
},
"Mode": {
@ -22427,7 +22427,7 @@
"type": "object",
"properties": {
"Context": {
"description": "Context to render\n\nin: body",
"description": "URL path for rendering issue, media and file links\nExpected format: /subpath/{user}/{repo}/src/{branch, commit, tag}/{identifier/path}/{file/dir}\n\nin: body",
"type": "string"
},
"FilePath": {

View File

@ -272,7 +272,7 @@ export function initRepoCommentForm() {
}
$list.find('.selected').html(`
<a class="item muted sidebar-item-link" href=${htmlEscape(this.getAttribute('href'))}>
<a class="item muted sidebar-item-link" href="${htmlEscape(this.getAttribute('data-href'))}">
${icon}
${htmlEscape(this.textContent)}
</a>