Merge remote-tracking branch 'upstream/main' into limit-repo-size

This commit is contained in:
DmitryFrolovTri
2023-04-18 03:58:56 +00:00
58 changed files with 743 additions and 310 deletions
+5
View File
@@ -21,6 +21,7 @@ const (
githubEventIssueComment = "issue_comment"
githubEventRelease = "release"
githubEventPullRequestComment = "pull_request_comment"
githubEventGollum = "gollum"
)
// canGithubEventMatch check if the input Github event can match any Gitea event.
@@ -29,6 +30,10 @@ func canGithubEventMatch(eventName string, triggedEvent webhook_module.HookEvent
case githubEventRegistryPackage:
return triggedEvent == webhook_module.HookEventPackage
// See https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#gollum
case githubEventGollum:
return triggedEvent == webhook_module.HookEventWiki
case githubEventIssues:
switch triggedEvent {
case webhook_module.HookEventIssues,
-2
View File
@@ -119,8 +119,6 @@ func detectMatched(commit *git.Commit, triggedEvent webhook_module.HookEventType
webhook_module.HookEventCreate,
webhook_module.HookEventDelete,
webhook_module.HookEventFork,
// FIXME: `wiki` event should match `gollum` event
// See https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#gollum
webhook_module.HookEventWiki:
if len(evt.Acts()) != 0 {
log.Warn("Ignore unsupported %s event arguments %v", triggedEvent, evt.Acts())
+7
View File
@@ -92,6 +92,13 @@ func TestDetectMatched(t *testing.T) {
yamlOn: "on:\n registry_package:\n types: [updated]",
expected: false,
},
{
desc: "HookEventWiki(wiki) matches githubEventGollum(gollum)",
triggedEvent: webhook_module.HookEventWiki,
payload: nil,
yamlOn: "on: gollum",
expected: true,
},
}
for _, tc := range testCases {
+1 -1
View File
@@ -34,7 +34,7 @@ func nodeToTable(meta *yaml.Node) ast.Node {
func mappingNodeToTable(meta *yaml.Node) ast.Node {
table := east.NewTable()
alignments := []east.Alignment{}
alignments := make([]east.Alignment, 0, len(meta.Content)/2)
for i := 0; i < len(meta.Content); i += 2 {
alignments = append(alignments, east.AlignNone)
}
+20 -14
View File
@@ -34,16 +34,17 @@ type ASTTransformer struct{}
// Transform transforms the given AST tree.
func (g *ASTTransformer) Transform(node *ast.Document, reader text.Reader, pc parser.Context) {
firstChild := node.FirstChild()
createTOC := false
tocMode := ""
ctx := pc.Get(renderContextKey).(*markup.RenderContext)
rc := pc.Get(renderConfigKey).(*RenderConfig)
tocList := make([]markup.Header, 0, 20)
if rc.yamlNode != nil {
metaNode := rc.toMetaNode()
if metaNode != nil {
node.InsertBefore(node, firstChild, metaNode)
}
createTOC = rc.TOC
ctx.TableOfContents = make([]markup.Header, 0, 100)
tocMode = rc.TOC
}
attentionMarkedBlockquotes := make(container.Set[*ast.Blockquote])
@@ -59,15 +60,15 @@ func (g *ASTTransformer) Transform(node *ast.Document, reader text.Reader, pc pa
v.SetAttribute(attr.Name, []byte(fmt.Sprintf("%v", attr.Value)))
}
}
text := n.Text(reader.Source())
txt := n.Text(reader.Source())
header := markup.Header{
Text: util.BytesToReadOnlyString(text),
Text: util.BytesToReadOnlyString(txt),
Level: v.Level,
}
if id, found := v.AttributeString("id"); found {
header.ID = util.BytesToReadOnlyString(id.([]byte))
}
ctx.TableOfContents = append(ctx.TableOfContents, header)
tocList = append(tocList, header)
case *ast.Image:
// Images need two things:
//
@@ -201,14 +202,15 @@ func (g *ASTTransformer) Transform(node *ast.Document, reader text.Reader, pc pa
return ast.WalkContinue, nil
})
if createTOC && len(ctx.TableOfContents) > 0 {
lang := rc.Lang
if len(lang) == 0 {
lang = setting.Langs[0]
}
tocNode := createTOCNode(ctx.TableOfContents, lang)
if tocNode != nil {
showTocInMain := tocMode == "true" /* old behavior, in main view */ || tocMode == "main"
showTocInSidebar := !showTocInMain && tocMode != "false" // not hidden, not main, then show it in sidebar
if len(tocList) > 0 && (showTocInMain || showTocInSidebar) {
if showTocInMain {
tocNode := createTOCNode(tocList, rc.Lang, nil)
node.InsertBefore(node, firstChild, tocNode)
} else {
tocNode := createTOCNode(tocList, rc.Lang, map[string]string{"open": "open"})
ctx.SidebarTocNode = tocNode
}
}
@@ -373,7 +375,11 @@ func (r *HTMLRenderer) renderDocument(w util.BufWriter, source []byte, node ast.
func (r *HTMLRenderer) renderDetails(w util.BufWriter, source []byte, node ast.Node, entering bool) (ast.WalkStatus, error) {
var err error
if entering {
_, err = w.WriteString("<details>")
if _, err = w.WriteString("<details"); err != nil {
return ast.WalkStop, err
}
html.RenderAttributes(w, node, nil)
_, err = w.WriteString(">")
} else {
_, err = w.WriteString("</details>")
}
+14 -9
View File
@@ -29,8 +29,8 @@ import (
)
var (
converter goldmark.Markdown
once = sync.Once{}
specMarkdown goldmark.Markdown
specMarkdownOnce sync.Once
)
var (
@@ -56,7 +56,7 @@ func (l *limitWriter) Write(data []byte) (int, error) {
if err != nil {
return n, err
}
return n, fmt.Errorf("Rendered content too large - truncating render")
return n, fmt.Errorf("rendered content too large - truncating render")
}
n, err := l.w.Write(data)
l.sum += int64(n)
@@ -73,10 +73,10 @@ func newParserContext(ctx *markup.RenderContext) parser.Context {
return pc
}
// actualRender renders Markdown to HTML without handling special links.
func actualRender(ctx *markup.RenderContext, input io.Reader, output io.Writer) error {
once.Do(func() {
converter = goldmark.New(
// SpecializedMarkdown sets up the Gitea specific markdown extensions
func SpecializedMarkdown() goldmark.Markdown {
specMarkdownOnce.Do(func() {
specMarkdown = goldmark.New(
goldmark.WithExtensions(
extension.NewTable(
extension.WithTableCellAlignMethod(extension.TableCellAlignAttribute)),
@@ -139,13 +139,18 @@ func actualRender(ctx *markup.RenderContext, input io.Reader, output io.Writer)
)
// Override the original Tasklist renderer!
converter.Renderer().AddOptions(
specMarkdown.Renderer().AddOptions(
renderer.WithNodeRenderers(
util.Prioritized(NewHTMLRenderer(), 10),
),
)
})
return specMarkdown
}
// actualRender renders Markdown to HTML without handling special links.
func actualRender(ctx *markup.RenderContext, input io.Reader, output io.Writer) error {
converter := SpecializedMarkdown()
lw := &limitWriter{
w: output,
limit: setting.UI.MaxDisplayFileSize * 3,
@@ -174,7 +179,7 @@ func actualRender(ctx *markup.RenderContext, input io.Reader, output io.Writer)
buf = giteautil.NormalizeEOL(buf)
rc := &RenderConfig{
Meta: "table",
Meta: renderMetaModeFromString(string(ctx.RenderMetaAs)),
Icon: "table",
Lang: "",
}
+39 -42
View File
@@ -7,32 +7,42 @@ import (
"fmt"
"strings"
"code.gitea.io/gitea/modules/markup"
"github.com/yuin/goldmark/ast"
"gopkg.in/yaml.v3"
)
// RenderConfig represents rendering configuration for this file
type RenderConfig struct {
Meta string
Meta markup.RenderMetaMode
Icon string
TOC bool
TOC string // "false": hide, "side"/empty: in sidebar, "main"/"true": in main view
Lang string
yamlNode *yaml.Node
}
func renderMetaModeFromString(s string) markup.RenderMetaMode {
switch strings.TrimSpace(strings.ToLower(s)) {
case "none":
return markup.RenderMetaAsNone
case "table":
return markup.RenderMetaAsTable
default: // "details"
return markup.RenderMetaAsDetails
}
}
// UnmarshalYAML implement yaml.v3 UnmarshalYAML
func (rc *RenderConfig) UnmarshalYAML(value *yaml.Node) error {
if rc == nil {
rc = &RenderConfig{
Meta: "table",
Icon: "table",
Lang: "",
}
return nil
}
rc.yamlNode = value
type commonRenderConfig struct {
TOC bool `yaml:"include_toc"`
TOC string `yaml:"include_toc"`
Lang string `yaml:"lang"`
}
var basic commonRenderConfig
@@ -54,58 +64,45 @@ func (rc *RenderConfig) UnmarshalYAML(value *yaml.Node) error {
if err := value.Decode(&stringBasic); err == nil {
if stringBasic.Gitea != "" {
switch strings.TrimSpace(strings.ToLower(stringBasic.Gitea)) {
case "none":
rc.Meta = "none"
case "table":
rc.Meta = "table"
default: // "details"
rc.Meta = "details"
}
rc.Meta = renderMetaModeFromString(stringBasic.Gitea)
}
return nil
}
type giteaControl struct {
type yamlRenderConfig struct {
Meta *string `yaml:"meta"`
Icon *string `yaml:"details_icon"`
TOC *bool `yaml:"include_toc"`
TOC *string `yaml:"include_toc"`
Lang *string `yaml:"lang"`
}
type complexGiteaConfig struct {
Gitea *giteaControl `yaml:"gitea"`
}
var complex complexGiteaConfig
if err := value.Decode(&complex); err != nil {
return fmt.Errorf("unable to decode into complexRenderConfig %w", err)
type yamlRenderConfigWrapper struct {
Gitea *yamlRenderConfig `yaml:"gitea"`
}
if complex.Gitea == nil {
var cfg yamlRenderConfigWrapper
if err := value.Decode(&cfg); err != nil {
return fmt.Errorf("unable to decode into yamlRenderConfigWrapper %w", err)
}
if cfg.Gitea == nil {
return nil
}
if complex.Gitea.Meta != nil {
switch strings.TrimSpace(strings.ToLower(*complex.Gitea.Meta)) {
case "none":
rc.Meta = "none"
case "table":
rc.Meta = "table"
default: // "details"
rc.Meta = "details"
}
if cfg.Gitea.Meta != nil {
rc.Meta = renderMetaModeFromString(*cfg.Gitea.Meta)
}
if complex.Gitea.Icon != nil {
rc.Icon = strings.TrimSpace(strings.ToLower(*complex.Gitea.Icon))
if cfg.Gitea.Icon != nil {
rc.Icon = strings.TrimSpace(strings.ToLower(*cfg.Gitea.Icon))
}
if complex.Gitea.Lang != nil && *complex.Gitea.Lang != "" {
rc.Lang = *complex.Gitea.Lang
if cfg.Gitea.Lang != nil && *cfg.Gitea.Lang != "" {
rc.Lang = *cfg.Gitea.Lang
}
if complex.Gitea.TOC != nil {
rc.TOC = *complex.Gitea.TOC
if cfg.Gitea.TOC != nil {
rc.TOC = *cfg.Gitea.TOC
}
return nil
@@ -116,9 +113,9 @@ func (rc *RenderConfig) toMetaNode() ast.Node {
return nil
}
switch rc.Meta {
case "table":
case markup.RenderMetaAsTable:
return nodeToTable(rc.yamlNode)
case "details":
case markup.RenderMetaAsDetails:
return nodeToDetails(rc.yamlNode, rc.Icon)
default:
return nil
+5 -5
View File
@@ -60,7 +60,7 @@ func TestRenderConfig_UnmarshalYAML(t *testing.T) {
},
{
"toc", &RenderConfig{
TOC: true,
TOC: "true",
Meta: "table",
Icon: "table",
Lang: "",
@@ -68,7 +68,7 @@ func TestRenderConfig_UnmarshalYAML(t *testing.T) {
},
{
"tocfalse", &RenderConfig{
TOC: false,
TOC: "false",
Meta: "table",
Icon: "table",
Lang: "",
@@ -78,7 +78,7 @@ func TestRenderConfig_UnmarshalYAML(t *testing.T) {
"toclang", &RenderConfig{
Meta: "table",
Icon: "table",
TOC: true,
TOC: "true",
Lang: "testlang",
}, `
include_toc: true
@@ -120,7 +120,7 @@ func TestRenderConfig_UnmarshalYAML(t *testing.T) {
"complex2", &RenderConfig{
Lang: "two",
Meta: "table",
TOC: true,
TOC: "true",
Icon: "smiley",
}, `
lang: one
@@ -155,7 +155,7 @@ func TestRenderConfig_UnmarshalYAML(t *testing.T) {
t.Errorf("Lang Expected %s Got %s", tt.expected.Lang, got.Lang)
}
if got.TOC != tt.expected.TOC {
t.Errorf("TOC Expected %t Got %t", tt.expected.TOC, got.TOC)
t.Errorf("TOC Expected %q Got %q", tt.expected.TOC, got.TOC)
}
})
}
+6 -2
View File
@@ -13,10 +13,14 @@ import (
"github.com/yuin/goldmark/ast"
)
func createTOCNode(toc []markup.Header, lang string) ast.Node {
func createTOCNode(toc []markup.Header, lang string, detailsAttrs map[string]string) ast.Node {
details := NewDetails()
summary := NewSummary()
for k, v := range detailsAttrs {
details.SetAttributeString(k, []byte(v))
}
summary.AppendChild(summary, ast.NewString([]byte(translation.NewLocale(lang).Tr("toc"))))
details.AppendChild(details, summary)
ul := ast.NewList('-')
@@ -40,7 +44,7 @@ func createTOCNode(toc []markup.Header, lang string) ast.Node {
}
li := ast.NewListItem(currentLevel * 2)
a := ast.NewLink()
a.Destination = []byte(fmt.Sprintf("#%s", url.PathEscape(header.ID)))
a.Destination = []byte(fmt.Sprintf("#%s", url.QueryEscape(header.ID)))
a.AppendChild(a, ast.NewString([]byte(header.Text)))
li.AppendChild(li, a)
ul.AppendChild(ul, li)
+12 -1
View File
@@ -16,6 +16,16 @@ import (
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/setting"
"github.com/yuin/goldmark/ast"
)
type RenderMetaMode string
const (
RenderMetaAsDetails RenderMetaMode = "details" // default
RenderMetaAsNone RenderMetaMode = "none"
RenderMetaAsTable RenderMetaMode = "table"
)
type ProcessorHelper struct {
@@ -63,7 +73,8 @@ type RenderContext struct {
GitRepo *git.Repository
ShaExistCache map[string]bool
cancelFn func()
TableOfContents []Header
SidebarTocNode ast.Node
RenderMetaAs RenderMetaMode
InStandalonePage bool // used by external render. the router "/org/repo/render/..." will output the rendered content in a standalone page
}
+27
View File
@@ -0,0 +1,27 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package private
import (
"context"
"code.gitea.io/gitea/modules/setting"
)
// Email structure holds a data for sending general emails
type GenerateTokenRequest struct {
Scope string
}
// GenerateActionsRunnerToken calls the internal GenerateActionsRunnerToken function
func GenerateActionsRunnerToken(ctx context.Context, scope string) (string, ResponseExtra) {
reqURL := setting.LocalURL + "api/internal/actions/generate_actions_runner_token"
req := newInternalRequest(ctx, reqURL, "POST", GenerateTokenRequest{
Scope: scope,
})
resp, extra := requestJSONResp(req, &responseText{})
return resp.Text, extra
}
+2 -1
View File
@@ -129,7 +129,8 @@ func SetDefaultBranch(ctx context.Context, ownerName, repoName, branch string) R
url.PathEscape(branch),
)
req := newInternalRequest(ctx, reqURL, "POST")
return requestJSONUserMsg(req, "")
_, extra := requestJSONResp(req, &responseText{})
return extra
}
// SSHLog sends ssh error log response
+3 -3
View File
@@ -30,8 +30,8 @@ type OrganizationPermissions struct {
// CreateOrgOption options for creating an organization
type CreateOrgOption struct {
// required: true
UserName string `json:"username" binding:"Required"`
FullName string `json:"full_name"`
UserName string `json:"username" binding:"Required;Username;MaxSize(40)"`
FullName string `json:"full_name" binding:"MaxSize(100)"`
Description string `json:"description" binding:"MaxSize(255)"`
Website string `json:"website" binding:"ValidUrl;MaxSize(255)"`
Location string `json:"location" binding:"MaxSize(50)"`
@@ -45,7 +45,7 @@ type CreateOrgOption struct {
// EditOrgOption options for editing an organization
type EditOrgOption struct {
FullName string `json:"full_name"`
FullName string `json:"full_name" binding:"MaxSize(100)"`
Description string `json:"description" binding:"MaxSize(255)"`
Website string `json:"website" binding:"ValidUrl;MaxSize(255)"`
Location string `json:"location" binding:"MaxSize(50)"`
-7
View File
@@ -171,13 +171,6 @@ func NewFuncMap() []template.FuncMap {
}
return false
},
"Iterate": func(arg interface{}) (items []int64) {
count, _ := util.ToInt64(arg)
for i := int64(0); i < count; i++ {
items = append(items, i)
}
return items
},
// -----------------------------------------------------------------
// setting