From e67d60d3368614c87b3d15ed9948fa17209bb120 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Wed, 22 Feb 2023 23:26:48 +0800 Subject: [PATCH 001/340] Fix some more hidden problems (#23074) (#23075) Backport #23074 --- templates/admin/auth/edit.tmpl | 2 +- templates/admin/user/edit.tmpl | 2 +- web_src/js/features/admin/common.js | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/templates/admin/auth/edit.tmpl b/templates/admin/auth/edit.tmpl index 36d335f32364..d64ee188af15 100644 --- a/templates/admin/auth/edit.tmpl +++ b/templates/admin/auth/edit.tmpl @@ -117,7 +117,7 @@ -
+
diff --git a/templates/admin/user/edit.tmpl b/templates/admin/user/edit.tmpl index 7d31eb4d2b9b..5dd1f531fda9 100644 --- a/templates/admin/user/edit.tmpl +++ b/templates/admin/user/edit.tmpl @@ -122,7 +122,7 @@
-
+
diff --git a/web_src/js/features/admin/common.js b/web_src/js/features/admin/common.js index 092cf770be41..d023e0bc3695 100644 --- a/web_src/js/features/admin/common.js +++ b/web_src/js/features/admin/common.js @@ -50,11 +50,11 @@ export function initAdminCommon() { function onUsePagedSearchChange() { if ($('#use_paged_search').prop('checked')) { - showElem($('.search-page-size')) - .find('input').attr('required', 'required'); + showElem('.search-page-size'); + $('.search-page-size').find('input').attr('required', 'required'); } else { - hideElem($('.search-page-size')) - .find('input').removeAttr('required'); + hideElem('.search-page-size'); + $('.search-page-size').find('input').removeAttr('required'); } } From 75eaf9907604b1689e491b4fb4354b2d0b9ac3b6 Mon Sep 17 00:00:00 2001 From: Yarden Shoham Date: Thu, 23 Feb 2023 02:34:47 +0200 Subject: [PATCH 002/340] Wrap unless-check in docker manifests (#23079) (#23081) Backport #23079 Should fix the following: > failed to render template: Evaluation error: Helper 'unless' called with wrong number of arguments, needed 2 but got 3 https://go.dev/play/p/h7bt7MWKTcv Signed-off-by: jolheiser Co-authored-by: John Olheiser --- docker/manifest.rootless.tmpl | 2 +- docker/manifest.tmpl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docker/manifest.rootless.tmpl b/docker/manifest.rootless.tmpl index 46a397c828d8..ef48dd1684b0 100644 --- a/docker/manifest.rootless.tmpl +++ b/docker/manifest.rootless.tmpl @@ -1,6 +1,6 @@ image: gitea/gitea:{{#if build.tag}}{{trimPrefix "v" build.tag}}{{else}}{{#if (hasPrefix "refs/heads/release/v" build.ref)}}{{trimPrefix "refs/heads/release/v" build.ref}}-{{/if}}dev{{/if}}-rootless {{#if build.tags}} -{{#unless contains "-rc" build.tag}} +{{#unless (contains "-rc" build.tag)}} tags: {{#each build.tags}} - {{this}}-rootless diff --git a/docker/manifest.tmpl b/docker/manifest.tmpl index b4ba5a76ed4a..018d87e9796b 100644 --- a/docker/manifest.tmpl +++ b/docker/manifest.tmpl @@ -1,6 +1,6 @@ image: gitea/gitea:{{#if build.tag}}{{trimPrefix "v" build.tag}}{{else}}{{#if (hasPrefix "refs/heads/release/v" build.ref)}}{{trimPrefix "refs/heads/release/v" build.ref}}-{{/if}}dev{{/if}} {{#if build.tags}} -{{#unless contains "-rc" build.tag }} +{{#unless (contains "-rc" build.tag)}} tags: {{#each build.tags}} - {{this}} From 0ac3be14829125f0c12be4e69195e6cb095353f4 Mon Sep 17 00:00:00 2001 From: Yarden Shoham Date: Thu, 23 Feb 2023 10:32:15 +0200 Subject: [PATCH 003/340] Improve accessibility for issue comments (#22612) (#23083) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Backport #22612 ### Preamble Gitea is an extremely great and smart solution perfectly suitable for smaller systems and self-hosted Git-powered setups. However, there is a group of people who have indredible difficulties in using Gitea, rendering it useless in many cases. Those people are blind developers using [screen readers](https://en.wikipedia.org/wiki/Screen_reader). Unfortunately, the frontend framework is super convoluted, and Go templates don’t allow accessibility improvements in a straightforward way. As a blind developer myself, I'm trying to start fixing smaller accessibility quirks with intention to go deeper and eventually, alone or not, make Gitea at least mostly accessible for screen reader users. ### What This Fix Does My blind fellows and me navigate webpages not very similarly to how a sighted person does it. For instance, we love semantic HTML markup like headings, lists, tables etc. because our screen readers allow us to jump by those landmarks with a single keypress. Currently in Gitea issue comments are not marked up with headings. I'm trying to fix this by adding an appropriate [ARIA](https://www.w3.org/WAI/standards-guidelines/aria/) role for comment header and also by enclosing the comment itself in a semantical article element. Co-authored-by: Andre Polykanine Co-authored-by: Lunny Xiao Co-authored-by: John Olheiser --- templates/repo/issue/view_content.tmpl | 6 +++--- templates/repo/issue/view_content/comments.tmpl | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/templates/repo/issue/view_content.tmpl b/templates/repo/issue/view_content.tmpl index 887dd2c42da8..08ba50904587 100644 --- a/templates/repo/issue/view_content.tmpl +++ b/templates/repo/issue/view_content.tmpl @@ -27,7 +27,7 @@ {{end}}
-
+
{{if .Issue.OriginalAuthor}} @@ -69,7 +69,7 @@ {{end}}
-
+
{{if .Issue.RenderedContent}} {{.Issue.RenderedContent|Str2html}} @@ -85,7 +85,7 @@
{{$reactions := .Issue.Reactions.GroupByType}} {{if $reactions}} -
+
{{template "repo/issue/view_content/reactions" Dict "ctx" $ "ActionURL" (Printf "%s/issues/%d/reactions" $.RepoLink .Issue.Index) "Reactions" $reactions}}
{{end}} diff --git a/templates/repo/issue/view_content/comments.tmpl b/templates/repo/issue/view_content/comments.tmpl index 8894a7ffd206..94b46bd9f13a 100644 --- a/templates/repo/issue/view_content/comments.tmpl +++ b/templates/repo/issue/view_content/comments.tmpl @@ -22,7 +22,7 @@ {{end}}
-
+
{{if .OriginalAuthor}} @@ -69,7 +69,7 @@ {{end}}
-
+
{{if .RenderedContent}} {{.RenderedContent|Str2html}} @@ -85,7 +85,7 @@
{{$reactions := .Reactions.GroupByType}} {{if $reactions}} -
+
{{template "repo/issue/view_content/reactions" Dict "ctx" $ "ActionURL" (Printf "%s/comments/%d/reactions" $.RepoLink .ID) "Reactions" $reactions}}
{{end}} From aff432b1976de68abe4b266bd322ddd57cbeed42 Mon Sep 17 00:00:00 2001 From: Yarden Shoham Date: Thu, 23 Feb 2023 10:39:30 +0200 Subject: [PATCH 004/340] Nest metadata in refactoring docs (#23087) (#23091) Backport #23087 Whitespace was missing from refactoring docs metadata. backport label applied so it is included in versioned docs. Co-authored-by: techknowlogick --- .../doc/developers/guidelines-refactoring.en-us.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/content/doc/developers/guidelines-refactoring.en-us.md b/docs/content/doc/developers/guidelines-refactoring.en-us.md index 2d607720dcb8..29025f25f752 100644 --- a/docs/content/doc/developers/guidelines-refactoring.en-us.md +++ b/docs/content/doc/developers/guidelines-refactoring.en-us.md @@ -6,11 +6,11 @@ weight: 20 toc: false draft: false menu: -sidebar: -parent: "developers" -name: "Guidelines for Refactoring" -weight: 20 -identifier: "guidelines-refactoring" + sidebar: + parent: "developers" + name: "Guidelines for Refactoring" + weight: 20 + identifier: "guidelines-refactoring" --- # Guidelines for Refactoring From ced94f2e0df249d1779f349e11922bfad61cba67 Mon Sep 17 00:00:00 2001 From: HesterG Date: Thu, 23 Feb 2023 20:56:03 +0800 Subject: [PATCH 005/340] Add accessibility to the menu on the navbar (#23059) (#23095) Backport #23059 This PR is trying to add accessibility to the menu as mentioned in #23053 so the menu can be accessed using keyboard (A quick demo is added below), with a reference to [PR2612](https://github.com/go-gitea/gitea/pull/22612). The goal is to make the menu accessible merely using keyboard like shown below. And this PR might need confirmation from developers using screen readers. --- templates/base/head_navbar.tmpl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/base/head_navbar.tmpl b/templates/base/head_navbar.tmpl index 059363b72d07..10bbf655b5b9 100644 --- a/templates/base/head_navbar.tmpl +++ b/templates/base/head_navbar.tmpl @@ -18,9 +18,9 @@ {{end}} - +
From b4ed3f07e44975e971dcbbf1afcdedbf874c0820 Mon Sep 17 00:00:00 2001 From: Yarden Shoham Date: Fri, 24 Feb 2023 02:47:35 +0200 Subject: [PATCH 006/340] Fix commit name in Apply Patch page (#23086) (#23099) Backport #23086 Fixes https://github.com/go-gitea/gitea/issues/22621#issuecomment-1439309200 Co-authored-by: yp05327 <576951401@qq.com> --- routers/web/repo/patch.go | 3 +++ templates/repo/editor/commit_form.tmpl | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/routers/web/repo/patch.go b/routers/web/repo/patch.go index 12b26f38e901..0ffec0c4ea46 100644 --- a/routers/web/repo/patch.go +++ b/routers/web/repo/patch.go @@ -25,6 +25,8 @@ const ( func NewDiffPatch(ctx *context.Context) { canCommit := renderCommitRights(ctx) + ctx.Data["PageIsPatch"] = true + ctx.Data["TreePath"] = "" ctx.Data["commit_summary"] = "" @@ -51,6 +53,7 @@ func NewDiffPatchPost(ctx *context.Context) { if form.CommitChoice == frmCommitChoiceNewBranch { branchName = form.NewBranchName } + ctx.Data["PageIsPatch"] = true ctx.Data["TreePath"] = "" ctx.Data["BranchLink"] = ctx.Repo.RepoLink + "/src/" + ctx.Repo.BranchNameSubURL() ctx.Data["FileContent"] = form.Content diff --git a/templates/repo/editor/commit_form.tmpl b/templates/repo/editor/commit_form.tmpl index 7fac7f13bc24..c6c48c5a838c 100644 --- a/templates/repo/editor/commit_form.tmpl +++ b/templates/repo/editor/commit_form.tmpl @@ -9,7 +9,7 @@ {{.locale.Tr "repo.editor.commit_changes"}} {{- end}}
- +
From ddf61373f691a584844f141bc4728948fe142dc3 Mon Sep 17 00:00:00 2001 From: Yarden Shoham Date: Fri, 24 Feb 2023 04:45:18 +0200 Subject: [PATCH 007/340] Add wrapper to author to avoid long name ui problem (#23030) (#23098) Backport #23030 This PR is a possible solution for issue #22866. Main change is to add a `author-wrapper` class around author name, like the wrapper added to message. The `max-width` is set to 200px on PC, and 100px on mobile device for now. Which will work like below: 2023-02-21 11 57 53 2023-02-21 11 58 43 And `title` is added to the wrapper like it did in message wrapper. So the full author name will show on hover. Co-authored-by: HesterG Co-authored-by: Lunny Xiao --- templates/repo/view_list.tmpl | 6 +++--- web_src/less/_repository.less | 19 +++++++++++++++---- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/templates/repo/view_list.tmpl b/templates/repo/view_list.tmpl index 6fcf60daef13..9540c872c2c5 100644 --- a/templates/repo/view_list.tmpl +++ b/templates/repo/view_list.tmpl @@ -8,14 +8,14 @@ {{if .LatestCommitUser}} {{avatar $.Context .LatestCommitUser 24}} {{if .LatestCommitUser.FullName}} - {{.LatestCommitUser.FullName}} + {{.LatestCommitUser.FullName}} {{else}} - {{if .LatestCommit.Author}}{{.LatestCommit.Author.Name}}{{else}}{{.LatestCommitUser.Name}}{{end}} + {{if .LatestCommit.Author}}{{.LatestCommit.Author.Name}}{{else}}{{.LatestCommitUser.Name}}{{end}} {{end}} {{else}} {{if .LatestCommit.Author}} {{avatarByEmail $.Context .LatestCommit.Author.Email .LatestCommit.Author.Name 24}} - {{.LatestCommit.Author.Name}} + {{.LatestCommit.Author.Name}} {{end}} {{end}} diff --git a/web_src/less/_repository.less b/web_src/less/_repository.less index 627a5f6c2f6d..83e8e1f338e1 100644 --- a/web_src/less/_repository.less +++ b/web_src/less/_repository.less @@ -237,6 +237,8 @@ } #repo-files-table { + table-layout: fixed; + thead { th { padding-top: 8px; @@ -2885,7 +2887,8 @@ tbody.commit-list { vertical-align: baseline; } -.message-wrapper { +.message-wrapper, +.author-wrapper { overflow: hidden; text-overflow: ellipsis; max-width: calc(100% - 50px); @@ -2893,6 +2896,10 @@ tbody.commit-list { vertical-align: middle; } +.author-wrapper { + max-width: 180px; +} + // in the commit list, messages can wrap so we can use inline .commit-list .message-wrapper { display: inline; @@ -2912,6 +2919,10 @@ tbody.commit-list { display: block; max-width: calc(100vw - 70px); } + + .author-wrapper { + max-width: 80px; + } } @media @mediaMd { @@ -2920,7 +2931,7 @@ tbody.commit-list { } th .message-wrapper { - max-width: 280px; + max-width: 120px; } } @@ -2930,7 +2941,7 @@ tbody.commit-list { } th .message-wrapper { - max-width: 490px; + max-width: 350px; } } @@ -2940,7 +2951,7 @@ tbody.commit-list { } th .message-wrapper { - max-width: 680px; + max-width: 525px; } } From 4d3e2b23b86f5be8eaf649980ed3fa81b5997e3b Mon Sep 17 00:00:00 2001 From: Yarden Shoham Date: Fri, 24 Feb 2023 08:36:25 +0200 Subject: [PATCH 008/340] Fix SyncOnCommit always return false in API of push_mirrors (#23088) (#23100) Backport #23088 Fix: #22990 --- Before, the return value of the api is always false,regrardless of whether the entry of `sync_on_commit` is true or false. I have confirmed that the value of `sync_on_commit` dropped into the database is correct. So, I think it is enough to make some small changes. Co-authored-by: sillyguodong <33891828+sillyguodong@users.noreply.github.com> Co-authored-by: Lunny Xiao --- services/convert/mirror.go | 1 + 1 file changed, 1 insertion(+) diff --git a/services/convert/mirror.go b/services/convert/mirror.go index 1dcfc9b64dcf..f7a8e17fd0c9 100644 --- a/services/convert/mirror.go +++ b/services/convert/mirror.go @@ -24,6 +24,7 @@ func ToPushMirror(pm *repo_model.PushMirror) (*api.PushMirror, error) { LastUpdateUnix: pm.LastUpdateUnix.FormatLong(), LastError: pm.LastError, Interval: pm.Interval.String(), + SyncOnCommit: pm.SyncOnCommit, }, nil } From 5ddf67a9c2325282a2121672d7d7ea77789e2cf8 Mon Sep 17 00:00:00 2001 From: Yarden Shoham Date: Fri, 24 Feb 2023 11:40:36 +0200 Subject: [PATCH 009/340] Make issue meta dropdown support Enter, confirm before reloading (#23014) (#23102) Backport #23014 As the title. Label/assignee share the same code. * Close #22607 * Close #20727 Also: * partially fix for #21742, now the comment reaction and menu work with keyboard. * partially fix for #17705, in most cases the comment won't be lost. * partially fix for #21539 * partially fix for #20347 * partially fix for #7329 ### The `Enter` support Before, if user presses Enter, the dropdown just disappears and nothing happens or the window reloads. After, Enter can be used to select/deselect labels, and press Esc to hide the dropdown to update the labels (still no way to cancel .... maybe you can do a Cmd+R or F5 to refresh the window to discard the changes .....) This is only a quick patch, the UX is still not perfect, but it's much better than before. ### The `confirm` before reloading And more fixes for the `reload` problem, the new behaviors: * If nothing changes (just show/hide the dropdown), then the page won't be reloaded. * If there are draft comments, show a confirm dialog before reloading, to avoid losing comments. That's the best effect can be done at the moment, unless completely refactor these dropdown related code. Screenshot of the confirm dialog:
![image](https://user-images.githubusercontent.com/2114189/220538288-e2da8459-6a4e-43cb-8596-74057f8a03a2.png)
Co-authored-by: wxiaoguang Co-authored-by: Brecht Van Lommel Co-authored-by: Lunny Xiao --- .../repo/issue/view_content/add_reaction.tmpl | 2 +- .../repo/issue/view_content/context_menu.tmpl | 10 ++-- .../repo/issue/view_content/sidebar.tmpl | 2 +- web_src/js/features/aria.js | 3 +- web_src/js/features/repo-legacy.js | 49 ++++++++++++++----- 5 files changed, 46 insertions(+), 20 deletions(-) diff --git a/templates/repo/issue/view_content/add_reaction.tmpl b/templates/repo/issue/view_content/add_reaction.tmpl index 9bd9022d28ab..bfa8a7e12234 100644 --- a/templates/repo/issue/view_content/add_reaction.tmpl +++ b/templates/repo/issue/view_content/add_reaction.tmpl @@ -7,7 +7,7 @@
{{.ctx.locale.Tr "repo.pick_reaction"}}
{{range $value := AllowedReactions}} -
{{ReactionToEmoji $value}}
+
{{ReactionToEmoji $value}} {{end}}
diff --git a/templates/repo/issue/view_content/context_menu.tmpl b/templates/repo/issue/view_content/context_menu.tmpl index b96fd86af5d0..b4b9403b2af7 100644 --- a/templates/repo/issue/view_content/context_menu.tmpl +++ b/templates/repo/issue/view_content/context_menu.tmpl @@ -10,16 +10,16 @@ {{else}} {{$referenceUrl = Printf "%s/files#%s" .ctx.Issue.Link .item.HashTag}} {{end}} -
{{.ctx.locale.Tr "repo.issues.context.copy_link"}}
-
{{.ctx.locale.Tr "repo.issues.context.quote_reply"}}
+ {{.ctx.locale.Tr "repo.issues.context.copy_link"}} + {{.ctx.locale.Tr "repo.issues.context.quote_reply"}} {{if not .ctx.UnitIssuesGlobalDisabled}} -
{{.ctx.locale.Tr "repo.issues.context.reference_issue"}}
+ {{.ctx.locale.Tr "repo.issues.context.reference_issue"}} {{end}} {{if or .ctx.Permission.IsAdmin .IsCommentPoster .ctx.HasIssuesOrPullsWritePermission}}
-
{{.ctx.locale.Tr "repo.issues.context.edit"}}
+ {{.ctx.locale.Tr "repo.issues.context.edit"}} {{if .delete}} -
{{.ctx.locale.Tr "repo.issues.context.delete"}}
+ {{.ctx.locale.Tr "repo.issues.context.delete"}} {{end}} {{end}}
diff --git a/templates/repo/issue/view_content/sidebar.tmpl b/templates/repo/issue/view_content/sidebar.tmpl index 2b24825b5f7b..d9c506243705 100644 --- a/templates/repo/issue/view_content/sidebar.tmpl +++ b/templates/repo/issue/view_content/sidebar.tmpl @@ -121,7 +121,7 @@
{{end}} -
{{.locale.Tr "repo.issues.new.clear_labels"}}
+ {{.locale.Tr "repo.issues.new.clear_labels"}} {{if or .Labels .OrgLabels}} {{$previousExclusiveScope := "_no_scope"}} {{range .Labels}} diff --git a/web_src/js/features/aria.js b/web_src/js/features/aria.js index a5ac84e4464c..373d667c5f73 100644 --- a/web_src/js/features/aria.js +++ b/web_src/js/features/aria.js @@ -81,7 +81,8 @@ function attachOneDropdownAria($dropdown) { $dropdown.on('keydown', (e) => { // here it must use keydown event before dropdown's keyup handler, otherwise there is no Enter event in our keyup handler if (e.key === 'Enter') { - const $item = $dropdown.dropdown('get item', $dropdown.dropdown('get value')); + let $item = $dropdown.dropdown('get item', $dropdown.dropdown('get value')); + if (!$item) $item = $menu.find('> .item.selected'); // when dropdown filters items by input, there is no "value", so query the "selected" item // if the selected item is clickable, then trigger the click event. in the future there could be a special CSS class for it. if ($item && $item.is('a')) $item[0].click(); } diff --git a/web_src/js/features/repo-legacy.js b/web_src/js/features/repo-legacy.js index 8178ed6547f0..a9229c0d1e6f 100644 --- a/web_src/js/features/repo-legacy.js +++ b/web_src/js/features/repo-legacy.js @@ -29,6 +29,26 @@ import {hideElem, showElem} from '../utils/dom.js'; const {csrfToken} = window.config; +// if there are draft comments (more than 20 chars), confirm before reloading, to avoid losing comments +function reloadConfirmDraftComment() { + const commentTextareas = [ + document.querySelector('.edit-content-zone:not(.gt-hidden) textarea'), + document.querySelector('.edit_area'), + ]; + for (const textarea of commentTextareas) { + // Most users won't feel too sad if they lose a comment with 10 or 20 chars, they can re-type these in seconds. + // But if they have typed more (like 50) chars and the comment is lost, they will be very unhappy. + if (textarea && textarea.value.trim().length > 20) { + textarea.parentElement.scrollIntoView(); + if (!window.confirm('Page will be reloaded, but there are draft comments. Continuing to reload will discard the comments. Continue?')) { + return; + } + break; + } + } + window.location.reload(); +} + export function initRepoCommentForm() { const $commentForm = $('.comment.form'); if ($commentForm.length === 0) { @@ -86,12 +106,15 @@ export function initRepoCommentForm() { let hasUpdateAction = $listMenu.data('action') === 'update'; const items = {}; - $(`.${selector}`).dropdown('setting', 'onHide', () => { - hasUpdateAction = $listMenu.data('action') === 'update'; // Update the var - if (hasUpdateAction) { - // TODO: Add batch functionality and make this 1 network request. - (async function() { - for (const [elementId, item] of Object.entries(items)) { + $(`.${selector}`).dropdown({ + 'action': 'nothing', // do not hide the menu if user presses Enter + fullTextSearch: 'exact', + async onHide() { + hasUpdateAction = $listMenu.data('action') === 'update'; // Update the var + if (hasUpdateAction) { + // TODO: Add batch functionality and make this 1 network request. + const itemEntries = Object.entries(items); + for (const [elementId, item] of itemEntries) { await updateIssuesMeta( item['update-url'], item.action, @@ -99,9 +122,11 @@ export function initRepoCommentForm() { elementId, ); } - window.location.reload(); - })(); - } + if (itemEntries.length) { + reloadConfirmDraftComment(); + } + } + }, }); $listMenu.find('.item:not(.no-select)').on('click', function (e) { @@ -196,7 +221,7 @@ export function initRepoCommentForm() { 'clear', $listMenu.data('issue-id'), '', - ).then(() => window.location.reload()); + ).then(reloadConfirmDraftComment); } $(this).parent().find('.item').each(function () { @@ -239,7 +264,7 @@ export function initRepoCommentForm() { '', $menu.data('issue-id'), $(this).data('id'), - ).then(() => window.location.reload()); + ).then(reloadConfirmDraftComment); } let icon = ''; @@ -272,7 +297,7 @@ export function initRepoCommentForm() { '', $menu.data('issue-id'), $(this).data('id'), - ).then(() => window.location.reload()); + ).then(reloadConfirmDraftComment); } $list.find('.selected').html(''); From e02e752f688d8822d0da6e824f303f3819195eb9 Mon Sep 17 00:00:00 2001 From: Yarden Shoham Date: Fri, 24 Feb 2023 15:17:03 +0200 Subject: [PATCH 010/340] Fix nil context in RenderMarkdownToHtml (#23092) (#23108) Backport #23092 Fix #23082. This bug is caused by a nil context in https://github.com/go-gitea/gitea/issues/23082#issuecomment-1441276546 . Co-authored-by: Zettat123 Co-authored-by: Lunny Xiao --- modules/templates/helper.go | 3 ++- templates/package/content/cargo.tmpl | 2 +- templates/package/content/chef.tmpl | 2 +- templates/package/content/npm.tmpl | 2 +- templates/package/content/pub.tmpl | 2 +- templates/package/content/pypi.tmpl | 4 ++-- templates/repo/issue/comment_tab.tmpl | 10 +++++----- templates/repo/issue/fields/checkboxes.tmpl | 2 +- templates/repo/issue/fields/dropdown.tmpl | 6 +++--- templates/repo/issue/fields/header.tmpl | 8 ++++---- templates/repo/issue/fields/input.tmpl | 2 +- templates/repo/issue/fields/markdown.tmpl | 2 +- templates/repo/issue/fields/textarea.tmpl | 2 +- 13 files changed, 24 insertions(+), 23 deletions(-) diff --git a/modules/templates/helper.go b/modules/templates/helper.go index 4ffd0a5dee03..b7bd07670cf7 100644 --- a/modules/templates/helper.go +++ b/modules/templates/helper.go @@ -174,8 +174,9 @@ func NewFuncMap() []template.FuncMap { "RenderEmojiPlain": emoji.ReplaceAliases, "ReactionToEmoji": ReactionToEmoji, "RenderNote": RenderNote, - "RenderMarkdownToHtml": func(input string) template.HTML { + "RenderMarkdownToHtml": func(ctx context.Context, input string) template.HTML { output, err := markdown.RenderString(&markup.RenderContext{ + Ctx: ctx, URLPrefix: setting.AppSubURL, }, input) if err != nil { diff --git a/templates/package/content/cargo.tmpl b/templates/package/content/cargo.tmpl index f78647ca69c6..410a81d9017a 100644 --- a/templates/package/content/cargo.tmpl +++ b/templates/package/content/cargo.tmpl @@ -26,7 +26,7 @@ git-fetch-with-cli = true
{{if or .PackageDescriptor.Metadata.Description .PackageDescriptor.Metadata.Readme}}

{{.locale.Tr "packages.about"}}

{{if .PackageDescriptor.Metadata.Description}}
{{.PackageDescriptor.Metadata.Description}}
{{end}} - {{if .PackageDescriptor.Metadata.Readme}}
{{RenderMarkdownToHtml .PackageDescriptor.Metadata.Readme}}
{{end}} + {{if .PackageDescriptor.Metadata.Readme}}
{{RenderMarkdownToHtml $.Context .PackageDescriptor.Metadata.Readme}}
{{end}} {{end}} {{if .PackageDescriptor.Metadata.Dependencies}} diff --git a/templates/package/content/chef.tmpl b/templates/package/content/chef.tmpl index edc175f9bedd..d80ecdf40317 100644 --- a/templates/package/content/chef.tmpl +++ b/templates/package/content/chef.tmpl @@ -20,7 +20,7 @@

{{.locale.Tr "packages.about"}}

{{if .PackageDescriptor.Metadata.Description}}

{{.PackageDescriptor.Metadata.Description}}

{{end}} - {{if .PackageDescriptor.Metadata.LongDescription}}{{RenderMarkdownToHtml .PackageDescriptor.Metadata.LongDescription}}{{end}} + {{if .PackageDescriptor.Metadata.LongDescription}}{{RenderMarkdownToHtml $.Context .PackageDescriptor.Metadata.LongDescription}}{{end}}
{{end}} diff --git a/templates/package/content/npm.tmpl b/templates/package/content/npm.tmpl index ea514c5263ad..d0c037b38a6d 100644 --- a/templates/package/content/npm.tmpl +++ b/templates/package/content/npm.tmpl @@ -25,7 +25,7 @@
{{if .PackageDescriptor.Metadata.Readme}}
- {{RenderMarkdownToHtml .PackageDescriptor.Metadata.Readme}} + {{RenderMarkdownToHtml $.Context .PackageDescriptor.Metadata.Readme}}
{{else if .PackageDescriptor.Metadata.Description}} {{.PackageDescriptor.Metadata.Description}} diff --git a/templates/package/content/pub.tmpl b/templates/package/content/pub.tmpl index e81439d4daec..d5676fca5a5d 100644 --- a/templates/package/content/pub.tmpl +++ b/templates/package/content/pub.tmpl @@ -14,6 +14,6 @@ {{if or .PackageDescriptor.Metadata.Description .PackageDescriptor.Metadata.Readme}}

{{.locale.Tr "packages.about"}}

{{if .PackageDescriptor.Metadata.Description}}
{{.PackageDescriptor.Metadata.Description}}
{{end}} - {{if .PackageDescriptor.Metadata.Readme}}
{{RenderMarkdownToHtml .PackageDescriptor.Metadata.Readme}}
{{end}} + {{if .PackageDescriptor.Metadata.Readme}}
{{RenderMarkdownToHtml $.Context .PackageDescriptor.Metadata.Readme}}
{{end}} {{end}} {{end}} diff --git a/templates/package/content/pypi.tmpl b/templates/package/content/pypi.tmpl index 830ba9bd67e5..8dbed5395ebd 100644 --- a/templates/package/content/pypi.tmpl +++ b/templates/package/content/pypi.tmpl @@ -16,9 +16,9 @@

{{if .PackageDescriptor.Metadata.Summary}}{{.PackageDescriptor.Metadata.Summary}}{{end}}

{{if .PackageDescriptor.Metadata.LongDescription}} - {{RenderMarkdownToHtml .PackageDescriptor.Metadata.LongDescription}} + {{RenderMarkdownToHtml $.Context .PackageDescriptor.Metadata.LongDescription}} {{else if .PackageDescriptor.Metadata.Description}} - {{RenderMarkdownToHtml .PackageDescriptor.Metadata.Description}} + {{RenderMarkdownToHtml $.Context .PackageDescriptor.Metadata.Description}} {{end}}
{{end}} diff --git a/templates/repo/issue/comment_tab.tmpl b/templates/repo/issue/comment_tab.tmpl index 86efa8c833b0..b04a3c6bbbb4 100644 --- a/templates/repo/issue/comment_tab.tmpl +++ b/templates/repo/issue/comment_tab.tmpl @@ -2,15 +2,15 @@ {{range .Fields}} {{if eq .Type "input"}} - {{template "repo/issue/fields/input" .}} + {{template "repo/issue/fields/input" Dict "Context" $.Context "item" .}} {{else if eq .Type "markdown"}} - {{template "repo/issue/fields/markdown" .}} + {{template "repo/issue/fields/markdown" Dict "Context" $.Context "item" .}} {{else if eq .Type "textarea"}} - {{template "repo/issue/fields/textarea" .}} + {{template "repo/issue/fields/textarea" Dict "Context" $.Context "item" .}} {{else if eq .Type "dropdown"}} - {{template "repo/issue/fields/dropdown" .}} + {{template "repo/issue/fields/dropdown" Dict "Context" $.Context "item" .}} {{else if eq .Type "checkboxes"}} - {{template "repo/issue/fields/checkboxes" .}} + {{template "repo/issue/fields/checkboxes" Dict "Context" $.Context "item" .}} {{end}} {{end}} {{else}} diff --git a/templates/repo/issue/fields/checkboxes.tmpl b/templates/repo/issue/fields/checkboxes.tmpl index b70334681f22..80835b649a50 100644 --- a/templates/repo/issue/fields/checkboxes.tmpl +++ b/templates/repo/issue/fields/checkboxes.tmpl @@ -1,7 +1,7 @@
{{template "repo/issue/fields/header" .}} {{$field := .}} - {{range $i, $opt := .Attributes.options}} + {{range $i, $opt := .item.Attributes.options}}
diff --git a/templates/repo/issue/fields/dropdown.tmpl b/templates/repo/issue/fields/dropdown.tmpl index 83c2bb4aac89..9adce5602f9a 100644 --- a/templates/repo/issue/fields/dropdown.tmpl +++ b/templates/repo/issue/fields/dropdown.tmpl @@ -1,12 +1,12 @@
{{template "repo/issue/fields/header" .}} {{/* FIXME: required validation */}} - diff --git a/web_src/js/components/DashboardRepoList.js b/web_src/js/components/DashboardRepoList.js index 0a009e78d151..2328cc83a90c 100644 --- a/web_src/js/components/DashboardRepoList.js +++ b/web_src/js/components/DashboardRepoList.js @@ -87,6 +87,7 @@ function initVueComponents(app) { } return { + hasMounted: false, // accessing $refs in computed() need to wait for mounted tab, repos: [], reposTotalCount: 0, @@ -134,7 +135,19 @@ function initVueComponents(app) { }, repoTypeCount() { return this.counts[`${this.reposFilter}:${this.archivedFilter}:${this.privateFilter}`]; - } + }, + checkboxArchivedFilterTitle() { + return this.hasMounted && this.$refs.checkboxArchivedFilter?.getAttribute(`data-title-${this.archivedFilter}`); + }, + checkboxArchivedFilterProps() { + return {checked: this.archivedFilter === 'archived', indeterminate: this.archivedFilter === 'both'}; + }, + checkboxPrivateFilterTitle() { + return this.hasMounted && this.$refs.checkboxPrivateFilter?.getAttribute(`data-title-${this.privateFilter}`); + }, + checkboxPrivateFilterProps() { + return {checked: this.privateFilter === 'private', indeterminate: this.privateFilter === 'both'}; + }, }, mounted() { @@ -144,10 +157,11 @@ function initVueComponents(app) { initTooltip(elTooltip); } $(el).find('.dropdown').dropdown(); - this.setCheckboxes(); nextTick(() => { this.$refs.search.focus(); }); + + this.hasMounted = true; }, methods: { @@ -156,39 +170,6 @@ function initVueComponents(app) { this.updateHistory(); }, - setCheckboxes() { - switch (this.archivedFilter) { - case 'unarchived': - $('#archivedFilterCheckbox').checkbox('set unchecked'); - break; - case 'archived': - $('#archivedFilterCheckbox').checkbox('set checked'); - break; - case 'both': - $('#archivedFilterCheckbox').checkbox('set indeterminate'); - break; - default: - this.archivedFilter = 'unarchived'; - $('#archivedFilterCheckbox').checkbox('set unchecked'); - break; - } - switch (this.privateFilter) { - case 'public': - $('#privateFilterCheckbox').checkbox('set unchecked'); - break; - case 'private': - $('#privateFilterCheckbox').checkbox('set checked'); - break; - case 'both': - $('#privateFilterCheckbox').checkbox('set indeterminate'); - break; - default: - this.privateFilter = 'both'; - $('#privateFilterCheckbox').checkbox('set indeterminate'); - break; - } - }, - changeReposFilter(filter) { this.reposFilter = filter; this.repos = []; @@ -245,45 +226,29 @@ function initVueComponents(app) { }, toggleArchivedFilter() { - switch (this.archivedFilter) { - case 'both': - this.archivedFilter = 'unarchived'; - break; - case 'unarchived': - this.archivedFilter = 'archived'; - break; - case 'archived': - this.archivedFilter = 'both'; - break; - default: - this.archivedFilter = 'unarchived'; - break; + if (this.archivedFilter === 'unarchived') { + this.archivedFilter = 'archived'; + } else if (this.archivedFilter === 'archived') { + this.archivedFilter = 'both'; + } else { // including both + this.archivedFilter = 'unarchived'; } this.page = 1; this.repos = []; - this.setCheckboxes(); this.counts[`${this.reposFilter}:${this.archivedFilter}:${this.privateFilter}`] = 0; this.searchRepos(); }, togglePrivateFilter() { - switch (this.privateFilter) { - case 'both': - this.privateFilter = 'public'; - break; - case 'public': - this.privateFilter = 'private'; - break; - case 'private': - this.privateFilter = 'both'; - break; - default: - this.privateFilter = 'both'; - break; + if (this.privateFilter === 'both') { + this.privateFilter = 'public'; + } else if (this.privateFilter === 'public') { + this.privateFilter = 'private'; + } else { // including private + this.privateFilter = 'both'; } this.page = 1; this.repos = []; - this.setCheckboxes(); this.counts[`${this.reposFilter}:${this.archivedFilter}:${this.privateFilter}`] = 0; this.searchRepos(); }, From 9843a0b741ae3690cd56bdad538f2cf35ccb2903 Mon Sep 17 00:00:00 2001 From: Giteabot Date: Thu, 2 Mar 2023 11:47:07 -0500 Subject: [PATCH 033/340] Close the temp file when dumping database to make the temp file can be deleted on Windows (#23249) (#23251) Backport #23249 There was no `dbDump.Close()` before, Windows doesn't like to delete opened files. Co-authored-by: wxiaoguang --- cmd/dump.go | 1 + 1 file changed, 1 insertion(+) diff --git a/cmd/dump.go b/cmd/dump.go index c879d2fbee07..600ec4f32eb0 100644 --- a/cmd/dump.go +++ b/cmd/dump.go @@ -272,6 +272,7 @@ func runDump(ctx *cli.Context) error { fatal("Failed to create tmp file: %v", err) } defer func() { + _ = dbDump.Close() if err := util.Remove(dbDump.Name()); err != nil { log.Warn("Unable to remove temporary file: %s: Error: %v", dbDump.Name(), err) } From f8a40dafb946da1eb28ccf6e18de2a151de420fc Mon Sep 17 00:00:00 2001 From: Giteabot Date: Thu, 2 Mar 2023 11:49:05 -0500 Subject: [PATCH 034/340] Allow `
-
+
@@ -62,12 +62,12 @@
-
+
-
+
diff --git a/templates/repo/editor/commit_form.tmpl b/templates/repo/editor/commit_form.tmpl index c6c48c5a838c..7ac0ed3df19f 100644 --- a/templates/repo/editor/commit_form.tmpl +++ b/templates/repo/editor/commit_form.tmpl @@ -58,7 +58,7 @@
-
+
{{svg "octicon-git-branch"}} From 9309098eab6446df0de625dfc2ec67936bdbb0f9 Mon Sep 17 00:00:00 2001 From: Giteabot Date: Thu, 2 Mar 2023 15:05:10 -0500 Subject: [PATCH 036/340] Fix switched citation format (#23250) (#23253) Backport #23250 Due to switched input parameters, the citation texts for Bibtex and Apa were switched. This pull request fixes #23244 Co-authored-by: Blender Defender --- web_src/js/features/citation.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web_src/js/features/citation.js b/web_src/js/features/citation.js index 38288456248d..c40b1adddd14 100644 --- a/web_src/js/features/citation.js +++ b/web_src/js/features/citation.js @@ -2,7 +2,7 @@ import $ from 'jquery'; const {pageData} = window.config; -const initInputCitationValue = async ($citationCopyBibtex, $citationCopyApa) => { +const initInputCitationValue = async ($citationCopyApa, $citationCopyBibtex) => { const [{Cite, plugins}] = await Promise.all([ import(/* webpackChunkName: "citation-js-core" */'@citation-js/core'), import(/* webpackChunkName: "citation-js-formats" */'@citation-js/plugin-software-formats'), From ef8209a953e7af14c1ee5c68678c2da959f511fb Mon Sep 17 00:00:00 2001 From: Giteabot Date: Thu, 2 Mar 2023 17:36:21 -0500 Subject: [PATCH 037/340] Use async await to fix empty quote reply at first time (#23168) (#23256) Backport #23168 The reason why quote reply is empty is when quote reply is clicked, it triggers the click function on `.comment-form-reply` button, and when the first time this function is triggered, easyMDE for the reply has not yet initialized, so that click handler of `.quote-reply` button in `repo-legacy.js` got an `undefined` as easyMDE, and the following lines which put quoted reply into the easyMDE is not executed. The workaround in this PR is to pass the replied content to '.comment-form-reply' button if easyMDE is not yet initialized (quote reply first clicked) and put the replied content into it the after easyMDE is created. Now quote reply on first click: https://user-images.githubusercontent.com/17645053/221452823-fc699d50-1649-4af1-952e-f04fc8d2978e.mov
Update: The above change is not appropriate as stated in the [comment](https://github.com/go-gitea/gitea/pull/23168#issuecomment-1445562284) Use await instead Close #22075. Close #23247. Co-authored-by: HesterG --- web_src/js/features/repo-issue.js | 30 +++++++++++++++++------------- web_src/js/features/repo-legacy.js | 11 +++++------ 2 files changed, 22 insertions(+), 19 deletions(-) diff --git a/web_src/js/features/repo-issue.js b/web_src/js/features/repo-issue.js index 4fc8bb5e62d9..4163fb120e52 100644 --- a/web_src/js/features/repo-issue.js +++ b/web_src/js/features/repo-issue.js @@ -418,6 +418,22 @@ function assignMenuAttributes(menu) { return id; } +export async function handleReply($el) { + hideElem($el); + const form = $el.closest('.comment-code-cloud').find('.comment-form'); + form.removeClass('gt-hidden'); + const $textarea = form.find('textarea'); + let easyMDE = getAttachedEasyMDE($textarea); + if (!easyMDE) { + await attachTribute($textarea.get(), {mentions: true, emoji: true}); + easyMDE = await createCommentEasyMDE($textarea); + } + $textarea.focus(); + easyMDE.codemirror.focus(); + assignMenuAttributes(form.find('.menu')); + return easyMDE; +} + export function initRepoPullRequestReview() { if (window.location.hash && window.location.hash.startsWith('#issuecomment-')) { const commentDiv = $(window.location.hash); @@ -455,19 +471,7 @@ export function initRepoPullRequestReview() { $(document).on('click', 'button.comment-form-reply', async function (e) { e.preventDefault(); - - hideElem($(this)); - const form = $(this).closest('.comment-code-cloud').find('.comment-form'); - form.removeClass('gt-hidden'); - const $textarea = form.find('textarea'); - let easyMDE = getAttachedEasyMDE($textarea); - if (!easyMDE) { - await attachTribute($textarea.get(), {mentions: true, emoji: true}); - easyMDE = await createCommentEasyMDE($textarea); - } - $textarea.focus(); - easyMDE.codemirror.focus(); - assignMenuAttributes(form.find('.menu')); + await handleReply($(this)); }); const $reviewBox = $('.review-box-panel'); diff --git a/web_src/js/features/repo-legacy.js b/web_src/js/features/repo-legacy.js index 8c2a0207cb0f..22113af169e3 100644 --- a/web_src/js/features/repo-legacy.js +++ b/web_src/js/features/repo-legacy.js @@ -6,7 +6,7 @@ import { initRepoIssueBranchSelect, initRepoIssueCodeCommentCancel, initRepoIssueCommentDelete, initRepoIssueComments, initRepoIssueDependencyDelete, initRepoIssueReferenceIssue, initRepoIssueStatusButton, initRepoIssueTitleEdit, initRepoIssueWipToggle, - initRepoPullRequestUpdate, updateIssuesMeta, + initRepoPullRequestUpdate, updateIssuesMeta, handleReply } from './repo-issue.js'; import {initUnicodeEscapeButton} from './repo-unicode-escape.js'; import {svg} from '../svg.js'; @@ -613,15 +613,15 @@ function initRepoIssueCommentEdit() { $(document).on('click', '.edit-content', onEditContent); // Quote reply - $(document).on('click', '.quote-reply', function (event) { + $(document).on('click', '.quote-reply', async function (event) { + event.preventDefault(); const target = $(this).data('target'); const quote = $(`#${target}`).text().replace(/\n/g, '\n> '); const content = `> ${quote}\n\n`; let easyMDE; if ($(this).hasClass('quote-reply-diff')) { - const $parent = $(this).closest('.comment-code-cloud'); - $parent.find('button.comment-form-reply').trigger('click'); - easyMDE = getAttachedEasyMDE($parent.find('[name="content"]')); + const $replyBtn = $(this).closest('.comment-code-cloud').find('button.comment-form-reply'); + easyMDE = await handleReply($replyBtn); } else { // for normal issue/comment page easyMDE = getAttachedEasyMDE($('#comment-form .edit_area')); @@ -637,6 +637,5 @@ function initRepoIssueCommentEdit() { easyMDE.codemirror.setCursor(easyMDE.codemirror.lineCount(), 0); }); } - event.preventDefault(); }); } From 574182e1eb9b2a0b35b7940c11563f07499c40ee Mon Sep 17 00:00:00 2001 From: Giteabot Date: Fri, 3 Mar 2023 12:41:00 -0500 Subject: [PATCH 038/340] Revert relative links to absolute links in mail templates (#23267) (#23269) Backport #23267 Follow #21986 , fix regression. The mail templates should always use `AppURL` (the full absolute URL) Co-authored-by: wxiaoguang --- templates/mail/issue/assigned.tmpl | 2 +- templates/mail/issue/default.tmpl | 6 +++--- templates/mail/release.tmpl | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/templates/mail/issue/assigned.tmpl b/templates/mail/issue/assigned.tmpl index 232a41b56f8a..05bed6902221 100644 --- a/templates/mail/issue/assigned.tmpl +++ b/templates/mail/issue/assigned.tmpl @@ -8,7 +8,7 @@ {{.Subject}} -{{$repo_url := printf "%s" (Escape .Issue.Repo.Link) (Escape .Issue.Repo.FullName)}} +{{$repo_url := printf "%s" (Escape .Issue.Repo.HTMLURL) (Escape .Issue.Repo.FullName)}} {{$link := printf "#%d" (Escape .Link) .Issue.Index}}

diff --git a/templates/mail/issue/default.tmpl b/templates/mail/issue/default.tmpl index 3bda408a0581..64dbb3df681e 100644 --- a/templates/mail/issue/default.tmpl +++ b/templates/mail/issue/default.tmpl @@ -20,11 +20,11 @@ {{if eq .ActionName "push"}}

{{if .Comment.IsForcePush}} - {{$oldCommitUrl := printf "%s/commit/%s" .Comment.Issue.PullRequest.BaseRepo.Link .Comment.OldCommit}} + {{$oldCommitUrl := printf "%s/commit/%s" .Comment.Issue.PullRequest.BaseRepo.HTMLURL .Comment.OldCommit}} {{$oldShortSha := ShortSha .Comment.OldCommit}} {{$oldCommitLink := printf "%[2]s" (Escape $oldCommitUrl) (Escape $oldShortSha)}} - {{$newCommitUrl := printf "%s/commit/%s" .Comment.Issue.PullRequest.BaseRepo.Link .Comment.NewCommit}} + {{$newCommitUrl := printf "%s/commit/%s" .Comment.Issue.PullRequest.BaseRepo.HTMLURL .Comment.NewCommit}} {{$newShortSha := ShortSha .Comment.NewCommit}} {{$newCommitLink := printf "%[2]s" (Escape $newCommitUrl) (Escape $newShortSha)}} @@ -72,7 +72,7 @@

    {{range .Comment.Commits}}
  • - + {{ShortSha .ID.String}} - {{.Summary}}
  • diff --git a/templates/mail/release.tmpl b/templates/mail/release.tmpl index 42504335231a..b2acdce8b2b4 100644 --- a/templates/mail/release.tmpl +++ b/templates/mail/release.tmpl @@ -11,8 +11,8 @@ -{{$release_url := printf "%s" (.Release.Link | Escape) (.Release.TagName | Escape)}} -{{$repo_url := printf "%s" (.Release.Repo.Link | Escape) (.Release.Repo.FullName | Escape)}} +{{$release_url := printf "%s" (.Release.HTMLURL | Escape) (.Release.TagName | Escape)}} +{{$repo_url := printf "%s" (.Release.Repo.HTMLURL | Escape) (.Release.Repo.FullName | Escape)}}

    {{.locale.Tr "mail.release.new.text" .Release.Publisher.Name $release_url $repo_url | Str2html}} From 464bbd747edb3054bca061ad3ddbaf3555790764 Mon Sep 17 00:00:00 2001 From: Giteabot Date: Fri, 3 Mar 2023 14:42:46 -0500 Subject: [PATCH 039/340] Fix commit retrieval by tag (#21804) (#23266) Backport #21804 It is not correct to return tag data when commit data is requested, so remove the hacky code that overwrote parts of a commit with parts of a tag. This fixes commit retrieval by tag for both the latest commit in the UI and the commit info on tag webhook events. Fixes: https://github.com/go-gitea/gitea/issues/21687 Replaces: https://github.com/go-gitea/gitea/pull/21693 Screenshot 2022-11-13 at 15 26 37 image Co-authored-by: silverwind --- modules/git/repo_commit_gogit.go | 39 ------------------ modules/git/repo_commit_nogogit.go | 4 -- modules/git/repo_commit_test.go | 5 ++- modules/git/repo_ref_test.go | 12 ++++-- modules/git/repo_stats_test.go | 4 +- modules/git/repo_tag_test.go | 9 ++-- modules/git/repo_test.go | 6 +-- modules/git/tests/repos/repo1_bare/index | Bin 0 -> 65 bytes modules/git/tests/repos/repo1_bare/logs/HEAD | 1 + .../repos/repo1_bare/logs/refs/heads/master | 1 + .../1c/91d130dc5fb75fd2d9f586a058650889cfe7fb | Bin 0 -> 813 bytes .../28/b55526e7100924d864dd89e35c1ea62e7a5a32 | Bin 0 -> 818 bytes .../36/f97d9a96457e2bab511db30fe2db03893ebc64 | Bin 0 -> 770 bytes .../4b/825dc642cb6eb9a060e54bf8d69288fbee4904 | Bin 0 -> 15 bytes .../93/3305878a3c9ad485c29b87fb662a73a9675c4b | Bin 0 -> 770 bytes .../ce/064814f4a0d337b333e646ece456cd39fab612 | Bin 0 -> 815 bytes .../cf/8b0b492a950b358a7ce7f9d01b18aef48a6b2d | Bin 0 -> 827 bytes .../tests/repos/repo1_bare/refs/heads/master | 2 +- .../repos/repo1_bare/refs/tags/signed-tag | 1 + 19 files changed, 26 insertions(+), 58 deletions(-) create mode 100644 modules/git/tests/repos/repo1_bare/index create mode 100644 modules/git/tests/repos/repo1_bare/objects/1c/91d130dc5fb75fd2d9f586a058650889cfe7fb create mode 100644 modules/git/tests/repos/repo1_bare/objects/28/b55526e7100924d864dd89e35c1ea62e7a5a32 create mode 100644 modules/git/tests/repos/repo1_bare/objects/36/f97d9a96457e2bab511db30fe2db03893ebc64 create mode 100644 modules/git/tests/repos/repo1_bare/objects/4b/825dc642cb6eb9a060e54bf8d69288fbee4904 create mode 100644 modules/git/tests/repos/repo1_bare/objects/93/3305878a3c9ad485c29b87fb662a73a9675c4b create mode 100644 modules/git/tests/repos/repo1_bare/objects/ce/064814f4a0d337b333e646ece456cd39fab612 create mode 100644 modules/git/tests/repos/repo1_bare/objects/cf/8b0b492a950b358a7ce7f9d01b18aef48a6b2d create mode 100644 modules/git/tests/repos/repo1_bare/refs/tags/signed-tag diff --git a/modules/git/repo_commit_gogit.go b/modules/git/repo_commit_gogit.go index 72de158e6e11..ce0af936140d 100644 --- a/modules/git/repo_commit_gogit.go +++ b/modules/git/repo_commit_gogit.go @@ -7,7 +7,6 @@ package git import ( - "fmt" "strings" "github.com/go-git/go-git/v5/plumbing" @@ -67,38 +66,6 @@ func (repo *Repository) IsCommitExist(name string) bool { return err == nil } -func convertPGPSignatureForTag(t *object.Tag) *CommitGPGSignature { - if t.PGPSignature == "" { - return nil - } - - var w strings.Builder - var err error - - if _, err = fmt.Fprintf(&w, - "object %s\ntype %s\ntag %s\ntagger ", - t.Target.String(), t.TargetType.Bytes(), t.Name); err != nil { - return nil - } - - if err = t.Tagger.Encode(&w); err != nil { - return nil - } - - if _, err = fmt.Fprintf(&w, "\n\n"); err != nil { - return nil - } - - if _, err = fmt.Fprintf(&w, t.Message); err != nil { - return nil - } - - return &CommitGPGSignature{ - Signature: t.PGPSignature, - Payload: strings.TrimSpace(w.String()) + "\n", - } -} - func (repo *Repository) getCommit(id SHA1) (*Commit, error) { var tagObject *object.Tag @@ -122,12 +89,6 @@ func (repo *Repository) getCommit(id SHA1) (*Commit, error) { commit := convertCommit(gogitCommit) commit.repo = repo - if tagObject != nil { - commit.CommitMessage = strings.TrimSpace(tagObject.Message) - commit.Author = &tagObject.Tagger - commit.Signature = convertPGPSignatureForTag(tagObject) - } - tree, err := gogitCommit.Tree() if err != nil { return nil, err diff --git a/modules/git/repo_commit_nogogit.go b/modules/git/repo_commit_nogogit.go index 7373d01c8efb..d5eb723100a7 100644 --- a/modules/git/repo_commit_nogogit.go +++ b/modules/git/repo_commit_nogogit.go @@ -107,10 +107,6 @@ func (repo *Repository) getCommitFromBatchReader(rd *bufio.Reader, id SHA1) (*Co return nil, err } - commit.CommitMessage = strings.TrimSpace(tag.Message) - commit.Author = tag.Tagger - commit.Signature = tag.Signature - return commit, nil case "commit": commit, err := CommitFromReader(repo, id, io.LimitReader(rd, size)) diff --git a/modules/git/repo_commit_test.go b/modules/git/repo_commit_test.go index af8c0592fe22..729fb0ba103a 100644 --- a/modules/git/repo_commit_test.go +++ b/modules/git/repo_commit_test.go @@ -43,12 +43,13 @@ func TestGetTagCommitWithSignature(t *testing.T) { assert.NoError(t, err) defer bareRepo1.Close() - commit, err := bareRepo1.GetCommit("3ad28a9149a2864384548f3d17ed7f38014c9e8a") + // both the tag and the commit are signed here, this validates only the commit signature + commit, err := bareRepo1.GetCommit("28b55526e7100924d864dd89e35c1ea62e7a5a32") assert.NoError(t, err) assert.NotNil(t, commit) assert.NotNil(t, commit.Signature) // test that signature is not in message - assert.Equal(t, "tag", commit.CommitMessage) + assert.Equal(t, "signed-commit\n", commit.CommitMessage) } func TestGetCommitWithBadCommitID(t *testing.T) { diff --git a/modules/git/repo_ref_test.go b/modules/git/repo_ref_test.go index 776d7ce3e15b..c08ea1276039 100644 --- a/modules/git/repo_ref_test.go +++ b/modules/git/repo_ref_test.go @@ -19,13 +19,14 @@ func TestRepository_GetRefs(t *testing.T) { refs, err := bareRepo1.GetRefs() assert.NoError(t, err) - assert.Len(t, refs, 5) + assert.Len(t, refs, 6) expectedRefs := []string{ BranchPrefix + "branch1", BranchPrefix + "branch2", BranchPrefix + "master", TagPrefix + "test", + TagPrefix + "signed-tag", NotesRef, } @@ -43,9 +44,12 @@ func TestRepository_GetRefsFiltered(t *testing.T) { refs, err := bareRepo1.GetRefsFiltered(TagPrefix) assert.NoError(t, err) - if assert.Len(t, refs, 1) { - assert.Equal(t, TagPrefix+"test", refs[0].Name) + if assert.Len(t, refs, 2) { + assert.Equal(t, TagPrefix+"signed-tag", refs[0].Name) assert.Equal(t, "tag", refs[0].Type) - assert.Equal(t, "3ad28a9149a2864384548f3d17ed7f38014c9e8a", refs[0].Object.String()) + assert.Equal(t, "36f97d9a96457e2bab511db30fe2db03893ebc64", refs[0].Object.String()) + assert.Equal(t, TagPrefix+"test", refs[1].Name) + assert.Equal(t, "tag", refs[1].Type) + assert.Equal(t, "3ad28a9149a2864384548f3d17ed7f38014c9e8a", refs[1].Object.String()) } } diff --git a/modules/git/repo_stats_test.go b/modules/git/repo_stats_test.go index 668ed6799998..3d032385ee28 100644 --- a/modules/git/repo_stats_test.go +++ b/modules/git/repo_stats_test.go @@ -24,9 +24,9 @@ func TestRepository_GetCodeActivityStats(t *testing.T) { assert.NoError(t, err) assert.NotNil(t, code) - assert.EqualValues(t, 9, code.CommitCount) + assert.EqualValues(t, 10, code.CommitCount) assert.EqualValues(t, 3, code.AuthorCount) - assert.EqualValues(t, 9, code.CommitCountInAllBranches) + assert.EqualValues(t, 10, code.CommitCountInAllBranches) assert.EqualValues(t, 10, code.Additions) assert.EqualValues(t, 1, code.Deletions) assert.Len(t, code.Authors, 3) diff --git a/modules/git/repo_tag_test.go b/modules/git/repo_tag_test.go index 589349a72c9e..8ccfec3eb23e 100644 --- a/modules/git/repo_tag_test.go +++ b/modules/git/repo_tag_test.go @@ -25,11 +25,14 @@ func TestRepository_GetTags(t *testing.T) { assert.NoError(t, err) return } - assert.Len(t, tags, 1) + assert.Len(t, tags, 2) assert.Equal(t, len(tags), total) - assert.EqualValues(t, "test", tags[0].Name) - assert.EqualValues(t, "3ad28a9149a2864384548f3d17ed7f38014c9e8a", tags[0].ID.String()) + assert.EqualValues(t, "signed-tag", tags[0].Name) + assert.EqualValues(t, "36f97d9a96457e2bab511db30fe2db03893ebc64", tags[0].ID.String()) assert.EqualValues(t, "tag", tags[0].Type) + assert.EqualValues(t, "test", tags[1].Name) + assert.EqualValues(t, "3ad28a9149a2864384548f3d17ed7f38014c9e8a", tags[1].ID.String()) + assert.EqualValues(t, "tag", tags[1].Type) } func TestRepository_GetTag(t *testing.T) { diff --git a/modules/git/repo_test.go b/modules/git/repo_test.go index 2a39148192cf..044b9d406502 100644 --- a/modules/git/repo_test.go +++ b/modules/git/repo_test.go @@ -14,10 +14,10 @@ func TestGetLatestCommitTime(t *testing.T) { bareRepo1Path := filepath.Join(testReposDir, "repo1_bare") lct, err := GetLatestCommitTime(DefaultContext, bareRepo1Path) assert.NoError(t, err) - // Time is Sun Jul 21 22:43:13 2019 +0200 + // Time is Sun Nov 13 16:40:14 2022 +0100 // which is the time of commit - // feaf4ba6bc635fec442f46ddd4512416ec43c2c2 (refs/heads/master) - assert.EqualValues(t, 1563741793, lct.Unix()) + // ce064814f4a0d337b333e646ece456cd39fab612 (refs/heads/master) + assert.EqualValues(t, 1668354014, lct.Unix()) } func TestRepoIsEmpty(t *testing.T) { diff --git a/modules/git/tests/repos/repo1_bare/index b/modules/git/tests/repos/repo1_bare/index new file mode 100644 index 0000000000000000000000000000000000000000..65d675154f23ffb2d0196e017d44a5e7017550f5 GIT binary patch literal 65 zcmZ?q402{*U|<4bhL9jvS0E+HV4z^Y<=qr}%;|LA&IJiiy? 1563741799 +0200 push +feaf4ba6bc635fec442f46ddd4512416ec43c2c2 ce064814f4a0d337b333e646ece456cd39fab612 silverwind 1668354026 +0100 push diff --git a/modules/git/tests/repos/repo1_bare/logs/refs/heads/master b/modules/git/tests/repos/repo1_bare/logs/refs/heads/master index cef4ca2dcb90..46da5fe0b15a 100644 --- a/modules/git/tests/repos/repo1_bare/logs/refs/heads/master +++ b/modules/git/tests/repos/repo1_bare/logs/refs/heads/master @@ -1 +1,2 @@ 37991dec2c8e592043f47155ce4808d4580f9123 feaf4ba6bc635fec442f46ddd4512416ec43c2c2 silverwind 1563741799 +0200 push +feaf4ba6bc635fec442f46ddd4512416ec43c2c2 ce064814f4a0d337b333e646ece456cd39fab612 silverwind 1668354026 +0100 push diff --git a/modules/git/tests/repos/repo1_bare/objects/1c/91d130dc5fb75fd2d9f586a058650889cfe7fb b/modules/git/tests/repos/repo1_bare/objects/1c/91d130dc5fb75fd2d9f586a058650889cfe7fb new file mode 100644 index 0000000000000000000000000000000000000000..fb50b65f9ff04e722d4df5c734d8d64eb761f61a GIT binary patch literal 813 zcmV+|1Je9>0hN=$TCJP2Xxf!d&!#WIA07Sc z-}rko{0TTwlo3WUgn)${giP`CznT8;VLjH5rUu{sK1DZeAB1KIV%zk|TN3F%IRhBb z9PLkq5Je@VG#Xt$hdF;uMI+|B`^$-rht7qT6PT^;8KmNjgm2tCMa{5fZwl-At?ceGLjp0z2VhpHLt`~~|T~IpX0N;HyZB}>LdTjFq zF7l@L56{<9jqruT;wT6UKle|G7x5{QKjX-fT;KL)2Am#GHi~cTebB~Cf59;O2y2us z(Q_epA>N*DazSBOChX)i#BS@jqmH89jSn6w)NisbKr|Sq zKEn4(PPFFq+6X7=xN~Zc?G8aT6uQR%({_S$js!VG_XbOmqKqND4Fk5fN@vAH~};niGA@JCnu z_3!z6)Bg!1LY7GRS_~FYf>0=a_Ip(SJ6PZ9v8lngzehK1Hvpj>g2c50y4%O*Pc8rf zG?6>&lG|c65Myy2c?(cORdEEv&>#cn;eT#O%WN=JZb^8w&z{L#EE2i{f zDp{`5TdSUEVm^~jFW!M?r|4cH-Ch%`pz7&#OcxOCjAa*vnfw%;_#lA&E?^rm-YuBz zz}NV6*2?Z-9QGZa+xp1k6^WdIMp-WPfn^oTe1GX#JK=j{#R!Rk0KAnMCh%iMGe=Yn0HhHTH69K_~U#mDD#e)F9tuV$mC%km(m@{ITImFHXqaPvM==o#v(HMUn( zlDyj;vP8@8#iz>A9Cq3|tE|O|FHe3E9%f#j#nC)54D~8L&_)2_2crD#DhJV>=IXK6 z)!QoLuVEx%Q9j$6^RN2;!0yv_)I;6m{vC;FZPQ{;f=(R-K=Npw7p>&(l6@8&$7z*5 zR;SrLxVfhH2`L=(B5!Nh!33A^!&=@JAJ1%q47Tw2e$55I3@>}<<=%>|$k`@q=*`dg z5Eawb*CsrD#%s1sHClT+^KxBY6s0CE%3fqU`_+JBR{+jpQw19}dWl+_>)h=Mx1+wf z#s?$l$7^Q2=WdHwM@5CSMwVqJr268sa<%Z*ZeS>YE?!jU<&)_Sdy~)WR5$0bGg2&{ zPo-avmv=s%HQgC*}wMDx!J97h3X@&33Vm3fD-(!hEBf-4BoO w+B0=nHhnM})sQ$Zu`>Mc0{H$)Tub=nj2RgJWsLA8)wL?W{qj=y0e4SSEbv>W@Bjb+ literal 0 HcmV?d00001 diff --git a/modules/git/tests/repos/repo1_bare/objects/36/f97d9a96457e2bab511db30fe2db03893ebc64 b/modules/git/tests/repos/repo1_bare/objects/36/f97d9a96457e2bab511db30fe2db03893ebc64 new file mode 100644 index 0000000000000000000000000000000000000000..c96b843902407e9468f8851fa80fc054dbb045c4 GIT binary patch literal 770 zcmV+d1O5DX0d14HvZGcMMIG}M%Bg1%pbJ#FU1lD{jD&y;E{GXP7Z9MY_iMY#o%lq1 ztzg$l_MBA*o}+$ypT9$szl$Wf0t-&#^UhDQ2zA`e{UXt9*zKT^ob!U@_>^^lEkoI z4PQe!O<7f9Uq4S&G{ZS~ns*2d%@HowK>5dGSmPTXQ4mB)5DK+Xl$)1RZ4A_q8eY2@ z_||YHb<@>)#a4yE*<{=oq^kSRW4+?ewoecRe60M{4gf3atUrm_ZKuJdBTO#p#7zpv zw=+DEDI2tQrM1)IBA$!L&xi%_R9=lc^ldi_EE^tb^$%_+6%=J3u1y;D%-UcYXo}G4rI7Wyu9?uR0&U~S;kG`2#y8}*6I48-3+3Do-kT?PxcE%O8bp__jX$sDQ#?B> zulhl6G1c84gT9Pj(ywxGhZdUNRKFe1Q_7zwv^N3u1`i286*iq(DN}sl>qf0kmy%_3 zI^viZ+2$w#wG4J4YM)gwqq++wU*E22AL3T147JBQtaBdjQiDbgiEY_PxGH&SEx$}` z3nSeUm+>-8{!IY5Jp)=-!z7MU8^(T0&%@iOI(y7c`~C!<{Bq5pl=#|7;-*S^W4N5) z^UxF~$_%+;Z%6oG;xSouf^x_DmVYKe;g(m@k&_*+QBKd9u zA0m_9>7kwHsNy}bRB=vF#@Z^&eN~aN14N^1fBk{|K$8~!I}*i_|8F9H1G4HoaeVlG AYybcN literal 0 HcmV?d00001 diff --git a/modules/git/tests/repos/repo1_bare/objects/4b/825dc642cb6eb9a060e54bf8d69288fbee4904 b/modules/git/tests/repos/repo1_bare/objects/4b/825dc642cb6eb9a060e54bf8d69288fbee4904 new file mode 100644 index 0000000000000000000000000000000000000000..adf64119a33d7621aeeaa505d30adb58afaa5559 GIT binary patch literal 15 WcmbxJ#nW*WL@ocIdmEWK9r>)TVA>E9|chi@fKQQ|1m;JrD|G8lWLE?Ch7x~Q>^Z7+l zzY@MNdOq_CQQtqMLetuB0yEe|mbq8r*sw#@ADN1QH5N5#z+>U|~0sL6( zL+E0M+1b9?LC;X|p6E@XXjS_kr#cw0prS=Jdn5OJ5~|wvVH?V&tT|{3W~{!4F>Xgi z;rBs~{Yg-)Ad~&QTbxVJPbkn1wHPaog-^tb5~GzY!kFXm;Kf?4YDI-oIe3s`^YkcL z`XfD@YJH+F*knvkJ}nfzkoM>eTL=SsnV>$Xgp8|9va2-RV(-l~$B|?wP;gLt7-scm zS5B5{EK1#c%)K4ec`Vq2yWp;ttu>){clYkB;Pza?*L-JiP3XhzDjGyF;GEr345RdM zJ5SwvTk7D7DQBHcHqB18W7Lt;K0-+wa;T{miC{y_DIF@6cW&Y&SG{ygdFGanmtG#V zl+ChiE~!VjS`2+&qU5U;hq!B!+J>cisE&;Ww%)RR*A7`iG%A)~!1Z8Cce-nBO|S?w zr30dN>XXBHKV0nX%LWJYDrEd1Kg)qQP73>>m1-j9ByHVE^;{sSs+O~r!WO7k)ULd0kV*bOeT~H&k&Dn zMBPl5C@Y0L19<^>u|$O+aHRksgo4O&0t-HbFSvpuvSqINk(}!GiN;smLGllb{`$B5 zz3%@cSpZ~S6c|<@DTZYjqWJmWjQ;oH?Qxsx8~N?;+Ue&0M0%!2hI{j*MscA3(>0k3Gy?^E;pJ^ z(;jH6;gw(KV>;=9N;%49M`e@N^gD+)xSP7^$;_(aXur<-%dx92T_c7dD`Oen3?5=& zB?X=H4Xc7I;hXn*A05#Lj_i&~Nb7vWB*|j|sl1Cj_X@Lv6LV-?2=b&!QY6&pkh9yx zP1NQXCXXzVPY*Am@$?XjHd9t)4Et$8w6}z(i!h(yWMWFDj(tXuP!ftOUaEH3f~Or# zqjvQ!0UA;3AMZ;YH(+~p5Q^63T5{fO5FhxKf~nVpJT`L+pC@;kfg9sMko#>E#~r}m&H zC9~{mtIj10?v&|haRypt;cc89-lkc}>^jsV?Rm5x1PSWr&`ehDi6Yy@O8Al=yiXNt zet(HzvWE2zBCFno>&4qBrqUS9riqL4J45ML zt1~RHNXU$$DAP<4iB@0jWrGp4b23kFh(8yMdol%6gbz>bRqsjLcsYexWom2fz7u@N z;xHcI(jBU6V4jxB&BLoed9R_>9(olKq;9IufUzjktsXKSCBHsr+qj?2BkP=FAM|^H tX@=8L;`x@o11ve0?*#chs$T~2%NhNo{g*MsN2(6NZ@;`GegOD(SMvVNmv;aF literal 0 HcmV?d00001 diff --git a/modules/git/tests/repos/repo1_bare/objects/cf/8b0b492a950b358a7ce7f9d01b18aef48a6b2d b/modules/git/tests/repos/repo1_bare/objects/cf/8b0b492a950b358a7ce7f9d01b18aef48a6b2d new file mode 100644 index 0000000000000000000000000000000000000000..1152b25bb8318c8fcb2b11de4e18b0185eeef25f GIT binary patch literal 827 zcmV-B1H}Az0hN={!^kHPlWms3wlCQ+oE z+1}FGT9cLcZCfumNmAr5%Y+aPGLB-390DrOAjJzzk3Y7OV*+b`<h9v z2Wyta=yLImAN_ z##D*&bKCI+=#th#k4y$ay2Gw=-kC+PcK|`jjN8nf!*%IpqL{nz)+J<)0Kt;-?sL-(FZT_ z_%1)Ja-7%pVDO_(pohavsk_^@gi26+d ze6;S@2WbyS_wCYAJn{`gHf|{Gl+X&cVNE{_>?{D{&>rk%J+H-C*Qr>8L7lv+#3wU9 zCJm0wIdl^Ex4mm`76`^`{>e-?7~HLfhL87JzrHOl@`cpL2B!f?4O<<1H> z!c*yCAY>(?x~CS*PS%Ui^+K^Sv$K<6c#;jaz?R!yMDYw&R`1g=NF?EMQ_H?6NpSVy zyM4QAGd+4Y)b{o;9&AXC&+RZ^mFBsXA1A`|=XQ{IA%T<+tqh+ke}Q{Q%RZ FW`6CxpoRbd literal 0 HcmV?d00001 diff --git a/modules/git/tests/repos/repo1_bare/refs/heads/master b/modules/git/tests/repos/repo1_bare/refs/heads/master index c5e92eb22976..9b0de228190a 100644 --- a/modules/git/tests/repos/repo1_bare/refs/heads/master +++ b/modules/git/tests/repos/repo1_bare/refs/heads/master @@ -1 +1 @@ -feaf4ba6bc635fec442f46ddd4512416ec43c2c2 +ce064814f4a0d337b333e646ece456cd39fab612 diff --git a/modules/git/tests/repos/repo1_bare/refs/tags/signed-tag b/modules/git/tests/repos/repo1_bare/refs/tags/signed-tag new file mode 100644 index 000000000000..3998a68507d4 --- /dev/null +++ b/modules/git/tests/repos/repo1_bare/refs/tags/signed-tag @@ -0,0 +1 @@ +36f97d9a96457e2bab511db30fe2db03893ebc64 From 1322cd7a58f6c2041624eddaf9393cc8947e5a5d Mon Sep 17 00:00:00 2001 From: Giteabot Date: Sat, 4 Mar 2023 00:38:11 -0500 Subject: [PATCH 040/340] Use correct README link to render the README (#23152) (#23264) Backport #23152 `renderReadmeFile` needs `readmeTreelink` as parameter but gets `treeLink`. The values of them look like as following: `treeLink`: `/{OwnerName}/{RepoName}/src/branch/{BranchName}` `readmeTreelink`: `/{OwnerName}/{RepoName}/src/branch/{BranchName}/{ReadmeFileName}` `path.Dir` in https://github.com/go-gitea/gitea/blob/8540fc45b11eff9a73753ca139f8ea5c38509bf5/routers/web/repo/view.go#L316 should convert `readmeTreelink` into `/{OwnerName}/{RepoName}/src/branch/{BranchName}` instead of the current `/{OwnerName}/{RepoName}/src/branch`. Fixes #23151 Co-authored-by: yp05327 <576951401@qq.com> Co-authored-by: Jason Song Co-authored-by: John Olheiser Co-authored-by: silverwind --- models/fixtures/repository.yml | 2 +- routers/web/repo/view.go | 2 +- .../40/3d76c604cb569323864e06a07b85d466924802 | Bin 0 -> 68 bytes .../78/fb907e3a3309eae4fe8fef030874cebbf1cd5e | Bin 0 -> 158 bytes .../f3/fa0f5cc797fc4c02a1b8bec9de4b2072fcdbdf | Bin 0 -> 53 bytes .../repo1.git/refs/heads/home-md-img-check | 1 + tests/integration/repo_test.go | 20 ++++++++++++++++++ 7 files changed, 23 insertions(+), 2 deletions(-) create mode 100644 tests/gitea-repositories-meta/user2/repo1.git/objects/40/3d76c604cb569323864e06a07b85d466924802 create mode 100644 tests/gitea-repositories-meta/user2/repo1.git/objects/78/fb907e3a3309eae4fe8fef030874cebbf1cd5e create mode 100644 tests/gitea-repositories-meta/user2/repo1.git/objects/f3/fa0f5cc797fc4c02a1b8bec9de4b2072fcdbdf create mode 100644 tests/gitea-repositories-meta/user2/repo1.git/refs/heads/home-md-img-check diff --git a/models/fixtures/repository.yml b/models/fixtures/repository.yml index 58f9b919acfb..dd8facb7a313 100644 --- a/models/fixtures/repository.yml +++ b/models/fixtures/repository.yml @@ -25,7 +25,7 @@ fork_id: 0 is_template: false template_id: 0 - size: 6708 + size: 7028 is_fsck_enabled: true close_issues_via_commit_in_any_branch: false diff --git a/routers/web/repo/view.go b/routers/web/repo/view.go index e3c61fa408bd..8663e1138208 100644 --- a/routers/web/repo/view.go +++ b/routers/web/repo/view.go @@ -186,7 +186,7 @@ func renderDirectory(ctx *context.Context, treeLink string) { return } - renderReadmeFile(ctx, readmeFile, treeLink) + renderReadmeFile(ctx, readmeFile, fmt.Sprintf("%s/%s", treeLink, readmeFile.name)) } // localizedExtensions prepends the provided language code with and without a diff --git a/tests/gitea-repositories-meta/user2/repo1.git/objects/40/3d76c604cb569323864e06a07b85d466924802 b/tests/gitea-repositories-meta/user2/repo1.git/objects/40/3d76c604cb569323864e06a07b85d466924802 new file mode 100644 index 0000000000000000000000000000000000000000..ea0bf76d0cc85bb9d51720cae227d440a93a3388 GIT binary patch literal 68 zcmV-K0K5Nq0ZYosPf{?mU{F>lN-fAYEpczHPS& zC9f~@aEDl;W009N39E*sXI<5;4X;{IO4!g5>D~|jp1>4Yqlns~AsAelglXl4oEcm7 zp{8}D{+yrt0l#;or3hS3t5L3)uaC!@?b|zK77<1wfmdvZ>7?h|^#4_o MxNRTl4+U^QjwQiQZvX%Q literal 0 HcmV?d00001 diff --git a/tests/gitea-repositories-meta/user2/repo1.git/objects/f3/fa0f5cc797fc4c02a1b8bec9de4b2072fcdbdf b/tests/gitea-repositories-meta/user2/repo1.git/objects/f3/fa0f5cc797fc4c02a1b8bec9de4b2072fcdbdf new file mode 100644 index 0000000000000000000000000000000000000000..9b20f8af3f2d52f51ef5053a55a15ed946fda5a7 GIT binary patch literal 53 zcmb Date: Sat, 4 Mar 2023 00:38:31 -0500 Subject: [PATCH 041/340] Fix GetFilesChangedBetween if the file name may be escaped (#23272) (#23279) Backport #23272 The code for GetFilesChangedBetween uses `git diff --name-only base..head` to get the names of files changed between base and head however this forgets that git will escape certain values. This PR simply switches to use `-z` which has the `NUL` character as the separator. Ref https://github.com/go-gitea/gitea/pull/22568#discussion_r1123138096 Signed-off-by: Andrew Thornton Co-authored-by: zeripath Co-authored-by: techknowlogick --- modules/git/repo_compare.go | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/modules/git/repo_compare.go b/modules/git/repo_compare.go index 9a4d66f2f521..439455e3c295 100644 --- a/modules/git/repo_compare.go +++ b/modules/git/repo_compare.go @@ -277,11 +277,18 @@ func (repo *Repository) GetPatch(base, head string, w io.Writer) error { // GetFilesChangedBetween returns a list of all files that have been changed between the given commits func (repo *Repository) GetFilesChangedBetween(base, head string) ([]string, error) { - stdout, _, err := NewCommand(repo.Ctx, "diff", "--name-only").AddDynamicArguments(base + ".." + head).RunStdString(&RunOpts{Dir: repo.Path}) + stdout, _, err := NewCommand(repo.Ctx, "diff", "--name-only", "-z").AddDynamicArguments(base + ".." + head).RunStdString(&RunOpts{Dir: repo.Path}) if err != nil { return nil, err } - return strings.Split(stdout, "\n"), err + split := strings.Split(stdout, "\000") + + // Because Git will always emit filenames with a terminal NUL ignore the last entry in the split - which will always be empty. + if len(split) > 0 { + split = split[:len(split)-1] + } + + return split, err } // GetDiffFromMergeBase generates and return patch data from merge base to head From a4158d1904b04c4f4b499cf8b9505aca3bb70d11 Mon Sep 17 00:00:00 2001 From: Giteabot Date: Sat, 4 Mar 2023 09:23:49 -0500 Subject: [PATCH 042/340] Avoid panic caused by broken payload when creating commit status (#23216) (#23294) Backport #23216 When creating commit status for Actons jobs, a payload with nil `HeadCommit` will cause panic. Reported at: https://gitea.com/gitea/act_runner/issues/28#issuecomment-732166 Although the `HeadCommit` probably can not be nil after #23215, `CreateCommitStatus` should protect itself, to avoid being broken in the future. In addition, it's enough to print error log instead of returning err when `CreateCommitStatus` failed. Co-authored-by: Jason Song Co-authored-by: delvh --- routers/api/actions/runner/runner.go | 2 +- routers/web/repo/actions/view.go | 22 +++++++++++++++------- services/actions/clear_tasks.go | 22 +++++++++++++++++----- services/actions/commit_status.go | 10 ++++++++++ services/actions/notifier_helper.go | 3 ++- 5 files changed, 45 insertions(+), 14 deletions(-) diff --git a/routers/api/actions/runner/runner.go b/routers/api/actions/runner/runner.go index d0bfb2363e0c..839f776fe8de 100644 --- a/routers/api/actions/runner/runner.go +++ b/routers/api/actions/runner/runner.go @@ -150,7 +150,7 @@ func (s *Service) UpdateTask( } if err := actions_service.CreateCommitStatus(ctx, task.Job); err != nil { - log.Error("Update commit status failed: %v", err) + log.Error("Update commit status for job %v failed: %v", task.Job.ID, err) // go on } diff --git a/routers/web/repo/actions/view.go b/routers/web/repo/actions/view.go index 5370310e8d9d..86894ce55b11 100644 --- a/routers/web/repo/actions/view.go +++ b/routers/web/repo/actions/view.go @@ -15,6 +15,7 @@ import ( "code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/modules/actions" context_module "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/web" @@ -207,15 +208,18 @@ func Rerun(ctx *context_module.Context) { job.Stopped = 0 if err := db.WithTx(ctx, func(ctx context.Context) error { - if _, err := actions_model.UpdateRunJob(ctx, job, builder.Eq{"status": status}, "task_id", "status", "started", "stopped"); err != nil { - return err - } - return actions_service.CreateCommitStatus(ctx, job) + _, err := actions_model.UpdateRunJob(ctx, job, builder.Eq{"status": status}, "task_id", "status", "started", "stopped") + return err }); err != nil { ctx.Error(http.StatusInternalServerError, err.Error()) return } + if err := actions_service.CreateCommitStatus(ctx, job); err != nil { + log.Error("Update commit status for job %v failed: %v", job.ID, err) + // go on + } + ctx.JSON(http.StatusOK, struct{}{}) } @@ -248,9 +252,6 @@ func Cancel(ctx *context_module.Context) { if err := actions_model.StopTask(ctx, job.TaskID, actions_model.StatusCancelled); err != nil { return err } - if err := actions_service.CreateCommitStatus(ctx, job); err != nil { - return err - } } return nil }); err != nil { @@ -258,6 +259,13 @@ func Cancel(ctx *context_module.Context) { return } + for _, job := range jobs { + if err := actions_service.CreateCommitStatus(ctx, job); err != nil { + log.Error("Update commit status for job %v failed: %v", job.ID, err) + // go on + } + } + ctx.JSON(http.StatusOK, struct{}{}) } diff --git a/services/actions/clear_tasks.go b/services/actions/clear_tasks.go index 583e588de405..6f8e95218d67 100644 --- a/services/actions/clear_tasks.go +++ b/services/actions/clear_tasks.go @@ -43,6 +43,7 @@ func stopTasks(ctx context.Context, opts actions_model.FindTaskOptions) error { return fmt.Errorf("find tasks: %w", err) } + jobs := make([]*actions_model.ActionRunJob, 0, len(tasks)) for _, task := range tasks { if err := db.WithTx(ctx, func(ctx context.Context) error { if err := actions_model.StopTask(ctx, task.ID, actions_model.StatusFailure); err != nil { @@ -51,7 +52,8 @@ func stopTasks(ctx context.Context, opts actions_model.FindTaskOptions) error { if err := task.LoadJob(ctx); err != nil { return err } - return CreateCommitStatus(ctx, task.Job) + jobs = append(jobs, task.Job) + return nil }); err != nil { log.Warn("Cannot stop task %v: %v", task.ID, err) // go on @@ -61,6 +63,14 @@ func stopTasks(ctx context.Context, opts actions_model.FindTaskOptions) error { remove() } } + + for _, job := range jobs { + if err := CreateCommitStatus(ctx, job); err != nil { + log.Error("Update commit status for job %v failed: %v", job.ID, err) + // go on + } + } + return nil } @@ -80,14 +90,16 @@ func CancelAbandonedJobs(ctx context.Context) error { job.Status = actions_model.StatusCancelled job.Stopped = now if err := db.WithTx(ctx, func(ctx context.Context) error { - if _, err := actions_model.UpdateRunJob(ctx, job, nil, "status", "stopped"); err != nil { - return err - } - return CreateCommitStatus(ctx, job) + _, err := actions_model.UpdateRunJob(ctx, job, nil, "status", "stopped") + return err }); err != nil { log.Warn("cancel abandoned job %v: %v", job.ID, err) // go on } + if err := CreateCommitStatus(ctx, job); err != nil { + log.Error("Update commit status for job %v failed: %v", job.ID, err) + // go on + } } return nil diff --git a/services/actions/commit_status.go b/services/actions/commit_status.go index efb5ec6d44a3..4f313493523e 100644 --- a/services/actions/commit_status.go +++ b/services/actions/commit_status.go @@ -30,6 +30,16 @@ func CreateCommitStatus(ctx context.Context, job *actions_model.ActionRunJob) er return fmt.Errorf("GetPushEventPayload: %w", err) } + // Since the payload comes from json data, we should check if it's broken, or it will cause panic + switch { + case payload.Repo == nil: + return fmt.Errorf("repo is missing in event payload") + case payload.Pusher == nil: + return fmt.Errorf("pusher is missing in event payload") + case payload.HeadCommit == nil: + return fmt.Errorf("head commit is missing in event payload") + } + creator, err := user_model.GetUserByID(ctx, payload.Pusher.ID) if err != nil { return fmt.Errorf("GetUserByID: %w", err) diff --git a/services/actions/notifier_helper.go b/services/actions/notifier_helper.go index df67d2fa116d..f4f6a3aa5287 100644 --- a/services/actions/notifier_helper.go +++ b/services/actions/notifier_helper.go @@ -180,7 +180,8 @@ func notify(ctx context.Context, input *notifyInput) error { } else { for _, job := range jobs { if err := CreateCommitStatus(ctx, job); err != nil { - log.Error("CreateCommitStatus: %v", err) + log.Error("Update commit status for job %v failed: %v", job.ID, err) + // go on } } } From 8142408d3a95a97f305a12d3d1f9b1731211d0dd Mon Sep 17 00:00:00 2001 From: Giteabot Date: Sat, 4 Mar 2023 13:02:50 -0500 Subject: [PATCH 043/340] Fill head commit to in payload when notifying push commits for mirroring (#23215) (#23292) Backport #23215 Just like what has been done when pushing manually: https://github.com/go-gitea/gitea/blob/7a5af25592003ddc3017fcd7b822a3e02fc40ef6/services/repository/push.go#L225-L226 Before: image After: image Co-authored-by: Jason Song Co-authored-by: delvh Co-authored-by: Lunny Xiao --- services/mirror/mirror_pull.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/services/mirror/mirror_pull.go b/services/mirror/mirror_pull.go index 126d2bf35468..60699294c18b 100644 --- a/services/mirror/mirror_pull.go +++ b/services/mirror/mirror_pull.go @@ -499,6 +499,13 @@ func SyncPullMirror(ctx context.Context, repoID int64) bool { theCommits.Commits = theCommits.Commits[:setting.UI.FeedMaxCommitNum] } + if newCommit, err := gitRepo.GetCommit(newCommitID); err != nil { + log.Error("SyncMirrors [repo: %-v]: unable to get commit %s: %v", m.Repo, newCommitID, err) + continue + } else { + theCommits.HeadCommit = repo_module.CommitToPushCommit(newCommit) + } + theCommits.CompareURL = m.Repo.ComposeCompareURL(oldCommitID, newCommitID) notification.NotifySyncPushCommits(ctx, m.Repo.MustOwner(ctx), m.Repo, &repo_module.PushUpdateOptions{ From 83903535e3710b3f6dcbef20bd8f349182a24abe Mon Sep 17 00:00:00 2001 From: Giteabot Date: Sat, 4 Mar 2023 14:55:12 -0500 Subject: [PATCH 044/340] Fix code wrap for unbroken lines (#23268) (#23293) Backport #23268 ## The Problem `overflow-wrap: break-word` doesn't work well for unbroken lines. Use `overflow-wrap: anywhere` instead, and remove legacy alias `word-wrap` ## Before ![image](https://user-images.githubusercontent.com/2114189222743939-5f38d9e4-18d8-4ae0-8078-4b3a59195a30.png) ## After ![image](https://user-images.githubusercontent.com/2114189/222743833-0e0cfdbb-7b2e-420d-99f9-b1b45dde521a.png) Co-authored-by: wxiaoguang Co-authored-by: silverwind --- web_src/less/_base.less | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/web_src/less/_base.less b/web_src/less/_base.less index a73dae6bf37a..1cf65e784cd4 100644 --- a/web_src/less/_base.less +++ b/web_src/less/_base.less @@ -2121,8 +2121,7 @@ a.ui.label:hover { font: 12px var(--fonts-monospace); white-space: pre-wrap; word-break: break-all; - overflow-wrap: break-word; - word-wrap: break-word; + overflow-wrap: anywhere; } .blame .code-inner { From a926994bfe31eb8a4b44dabef2e35e86f724affe Mon Sep 17 00:00:00 2001 From: Giteabot Date: Sat, 4 Mar 2023 20:09:58 -0500 Subject: [PATCH 045/340] Re-add accidentally removed `hacking-on-gitea.zh-cn.md` (#23297) (#23305) --- .../doc/developers/hacking-on-gitea.zh-cn.md | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 docs/content/doc/developers/hacking-on-gitea.zh-cn.md diff --git a/docs/content/doc/developers/hacking-on-gitea.zh-cn.md b/docs/content/doc/developers/hacking-on-gitea.zh-cn.md new file mode 100644 index 000000000000..3e8cd3ec573a --- /dev/null +++ b/docs/content/doc/developers/hacking-on-gitea.zh-cn.md @@ -0,0 +1,43 @@ +--- +date: "2016-12-01T16:00:00+02:00" +title: "加入 Gitea 开源" +slug: "hacking-on-gitea" +weight: 10 +toc: false +draft: false +menu: + sidebar: + parent: "developers" + name: "加入 Gitea 开源" + weight: 10 + identifier: "hacking-on-gitea" +--- + +# Hacking on Gitea + +首先你需要一些运行环境,这和 [从源代码安装]({{< relref "doc/installation/from-source.zh-cn.md" >}}) 相同,如果你还没有设置好,可以先阅读那个章节。 + +如果你想为 Gitea 贡献代码,你需要 Fork 这个项目并且以 `master` 为开发分支。Gitea 使用 Govendor +来管理依赖,因此所有依赖项都被工具自动 copy 在 vendor 子目录下。用下面的命令来下载源码: + +``` +go get -d code.gitea.io/gitea +``` + +然后你可以在 Github 上 fork [Gitea 项目](https://github.com/go-gitea/gitea),之后可以通过下面的命令进入源码目录: + +``` +cd $GOPATH/src/code.gitea.io/gitea +``` + +要创建 pull requests 你还需要在源码中新增一个 remote 指向你 Fork 的地址,直接推送到 origin 的话会告诉你没有写权限: + +``` +git remote rename origin upstream +git remote add origin git@github.com:/gitea.git +git fetch --all --prune +``` + +然后你就可以开始开发了。你可以看一下 `Makefile` 的内容。`make test` 可以运行测试程序, `make build` 将生成一个 `gitea` 可运行文件在根目录。如果你的提交比较复杂,尽量多写一些单元测试代码。 + +好了,到这里你已经设置好了所有的开发 Gitea 所需的环境。欢迎成为 Gitea 的 Contributor。 From ff96f804b64d9179d01b58c2863ce11cdd532fb9 Mon Sep 17 00:00:00 2001 From: Giteabot Date: Sun, 5 Mar 2023 02:13:50 -0500 Subject: [PATCH 046/340] update to mermaid v10 (#23178) (#23299) Backport #23178 fix #23153 Co-authored-by: techknowlogick Co-authored-by: silverwind Co-authored-by: delvh --- package-lock.json | 256 +++++++++++++++++++++++++++++------ package.json | 2 +- web_src/js/markup/mermaid.js | 41 +++--- webpack.config.js | 2 +- 4 files changed, 233 insertions(+), 68 deletions(-) diff --git a/package-lock.json b/package-lock.json index 641a42b84670..7ec6d09d1996 100644 --- a/package-lock.json +++ b/package-lock.json @@ -31,7 +31,7 @@ "less": "4.1.3", "less-loader": "11.1.0", "license-checker-webpack-plugin": "0.2.1", - "mermaid": "9.3.0", + "mermaid": "10.0.2", "mini-css-extract-plugin": "2.7.2", "monaco-editor": "0.34.1", "monaco-editor-webpack-plugin": "7.0.1", @@ -2680,6 +2680,14 @@ "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", "dev": true }, + "node_modules/cose-base": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/cose-base/-/cose-base-1.0.3.tgz", + "integrity": "sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg==", + "dependencies": { + "layout-base": "^1.0.0" + } + }, "node_modules/cosmiconfig": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.0.0.tgz", @@ -2888,6 +2896,53 @@ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz", "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==" }, + "node_modules/cytoscape": { + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/cytoscape/-/cytoscape-3.23.0.tgz", + "integrity": "sha512-gRZqJj/1kiAVPkrVFvz/GccxsXhF3Qwpptl32gKKypO4IlqnKBjTOu+HbXtEggSGzC5KCaHp3/F7GgENrtsFkA==", + "dependencies": { + "heap": "^0.2.6", + "lodash": "^4.17.21" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/cytoscape-cose-bilkent": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cytoscape-cose-bilkent/-/cytoscape-cose-bilkent-4.1.0.tgz", + "integrity": "sha512-wgQlVIUJF13Quxiv5e1gstZ08rnZj2XaLHGoFMYXz7SkNfCDOOteKBE6SYRfA9WxxI/iBc3ajfDoc6hb/MRAHQ==", + "dependencies": { + "cose-base": "^1.0.0" + }, + "peerDependencies": { + "cytoscape": "^3.2.0" + } + }, + "node_modules/cytoscape-fcose": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cytoscape-fcose/-/cytoscape-fcose-2.2.0.tgz", + "integrity": "sha512-ki1/VuRIHFCzxWNrsshHYPs6L7TvLu3DL+TyIGEsRcvVERmxokbf5Gdk7mFxZnTdiGtnA4cfSmjZJMviqSuZrQ==", + "dependencies": { + "cose-base": "^2.2.0" + }, + "peerDependencies": { + "cytoscape": "^3.2.0" + } + }, + "node_modules/cytoscape-fcose/node_modules/cose-base": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cose-base/-/cose-base-2.2.0.tgz", + "integrity": "sha512-AzlgcsCbUMymkADOJtQm3wO9S3ltPfYOFD5033keQn9NJzIbtnZj+UdBJe7DYml/8TdbtHJW3j58SOnKhWY/5g==", + "dependencies": { + "layout-base": "^2.0.0" + } + }, + "node_modules/cytoscape-fcose/node_modules/layout-base": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/layout-base/-/layout-base-2.0.1.tgz", + "integrity": "sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg==" + }, "node_modules/d3": { "version": "7.8.2", "resolved": "https://registry.npmjs.org/d3/-/d3-7.8.2.tgz", @@ -3267,11 +3322,11 @@ } }, "node_modules/dagre-d3-es": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/dagre-d3-es/-/dagre-d3-es-7.0.6.tgz", - "integrity": "sha512-CaaE/nZh205ix+Up4xsnlGmpog5GGm81Upi2+/SBHxwNwrccBb3K51LzjZ1U6hgvOlAEUsVWf1xSTzCyKpJ6+Q==", + "version": "7.0.9", + "resolved": "https://registry.npmjs.org/dagre-d3-es/-/dagre-d3-es-7.0.9.tgz", + "integrity": "sha512-rYR4QfVmy+sR44IBDvVtcAmOReGBvRCWDpO2QjYwqgh9yijw6eSHBqaPG/LIOEy7aBsniLvtMW6pg19qJhq60w==", "dependencies": { - "d3": "^7.7.0", + "d3": "^7.8.2", "lodash-es": "^4.17.21" } }, @@ -3298,6 +3353,11 @@ "node": ">=12" } }, + "node_modules/dayjs": { + "version": "1.11.7", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.7.tgz", + "integrity": "sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ==" + }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -3632,9 +3692,9 @@ } }, "node_modules/dompurify": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.4.1.tgz", - "integrity": "sha512-ewwFzHzrrneRjxzmK6oVz/rZn9VWspGFRDb4/rRtIsM1n36t9AKma/ye8syCpcw+XJ25kOK/hOG7t1j2I2yBqA==" + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.4.3.tgz", + "integrity": "sha512-q6QaLcakcRjebxjg8/+NP+h0rPfatOgOzc46Fst9VAA3jF2ApfKBNKMzdP4DYTqtUMXSCd5pRS/8Po/OmoCHZQ==" }, "node_modules/domutils": { "version": "3.0.1", @@ -3681,6 +3741,11 @@ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz", "integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==" }, + "node_modules/elkjs": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/elkjs/-/elkjs-0.8.2.tgz", + "integrity": "sha512-L6uRgvZTH+4OF5NE/MBbzQx/WYpru1xCBE9respNj6qznEewGUIfhzmm7horWWxbNO2M0WckQypGctR8lH79xQ==" + }, "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -5043,6 +5108,11 @@ "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-2.0.0.tgz", "integrity": "sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg==" }, + "node_modules/heap": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/heap/-/heap-0.2.7.tgz", + "integrity": "sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg==" + }, "node_modules/hosted-git-info": { "version": "2.8.9", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", @@ -5877,6 +5947,11 @@ "integrity": "sha512-5FZRzrZzNTBruuurWpvZnvP9pum+fe0HcK8z/ooo+U+Hmp4vtbyp1/QDsqmufirXy4egGzbaH/y2uCZf+6W5Kg==", "dev": true }, + "node_modules/layout-base": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/layout-base/-/layout-base-1.0.2.tgz", + "integrity": "sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg==" + }, "node_modules/less": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/less/-/less-4.1.3.tgz", @@ -6049,8 +6124,7 @@ "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, "node_modules/lodash-es": { "version": "4.17.21", @@ -6393,20 +6467,26 @@ } }, "node_modules/mermaid": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-9.3.0.tgz", - "integrity": "sha512-mGl0BM19TD/HbU/LmlaZbjBi//tojelg8P/mxD6pPZTAYaI+VawcyBdqRsoUHSc7j71PrMdJ3HBadoQNdvP5cg==", + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-10.0.2.tgz", + "integrity": "sha512-slwoB9WdNUT+/W9VhxLYRLZ0Ey12fIE+cAZjm3FmHTD+0F1uoJETfsNbVS1POnvQZhFYzfT6/z6hJZXgecqVBA==", "dependencies": { "@braintree/sanitize-url": "^6.0.0", - "d3": "^7.0.0", - "dagre-d3-es": "7.0.6", - "dompurify": "2.4.1", + "cytoscape": "^3.23.0", + "cytoscape-cose-bilkent": "^4.1.0", + "cytoscape-fcose": "^2.1.0", + "d3": "^7.4.0", + "dagre-d3-es": "7.0.9", + "dayjs": "^1.11.7", + "dompurify": "2.4.3", + "elkjs": "^0.8.2", "khroma": "^2.0.0", "lodash-es": "^4.17.21", - "moment-mini": "^2.24.0", "non-layered-tidy-tree-layout": "^2.0.2", "stylis": "^4.1.2", - "uuid": "^9.0.0" + "ts-dedent": "^2.2.0", + "uuid": "^9.0.0", + "web-worker": "^1.2.0" } }, "node_modules/micromatch": { @@ -6531,11 +6611,6 @@ "integrity": "sha512-nPdMG0Pd09HuSsr7QOKUXO2Jr9eqaDiZvDwdyIhNG5SHYujkQHYKDfGQkulBxvbDHz8oHLsTgKN86LSwYzSHAg==", "dev": true }, - "node_modules/moment-mini": { - "version": "2.29.4", - "resolved": "https://registry.npmjs.org/moment-mini/-/moment-mini-2.29.4.tgz", - "integrity": "sha512-uhXpYwHFeiTbY9KSgPPRoo1nt8OxNVdMVoTBYHfSEKeRkIkwGpO+gERmhuhBtzfaeOyTkykSrm2+noJBgqt3Hg==" - }, "node_modules/monaco-editor": { "version": "0.34.1", "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.34.1.tgz", @@ -8807,6 +8882,14 @@ "node": ">=8" } }, + "node_modules/ts-dedent": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ts-dedent/-/ts-dedent-2.2.0.tgz", + "integrity": "sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==", + "engines": { + "node": ">=6.10" + } + }, "node_modules/tsconfig-paths": { "version": "3.14.1", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", @@ -9315,6 +9398,11 @@ "node": ">=10.13.0" } }, + "node_modules/web-worker": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/web-worker/-/web-worker-1.2.0.tgz", + "integrity": "sha512-PgF341avzqyx60neE9DD+XS26MMNMoUQRz9NOZwW32nPQrF6p77f1htcnjBSEV8BGMKZ16choqUG4hyI0Hx7mA==" + }, "node_modules/webidl-conversions": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", @@ -11774,6 +11862,14 @@ "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", "dev": true }, + "cose-base": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/cose-base/-/cose-base-1.0.3.tgz", + "integrity": "sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg==", + "requires": { + "layout-base": "^1.0.0" + } + }, "cosmiconfig": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.0.0.tgz", @@ -11937,6 +12033,46 @@ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz", "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==" }, + "cytoscape": { + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/cytoscape/-/cytoscape-3.23.0.tgz", + "integrity": "sha512-gRZqJj/1kiAVPkrVFvz/GccxsXhF3Qwpptl32gKKypO4IlqnKBjTOu+HbXtEggSGzC5KCaHp3/F7GgENrtsFkA==", + "requires": { + "heap": "^0.2.6", + "lodash": "^4.17.21" + } + }, + "cytoscape-cose-bilkent": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cytoscape-cose-bilkent/-/cytoscape-cose-bilkent-4.1.0.tgz", + "integrity": "sha512-wgQlVIUJF13Quxiv5e1gstZ08rnZj2XaLHGoFMYXz7SkNfCDOOteKBE6SYRfA9WxxI/iBc3ajfDoc6hb/MRAHQ==", + "requires": { + "cose-base": "^1.0.0" + } + }, + "cytoscape-fcose": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cytoscape-fcose/-/cytoscape-fcose-2.2.0.tgz", + "integrity": "sha512-ki1/VuRIHFCzxWNrsshHYPs6L7TvLu3DL+TyIGEsRcvVERmxokbf5Gdk7mFxZnTdiGtnA4cfSmjZJMviqSuZrQ==", + "requires": { + "cose-base": "^2.2.0" + }, + "dependencies": { + "cose-base": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cose-base/-/cose-base-2.2.0.tgz", + "integrity": "sha512-AzlgcsCbUMymkADOJtQm3wO9S3ltPfYOFD5033keQn9NJzIbtnZj+UdBJe7DYml/8TdbtHJW3j58SOnKhWY/5g==", + "requires": { + "layout-base": "^2.0.0" + } + }, + "layout-base": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/layout-base/-/layout-base-2.0.1.tgz", + "integrity": "sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg==" + } + } + }, "d3": { "version": "7.8.2", "resolved": "https://registry.npmjs.org/d3/-/d3-7.8.2.tgz", @@ -12208,11 +12344,11 @@ } }, "dagre-d3-es": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/dagre-d3-es/-/dagre-d3-es-7.0.6.tgz", - "integrity": "sha512-CaaE/nZh205ix+Up4xsnlGmpog5GGm81Upi2+/SBHxwNwrccBb3K51LzjZ1U6hgvOlAEUsVWf1xSTzCyKpJ6+Q==", + "version": "7.0.9", + "resolved": "https://registry.npmjs.org/dagre-d3-es/-/dagre-d3-es-7.0.9.tgz", + "integrity": "sha512-rYR4QfVmy+sR44IBDvVtcAmOReGBvRCWDpO2QjYwqgh9yijw6eSHBqaPG/LIOEy7aBsniLvtMW6pg19qJhq60w==", "requires": { - "d3": "^7.7.0", + "d3": "^7.8.2", "lodash-es": "^4.17.21" } }, @@ -12233,6 +12369,11 @@ "whatwg-url": "^11.0.0" } }, + "dayjs": { + "version": "1.11.7", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.7.tgz", + "integrity": "sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ==" + }, "debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -12472,9 +12613,9 @@ } }, "dompurify": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.4.1.tgz", - "integrity": "sha512-ewwFzHzrrneRjxzmK6oVz/rZn9VWspGFRDb4/rRtIsM1n36t9AKma/ye8syCpcw+XJ25kOK/hOG7t1j2I2yBqA==" + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.4.3.tgz", + "integrity": "sha512-q6QaLcakcRjebxjg8/+NP+h0rPfatOgOzc46Fst9VAA3jF2ApfKBNKMzdP4DYTqtUMXSCd5pRS/8Po/OmoCHZQ==" }, "domutils": { "version": "3.0.1", @@ -12518,6 +12659,11 @@ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz", "integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==" }, + "elkjs": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/elkjs/-/elkjs-0.8.2.tgz", + "integrity": "sha512-L6uRgvZTH+4OF5NE/MBbzQx/WYpru1xCBE9respNj6qznEewGUIfhzmm7horWWxbNO2M0WckQypGctR8lH79xQ==" + }, "emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -13548,6 +13694,11 @@ "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-2.0.0.tgz", "integrity": "sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg==" }, + "heap": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/heap/-/heap-0.2.7.tgz", + "integrity": "sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg==" + }, "hosted-git-info": { "version": "2.8.9", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", @@ -14129,6 +14280,11 @@ "integrity": "sha512-5FZRzrZzNTBruuurWpvZnvP9pum+fe0HcK8z/ooo+U+Hmp4vtbyp1/QDsqmufirXy4egGzbaH/y2uCZf+6W5Kg==", "dev": true }, + "layout-base": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/layout-base/-/layout-base-1.0.2.tgz", + "integrity": "sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg==" + }, "less": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/less/-/less-4.1.3.tgz", @@ -14251,8 +14407,7 @@ "lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, "lodash-es": { "version": "4.17.21", @@ -14531,20 +14686,26 @@ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==" }, "mermaid": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-9.3.0.tgz", - "integrity": "sha512-mGl0BM19TD/HbU/LmlaZbjBi//tojelg8P/mxD6pPZTAYaI+VawcyBdqRsoUHSc7j71PrMdJ3HBadoQNdvP5cg==", + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-10.0.2.tgz", + "integrity": "sha512-slwoB9WdNUT+/W9VhxLYRLZ0Ey12fIE+cAZjm3FmHTD+0F1uoJETfsNbVS1POnvQZhFYzfT6/z6hJZXgecqVBA==", "requires": { "@braintree/sanitize-url": "^6.0.0", - "d3": "^7.0.0", - "dagre-d3-es": "7.0.6", - "dompurify": "2.4.1", + "cytoscape": "^3.23.0", + "cytoscape-cose-bilkent": "^4.1.0", + "cytoscape-fcose": "^2.1.0", + "d3": "^7.4.0", + "dagre-d3-es": "7.0.9", + "dayjs": "^1.11.7", + "dompurify": "2.4.3", + "elkjs": "^0.8.2", "khroma": "^2.0.0", "lodash-es": "^4.17.21", - "moment-mini": "^2.24.0", "non-layered-tidy-tree-layout": "^2.0.2", "stylis": "^4.1.2", - "uuid": "^9.0.0" + "ts-dedent": "^2.2.0", + "uuid": "^9.0.0", + "web-worker": "^1.2.0" } }, "micromatch": { @@ -14634,11 +14795,6 @@ } } }, - "moment-mini": { - "version": "2.29.4", - "resolved": "https://registry.npmjs.org/moment-mini/-/moment-mini-2.29.4.tgz", - "integrity": "sha512-uhXpYwHFeiTbY9KSgPPRoo1nt8OxNVdMVoTBYHfSEKeRkIkwGpO+gERmhuhBtzfaeOyTkykSrm2+noJBgqt3Hg==" - }, "monaco-editor": { "version": "0.34.1", "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.34.1.tgz", @@ -16340,6 +16496,11 @@ "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", "dev": true }, + "ts-dedent": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ts-dedent/-/ts-dedent-2.2.0.tgz", + "integrity": "sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==" + }, "tsconfig-paths": { "version": "3.14.1", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", @@ -16674,6 +16835,11 @@ "graceful-fs": "^4.1.2" } }, + "web-worker": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/web-worker/-/web-worker-1.2.0.tgz", + "integrity": "sha512-PgF341avzqyx60neE9DD+XS26MMNMoUQRz9NOZwW32nPQrF6p77f1htcnjBSEV8BGMKZ16choqUG4hyI0Hx7mA==" + }, "webidl-conversions": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", diff --git a/package.json b/package.json index fc063d66dacb..c4457fe9708f 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,7 @@ "less": "4.1.3", "less-loader": "11.1.0", "license-checker-webpack-plugin": "0.2.1", - "mermaid": "9.3.0", + "mermaid": "10.0.2", "mini-css-extract-plugin": "2.7.2", "monaco-editor": "0.34.1", "monaco-editor-webpack-plugin": "7.0.1", diff --git a/web_src/js/markup/mermaid.js b/web_src/js/markup/mermaid.js index 60f53d2b341d..b519e2dcdc35 100644 --- a/web_src/js/markup/mermaid.js +++ b/web_src/js/markup/mermaid.js @@ -37,14 +37,10 @@ export async function renderMermaid() { continue; } - let valid; try { - valid = mermaid.parse(source); + await mermaid.parse(source); } catch (err) { displayError(el, err); - } - - if (!valid) { el.closest('pre').classList.remove('is-loading'); continue; } @@ -52,22 +48,25 @@ export async function renderMermaid() { try { // can't use bindFunctions here because we can't cross the iframe boundary. This // means js-based interactions won't work but they aren't intended to work either - mermaid.mermaidAPI.render('mermaid', source, (svgStr) => { - const heightStr = (svgStr.match(/viewBox="(.+?)"/) || ['', ''])[1].split(/\s+/)[3]; - if (!heightStr) return displayError(el, new Error('Could not determine chart height')); - const iframe = document.createElement('iframe'); - iframe.classList.add('markup-render'); - iframe.sandbox = 'allow-scripts'; - iframe.style.height = `${Math.ceil(parseFloat(heightStr))}px`; - iframe.srcdoc = ` ${svgStr}`; - const mermaidBlock = document.createElement('div'); - mermaidBlock.classList.add('mermaid-block'); - mermaidBlock.append(iframe); - const btn = makeCodeCopyButton(); - btn.setAttribute('data-clipboard-text', source); - mermaidBlock.append(btn); - el.closest('pre').replaceWith(mermaidBlock); - }); + const {svg} = await mermaid.render('mermaid', source); + const heightStr = (svg.match(/viewBox="(.+?)"/) || ['', ''])[1].split(/\s+/)[3]; + if (!heightStr) return displayError(el, new Error('Could not determine chart height')); + + const iframe = document.createElement('iframe'); + iframe.classList.add('markup-render'); + iframe.sandbox = 'allow-scripts'; + iframe.style.height = `${Math.ceil(parseFloat(heightStr))}px`; + iframe.srcdoc = ` ${svg}`; + + const mermaidBlock = document.createElement('div'); + mermaidBlock.classList.add('mermaid-block'); + mermaidBlock.append(iframe); + + const btn = makeCodeCopyButton(); + btn.setAttribute('data-clipboard-text', source); + + mermaidBlock.append(btn); + el.closest('pre').replaceWith(mermaidBlock); } catch (err) { displayError(el, err); } diff --git a/webpack.config.js b/webpack.config.js index 2ac463abef2b..245791e7ea6e 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -234,7 +234,7 @@ export default { 'khroma@*': {licenseName: 'MIT'}, // https://github.com/fabiospampinato/khroma/pull/33 }, emitError: true, - allow: '(Apache-2.0 OR BSD-2-Clause OR BSD-3-Clause OR MIT OR ISC OR CPAL-1.0 OR Unlicense)', + allow: '(Apache-2.0 OR BSD-2-Clause OR BSD-3-Clause OR MIT OR ISC OR CPAL-1.0 OR Unlicense OR EPL-1.0 OR EPL-2.0)', ignore: [ 'font-awesome', ], From a2a9b0f977461e3132bb78a276f47e3c0b42a8c4 Mon Sep 17 00:00:00 2001 From: Giteabot Date: Sun, 5 Mar 2023 02:14:12 -0500 Subject: [PATCH 047/340] Support sanitising the URL by removing extra slashes in the URL (#21333) (#23300) Backport #21333 Changes in this PR : Strips incoming request URL of additional slashes (/). For example an input like `https://git.data.coop//halfd/new-website.git` is translated to `https://git.data.coop/halfd/new-website.git` Fixes https://github.com/go-gitea/gitea/issues/20462 Fix #23242 Co-authored-by: Sandeep Bhat Co-authored-by: zeripath Co-authored-by: Jason Song Co-authored-by: Lunny Xiao Co-authored-by: delvh --- routers/common/middleware.go | 35 +++++++++++++++- routers/common/middleware_test.go | 70 +++++++++++++++++++++++++++++++ 2 files changed, 103 insertions(+), 2 deletions(-) create mode 100644 routers/common/middleware_test.go diff --git a/routers/common/middleware.go b/routers/common/middleware.go index 4f9d43c36218..2abdcb583d8f 100644 --- a/routers/common/middleware.go +++ b/routers/common/middleware.go @@ -16,7 +16,7 @@ import ( "code.gitea.io/gitea/modules/web/routing" "github.com/chi-middleware/proxy" - "github.com/go-chi/chi/v5/middleware" + chi "github.com/go-chi/chi/v5" ) // Middlewares returns common middlewares @@ -48,7 +48,8 @@ func Middlewares() []func(http.Handler) http.Handler { handlers = append(handlers, proxy.ForwardedHeaders(opt)) } - handlers = append(handlers, middleware.StripSlashes) + // Strip slashes. + handlers = append(handlers, stripSlashesMiddleware) if !setting.Log.DisableRouterLog { handlers = append(handlers, routing.NewLoggerHandler()) @@ -81,3 +82,33 @@ func Middlewares() []func(http.Handler) http.Handler { }) return handlers } + +func stripSlashesMiddleware(next http.Handler) http.Handler { + return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) { + var urlPath string + rctx := chi.RouteContext(req.Context()) + if rctx != nil && rctx.RoutePath != "" { + urlPath = rctx.RoutePath + } else if req.URL.RawPath != "" { + urlPath = req.URL.RawPath + } else { + urlPath = req.URL.Path + } + + sanitizedPath := &strings.Builder{} + prevWasSlash := false + for _, chr := range strings.TrimRight(urlPath, "/") { + if chr != '/' || !prevWasSlash { + sanitizedPath.WriteRune(chr) + } + prevWasSlash = chr == '/' + } + + if rctx == nil { + req.URL.Path = sanitizedPath.String() + } else { + rctx.RoutePath = sanitizedPath.String() + } + next.ServeHTTP(resp, req) + }) +} diff --git a/routers/common/middleware_test.go b/routers/common/middleware_test.go new file mode 100644 index 000000000000..f16b9374eca7 --- /dev/null +++ b/routers/common/middleware_test.go @@ -0,0 +1,70 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT +package common + +import ( + "net/http" + "net/http/httptest" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestStripSlashesMiddleware(t *testing.T) { + type test struct { + name string + expectedPath string + inputPath string + } + + tests := []test{ + { + name: "path with multiple slashes", + inputPath: "https://github.com///go-gitea//gitea.git", + expectedPath: "/go-gitea/gitea.git", + }, + { + name: "path with no slashes", + inputPath: "https://github.com/go-gitea/gitea.git", + expectedPath: "/go-gitea/gitea.git", + }, + { + name: "path with slashes in the middle", + inputPath: "https://git.data.coop//halfd/new-website.git", + expectedPath: "/halfd/new-website.git", + }, + { + name: "path with slashes in the middle", + inputPath: "https://git.data.coop//halfd/new-website.git", + expectedPath: "/halfd/new-website.git", + }, + { + name: "path with slashes in the end", + inputPath: "/user2//repo1/", + expectedPath: "/user2/repo1", + }, + { + name: "path with slashes and query params", + inputPath: "/repo//migrate?service_type=3", + expectedPath: "/repo/migrate", + }, + { + name: "path with encoded slash", + inputPath: "/user2/%2F%2Frepo1", + expectedPath: "/user2/%2F%2Frepo1", + }, + } + + for _, tt := range tests { + testMiddleware := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + assert.Equal(t, tt.expectedPath, r.URL.Path) + }) + + // pass the test middleware to validate the changes + handlerToTest := stripSlashesMiddleware(testMiddleware) + // create a mock request to use + req := httptest.NewRequest("GET", tt.inputPath, nil) + // call the handler using a mock response recorder + handlerToTest.ServeHTTP(httptest.NewRecorder(), req) + } +} From 1edb57eda9826a5b7402e92d516d6b9097eb8ad3 Mon Sep 17 00:00:00 2001 From: Giteabot Date: Sun, 5 Mar 2023 05:59:58 -0500 Subject: [PATCH 048/340] Fix various bugs for "install" page (#23194) (#23286) Backport #23194 ## TLDR * Fix the broken page / broken image problem when click "Install" * Fix the Password Hash Algorithm display problem for #22942 * Close #20089 * Close #23183 * Close #23184 ## Details ### The broken page / broken image problem when clicking on "Install" (Redirect failed after install - #23184) Before: when clicking on "install", all new requests will fail, because the server has been restarted. Users just see a broken page with broken images, sometimes the server is not ready but the user would have been redirect to "/user/login" page, then the users see a new broken page (connection refused or something wrong ...) After: only check InstallLock=true for necessary handlers, and sleep for a while before restarting the server, then the browser has enough time to load the "post-install" page. And there is a script to check whether "/user/login" is ready, the user will only be redirected to the login page when the server is ready. ### During new instance setup fill 'Gitea Base URL' with window.location.origin - #20089 If the "app_url" input contains `localhost` (the default value from config), use current window's location href as the `app_url` (aka ROOT_URL) ### Fix the Password Hash Algorithm display problem for "Provide the ability to set password hash algorithm parameters #22942" Before: the UI shows `pbkdf2$50000$50`

    ![image](https://user-images.githubusercontent.com/2114189/221917143-e1e54798-1698-4fee-a18d-00c48081fc39.png)
    After: the UI shows `pbkdf2`
    ![image](https://user-images.githubusercontent.com/2114189/221916999-97a15be8-2ebb-4a01-bf93-dac18e354fcc.png)
    ### GET data: net::ERR_INVALID_URL #23183 Cause by empty `data:` in `` Co-authored-by: wxiaoguang Co-authored-by: Jason Song Co-authored-by: Lunny Xiao Co-authored-by: techknowlogick --- modules/auth/password/hash/setting.go | 29 ++++++++++++---- options/locale/locale_en-US.ini | 2 +- routers/install/install.go | 48 ++++++++++++++++++--------- routers/install/routes.go | 13 ++++++-- templates/base/head.tmpl | 2 +- templates/post-install.tmpl | 4 +-- web_src/js/features/install.js | 39 +++++++++++++++++++++- 7 files changed, 107 insertions(+), 30 deletions(-) diff --git a/modules/auth/password/hash/setting.go b/modules/auth/password/hash/setting.go index 70169743040a..f0715f31e1a4 100644 --- a/modules/auth/password/hash/setting.go +++ b/modules/auth/password/hash/setting.go @@ -41,9 +41,8 @@ var RecommendedHashAlgorithms = []string{ "pbkdf2_hi", } -// SetDefaultPasswordHashAlgorithm will take a provided algorithmName and dealias it to -// a complete algorithm specification. -func SetDefaultPasswordHashAlgorithm(algorithmName string) (string, *PasswordHashAlgorithm) { +// hashAlgorithmToSpec converts an algorithm name or a specification to a full algorithm specification +func hashAlgorithmToSpec(algorithmName string) string { if algorithmName == "" { algorithmName = DefaultHashAlgorithmName } @@ -52,10 +51,26 @@ func SetDefaultPasswordHashAlgorithm(algorithmName string) (string, *PasswordHas algorithmName = alias alias, has = aliasAlgorithmNames[algorithmName] } + return algorithmName +} - // algorithmName should now be a full algorithm specification - // e.g. pbkdf2$50000$50 rather than pbdkf2 - DefaultHashAlgorithm = Parse(algorithmName) +// SetDefaultPasswordHashAlgorithm will take a provided algorithmName and de-alias it to +// a complete algorithm specification. +func SetDefaultPasswordHashAlgorithm(algorithmName string) (string, *PasswordHashAlgorithm) { + algoSpec := hashAlgorithmToSpec(algorithmName) + // now we get a full specification, e.g. pbkdf2$50000$50 rather than pbdkf2 + DefaultHashAlgorithm = Parse(algoSpec) + return algoSpec, DefaultHashAlgorithm +} - return algorithmName, DefaultHashAlgorithm +// ConfigHashAlgorithm will try to find a "recommended algorithm name" defined by RecommendedHashAlgorithms for config +// This function is not fast and is only used for the installation page +func ConfigHashAlgorithm(algorithm string) string { + algorithm = hashAlgorithmToSpec(algorithm) + for _, recommAlgo := range RecommendedHashAlgorithms { + if algorithm == hashAlgorithmToSpec(recommAlgo) { + return recommAlgo + } + } + return algorithm } diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index df66ce23390f..b2fb837bf02f 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -237,7 +237,6 @@ internal_token_failed = Failed to generate internal token: %v secret_key_failed = Failed to generate secret key: %v save_config_failed = Failed to save configuration: %v invalid_admin_setting = Administrator account setting is invalid: %v -install_success = Welcome! Thank you for choosing Gitea. Have fun and take care! invalid_log_root_path = The log path is invalid: %v default_keep_email_private = Hide Email Addresses by Default default_keep_email_private_popup = Hide email addresses of new user accounts by default. @@ -248,6 +247,7 @@ default_enable_timetracking_popup = Enable time tracking for new repositories by no_reply_address = Hidden Email Domain no_reply_address_helper = Domain name for users with a hidden email address. For example, the username 'joe' will be logged in Git as 'joe@noreply.example.org' if the hidden email domain is set to 'noreply.example.org'. password_algorithm = Password Hash Algorithm +invalid_password_algorithm = Invalid password hash algorithm password_algorithm_helper = Set the password hashing algorithm. Algorithms have differing requirements and strength. `argon2` whilst having good characteristics uses a lot of memory and may be inappropriate for small systems. enable_update_checker = Enable Update Checker enable_update_checker_helper = Checks for new version releases periodically by connecting to gitea.io. diff --git a/routers/install/install.go b/routers/install/install.go index a3d64e5f73a5..a377c2950ba3 100644 --- a/routers/install/install.go +++ b/routers/install/install.go @@ -59,11 +59,6 @@ func Init(ctx goctx.Context) func(next http.Handler) http.Handler { dbTypeNames := getSupportedDbTypeNames() return func(next http.Handler) http.Handler { return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) { - if setting.InstallLock { - resp.Header().Add("Refresh", "1; url="+setting.AppURL+"user/login") - _ = rnd.HTML(resp, http.StatusOK, string(tplPostInstall), nil) - return - } locale := middleware.Locale(resp, req) startTime := time.Now() ctx := context.Context{ @@ -93,6 +88,11 @@ func Init(ctx goctx.Context) func(next http.Handler) http.Handler { // Install render installation page func Install(ctx *context.Context) { + if setting.InstallLock { + InstallDone(ctx) + return + } + form := forms.InstallForm{} // Database settings @@ -162,7 +162,7 @@ func Install(ctx *context.Context) { form.DefaultAllowCreateOrganization = setting.Service.DefaultAllowCreateOrganization form.DefaultEnableTimetracking = setting.Service.DefaultEnableTimetracking form.NoReplyAddress = setting.Service.NoReplyAddress - form.PasswordAlgorithm = setting.PasswordHashAlgo + form.PasswordAlgorithm = hash.ConfigHashAlgorithm(setting.PasswordHashAlgo) middleware.AssignForm(form, ctx.Data) ctx.HTML(http.StatusOK, tplInstall) @@ -234,6 +234,11 @@ func checkDatabase(ctx *context.Context, form *forms.InstallForm) bool { // SubmitInstall response for submit install items func SubmitInstall(ctx *context.Context) { + if setting.InstallLock { + InstallDone(ctx) + return + } + var err error form := *web.GetForm(ctx).(*forms.InstallForm) @@ -277,7 +282,6 @@ func SubmitInstall(ctx *context.Context) { setting.Database.Charset = form.Charset setting.Database.Path = form.DbPath setting.Database.LogSQL = !setting.IsProd - setting.PasswordHashAlgo = form.PasswordAlgorithm if !checkDatabase(ctx, &form) { return @@ -499,6 +503,12 @@ func SubmitInstall(ctx *context.Context) { } if len(form.PasswordAlgorithm) > 0 { + var algorithm *hash.PasswordHashAlgorithm + setting.PasswordHashAlgo, algorithm = hash.SetDefaultPasswordHashAlgorithm(form.PasswordAlgorithm) + if algorithm == nil { + ctx.RenderWithErr(ctx.Tr("install.invalid_password_algorithm"), tplInstall, &form) + return + } cfg.Section("security").Key("PASSWORD_HASH_ALGO").SetValue(form.PasswordAlgorithm) } @@ -571,18 +581,26 @@ func SubmitInstall(ctx *context.Context) { } log.Info("First-time run install finished!") + InstallDone(ctx) - ctx.Flash.Success(ctx.Tr("install.install_success")) - - ctx.RespHeader().Add("Refresh", "1; url="+setting.AppURL+"user/login") - ctx.HTML(http.StatusOK, tplPostInstall) - - // Now get the http.Server from this request and shut it down - // NB: This is not our hammerable graceful shutdown this is http.Server.Shutdown - srv := ctx.Value(http.ServerContextKey).(*http.Server) go func() { + // Sleep for a while to make sure the user's browser has loaded the post-install page and its assets (images, css, js) + // What if this duration is not long enough? That's impossible -- if the user can't load the simple page in time, how could they install or use Gitea in the future .... + time.Sleep(3 * time.Second) + + // Now get the http.Server from this request and shut it down + // NB: This is not our hammerable graceful shutdown this is http.Server.Shutdown + srv := ctx.Value(http.ServerContextKey).(*http.Server) if err := srv.Shutdown(graceful.GetManager().HammerContext()); err != nil { log.Error("Unable to shutdown the install server! Error: %v", err) } + + // After the HTTP server for "install" shuts down, the `runWeb()` will continue to run the "normal" server }() } + +// InstallDone shows the "post-install" page, makes it easier to develop the page. +// The name is not called as "PostInstall" to avoid misinterpretation as a handler for "POST /install" +func InstallDone(ctx *context.Context) { //nolint + ctx.HTML(http.StatusOK, tplPostInstall) +} diff --git a/routers/install/routes.go b/routers/install/routes.go index 9aa5a88d24b1..a8efc92fe17c 100644 --- a/routers/install/routes.go +++ b/routers/install/routes.go @@ -6,6 +6,7 @@ package install import ( goctx "context" "fmt" + "html" "net/http" "path" @@ -37,7 +38,7 @@ func installRecovery(ctx goctx.Context) func(next http.Handler) http.Handler { // Why we need this? The first recover will try to render a beautiful // error page for user, but the process can still panic again, then // we have to just recover twice and send a simple error page that - // should not panic any more. + // should not panic anymore. defer func() { if err := recover(); err != nil { combinedErr := fmt.Sprintf("PANIC: %v\n%s", err, log.Stack(2)) @@ -107,8 +108,9 @@ func Routes(ctx goctx.Context) *web.Route { r.Use(installRecovery(ctx)) r.Use(Init(ctx)) - r.Get("/", Install) + r.Get("/", Install) // it must be on the root, because the "install.js" use the window.location to replace the "localhost" AppURL r.Post("/", web.Bind(forms.InstallForm{}), SubmitInstall) + r.Get("/post-install", InstallDone) r.Get("/api/healthz", healthcheck.Check) r.NotFound(web.Wrap(installNotFound)) @@ -116,5 +118,10 @@ func Routes(ctx goctx.Context) *web.Route { } func installNotFound(w http.ResponseWriter, req *http.Request) { - http.Redirect(w, req, setting.AppURL, http.StatusFound) + w.Header().Add("Content-Type", "text/html; charset=utf-8") + w.Header().Add("Refresh", fmt.Sprintf("1; url=%s", setting.AppSubURL+"/")) + // do not use 30x status, because the "post-install" page needs to use 404/200 to detect if Gitea has been installed. + // the fetch API could follow 30x requests to the page with 200 status. + w.WriteHeader(http.StatusNotFound) + _, _ = fmt.Fprintf(w, `Not Found. Go to default page.`, html.EscapeString(setting.AppSubURL+"/")) } diff --git a/templates/base/head.tmpl b/templates/base/head.tmpl index c552dcfd2d98..d179140b23b2 100644 --- a/templates/base/head.tmpl +++ b/templates/base/head.tmpl @@ -4,7 +4,7 @@ {{if .Title}}{{.Title | RenderEmojiPlain}} - {{end}}{{if .Repository.Name}}{{.Repository.Name}} - {{end}}{{AppName}} - + {{if .ManifestData}}{{end}} diff --git a/templates/post-install.tmpl b/templates/post-install.tmpl index 0d6cd3082c18..f237a6e01b10 100644 --- a/templates/post-install.tmpl +++ b/templates/post-install.tmpl @@ -1,5 +1,5 @@ {{template "base/head" .}} -
    +
    diff --git a/web_src/js/features/install.js b/web_src/js/features/install.js index 2ba6fe1279e0..23122ca4c383 100644 --- a/web_src/js/features/install.js +++ b/web_src/js/features/install.js @@ -2,10 +2,18 @@ import $ from 'jquery'; import {hideElem, showElem} from '../utils/dom.js'; export function initInstall() { - if ($('.page-content.install').length === 0) { + const $page = $('.page-content.install'); + if ($page.length === 0) { return; } + if ($page.is('.post-install')) { + initPostInstall(); + } else { + initPreInstall(); + } +} +function initPreInstall() { const defaultDbUser = 'gitea'; const defaultDbName = 'gitea'; @@ -40,6 +48,18 @@ export function initInstall() { } // else: for SQLite3, the default path is always prepared by backend code (setting) }).trigger('change'); + const $appUrl = $('#app_url'); + const configAppUrl = $appUrl.val(); + if (configAppUrl.includes('://localhost')) { + $appUrl.val(window.location.href); + } + + const $domain = $('#domain'); + const configDomain = $domain.val().trim(); + if (configDomain === 'localhost') { + $domain.val(window.location.hostname); + } + // TODO: better handling of exclusive relations. $('#offline-mode input').on('change', function () { if ($(this).is(':checked')) { @@ -83,3 +103,20 @@ export function initInstall() { } }); } + +function initPostInstall() { + const el = document.getElementById('goto-user-login'); + if (!el) return; + + const targetUrl = el.getAttribute('href'); + let tid = setInterval(async () => { + try { + const resp = await fetch(targetUrl); + if (tid && resp.status === 200) { + clearInterval(tid); + tid = null; + window.location.href = targetUrl; + } + } catch {} + }, 1000); +} From 17ae7e335effda0f88b1df83b6918ff9b131f914 Mon Sep 17 00:00:00 2001 From: Giteabot Date: Sun, 5 Mar 2023 07:38:46 -0500 Subject: [PATCH 049/340] Add basic documentation for labels, including scoped labels (#23304) (#23309) Backport #23304 Part of #22974 Co-authored-by: Brecht Van Lommel Co-authored-by: delvh --- docs/content/doc/usage/labels.en-us.md | 42 ++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 docs/content/doc/usage/labels.en-us.md diff --git a/docs/content/doc/usage/labels.en-us.md b/docs/content/doc/usage/labels.en-us.md new file mode 100644 index 000000000000..bf07c074edc6 --- /dev/null +++ b/docs/content/doc/usage/labels.en-us.md @@ -0,0 +1,42 @@ +--- +date: "2023-03-04T19:00:00+00:00" +title: "Usage: Labels" +slug: "labels" +weight: 13 +toc: false +draft: false +menu: + sidebar: + parent: "usage" + name: "Labels" + weight: 13 + identifier: "labels" +--- + +# Labels + +You can use labels to classify issues and pull requests and to improve your overview over them. + +## Creating Labels + +For repositories, labels can be created by going to `Issues` and clicking on `Labels`. + +For organizations, you can define organization-wide labels that are shared with all organization repositories, including both already-existing repositories as well as newly created ones. Organization-wide labels can be created in the organization `Settings`. + +Labels have a mandatory name, a mandatory color, an optional description, and must either be exclusive or not (see `Scoped labels` below). + +When you create a repository, you can ensure certain labels exist by using the `Issue Labels` option. This option lists a number of available label sets that are [configured globally on your instance](../customizing-gitea/#labels). Its contained labels will all be created as well while creating the repository. + +## Scoped Labels + +A scoped label is a label that contains `/` in its name (not at either end of the name). For example labels `kind/bug` and `kind/enhancement` both have scope `kind`. Such labels will display the scope with slightly darker color. + +The scope of a label is determined based on the **last** `/`, so for example the scope of label `scope/subscope/item` is `scope/subscope`. + +Scoped labels can be marked as exclusive. This ensures at most a single label with the same scope is assigned to an issue or pull request. For example, if `kind/bug` and `kind/enhancement` are marked exclusive, an issue can only be classified as a bug or an enhancement. + +## Filtering by Label + +Issue and pull request lists can be filtered by label. Selecting multiple labels shows issues and pull requests that have all selected labels assigned. + +By holding alt to click the label, issues and pull requests with the chosen label are excluded from the list. From e3b1ebbbfed7fac634eedf62a28d9dfdb990d22d Mon Sep 17 00:00:00 2001 From: Giteabot Date: Sun, 5 Mar 2023 10:05:11 -0500 Subject: [PATCH 050/340] Scoped labels: set aria-disabled on muted Exclusive option for a11y (#23306) (#23311) Backport #23306 It is convenient to be able to toggle off this option after removing / from the name. This ensures the muted state is communicated to blind users even when the input is not fully disabled. Part of #22974 Co-authored-by: Brecht Van Lommel Co-authored-by: Lunny Xiao --- web_src/js/features/comp/LabelEdit.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/web_src/js/features/comp/LabelEdit.js b/web_src/js/features/comp/LabelEdit.js index 313d4068218b..18676d25e6cc 100644 --- a/web_src/js/features/comp/LabelEdit.js +++ b/web_src/js/features/comp/LabelEdit.js @@ -13,6 +13,7 @@ function updateExclusiveLabelEdit(form) { if (isExclusiveScopeName(nameInput.val())) { exclusiveField.removeClass('muted'); + exclusiveField.removeAttr('aria-disabled'); if (exclusiveCheckbox.prop('checked') && exclusiveCheckbox.data('exclusive-warn')) { exclusiveWarning.removeClass('gt-hidden'); } else { @@ -20,6 +21,7 @@ function updateExclusiveLabelEdit(form) { } } else { exclusiveField.addClass('muted'); + exclusiveField.attr('aria-disabled', 'true'); exclusiveWarning.addClass('gt-hidden'); } } From d1d15306d1c760b93d928c4eec09d01e1528b889 Mon Sep 17 00:00:00 2001 From: Giteabot Date: Mon, 6 Mar 2023 03:45:43 -0500 Subject: [PATCH 051/340] Change interactiveBorder to fix popup preview (#23169) (#23314) Backport #23169 Close #23073. Used the solution as reference to the reply: https://github.com/go-gitea/gitea/issues/23073#issuecomment-1440124609 Here made the change inside the `contextpopup.js` because this is where the popup component is created and tippy configuration is given. Co-authored-by: Hester Gong Co-authored-by: Lunny Xiao --- web_src/js/features/contextpopup.js | 1 + 1 file changed, 1 insertion(+) diff --git a/web_src/js/features/contextpopup.js b/web_src/js/features/contextpopup.js index 61f71209083c..7a40e3b8d5b9 100644 --- a/web_src/js/features/contextpopup.js +++ b/web_src/js/features/contextpopup.js @@ -31,6 +31,7 @@ export function initContextPopups() { createTippy(this, { content: el, interactive: true, + interactiveBorder: 5, onShow: () => { el.firstChild.dispatchEvent(new CustomEvent('us-load-context-popup', {detail: {owner, repo, index}})); } From ee3d9330a82d5483b7d832593b6615d3d3a34f31 Mon Sep 17 00:00:00 2001 From: Giteabot Date: Mon, 6 Mar 2023 05:44:02 -0500 Subject: [PATCH 052/340] Update hacking-on-gitea-zh_cn documentation (#23315) (#23323) Backport #23315 This PR fix outdated hacking-on-gitea-zh_cn documentation. Co-authored-by: Lunny Xiao Co-authored-by: Jason Song --- .../doc/developers/hacking-on-gitea.zh-cn.md | 334 +++++++++++++++++- 1 file changed, 320 insertions(+), 14 deletions(-) diff --git a/docs/content/doc/developers/hacking-on-gitea.zh-cn.md b/docs/content/doc/developers/hacking-on-gitea.zh-cn.md index 3e8cd3ec573a..9c9141bf50cd 100644 --- a/docs/content/doc/developers/hacking-on-gitea.zh-cn.md +++ b/docs/content/doc/developers/hacking-on-gitea.zh-cn.md @@ -1,6 +1,6 @@ --- date: "2016-12-01T16:00:00+02:00" -title: "加入 Gitea 开源" +title: "玩转 Gitea" slug: "hacking-on-gitea" weight: 10 toc: false @@ -8,36 +8,342 @@ draft: false menu: sidebar: parent: "developers" - name: "加入 Gitea 开源" + name: "玩转 Gitea" weight: 10 identifier: "hacking-on-gitea" --- # Hacking on Gitea -首先你需要一些运行环境,这和 [从源代码安装]({{< relref "doc/installation/from-source.zh-cn.md" >}}) 相同,如果你还没有设置好,可以先阅读那个章节。 +**目录** -如果你想为 Gitea 贡献代码,你需要 Fork 这个项目并且以 `master` 为开发分支。Gitea 使用 Govendor -来管理依赖,因此所有依赖项都被工具自动 copy 在 vendor 子目录下。用下面的命令来下载源码: +{{< toc >}} -``` -go get -d code.gitea.io/gitea -``` +## 快速入门 + +要获得快速工作的开发环境,您可以使用 Gitpod。 + +[![在 Gitpod 中打开](/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/go-gitea/gitea) + +## 安装 Golang + +您需要 [安装 go]( https://golang.org/doc/install ) 并设置您的 go 环境。 + +接下来,[使用 npm 安装 Node.js](https://nodejs.org/en/download/) ,这是构建 +JavaScript 和 CSS 文件的必要工具。最低支持的 Node.js 版本是 {{< min-node-version >}} +并且推荐使用最新的 LTS 版本。 + +**注意** :当执行需要外部工具的 make 任务时,比如 +`make watch-backend`,Gitea 会自动下载并构建这些必要的组件。为了能够使用这些,你必须 +将 `"$GOPATH"/bin` 目录加入到可执行路径上。如果你不把go bin目录添加到可执行路径你必须手动 +指定可执行程序路径。 -然后你可以在 Github 上 fork [Gitea 项目](https://github.com/go-gitea/gitea),之后可以通过下面的命令进入源码目录: +**注意2** :Go版本 {{< min-go-version >}} 或更高版本是必须的。Gitea 使用 `gofmt` 来 +格式化源代码。然而,`gofmt` 的结果可能因 `go` 的版本而有差异。因此推荐安装我们持续集成使用 +的 Go版本。截至上次更新,Go 版本应该是 {{< go-version >}}。 +## 安装 Make + +Gitea 大量使用 `Make` 来自动化任务和改进开发。本指南涵盖了如何安装 Make。 + +### 在 Linux 上 + +使用包管理器安装。 + +在 Ubuntu/Debian 上: + +```bash +sudo apt-get install make ``` -cd $GOPATH/src/code.gitea.io/gitea + +在 Fedora/RHEL/CentOS 上: + +```bash +sudo yum install make ``` -要创建 pull requests 你还需要在源码中新增一个 remote 指向你 Fork 的地址,直接推送到 origin 的话会告诉你没有写权限: +### 在 Windows 上 + +Make 的这三个发行版都可以在 Windows 上运行: +- [单个二进制构建]( http://www.equation.com/servlet/equation.cmd?fa=make )。复制到某处并添加到 `PATH`。 + - [32 位版本](http://www.equation.com/ftpdir/make/32/make.exe) + - [64 位版本](http://www.equation.com/ftpdir/make/64/make.exe) +- [MinGW-w64](https://www.mingw-w64.org) / [MSYS2](https://www.msys2.org/)。 + - MSYS2 是一个工具和库的集合,为您提供一个易于使用的环境来构建、安装和运行本机 Windows 软件,它包括 MinGW-w64。 + - 在 MingGW-w64 中,二进制文件称为 `mingw32-make.exe` 而不是 `make.exe`。将 `bin` 文件夹添加到 `PATH`。 + - 在 MSYS2 中,您可以直接使用 `make`。请参阅 [MSYS2 移植](https://www.msys2.org/wiki/Porting/)。 + - 要使用 CGO_ENABLED(例如:SQLite3)编译 Gitea,您可能需要使用 [tdm-gcc](https://jmeubank.github.io/tdm-gcc/) 而不是 MSYS2 gcc,因为 MSYS2 gcc 标头缺少一些 Windows -只有 CRT 函数像 _beginthread 一样。 +- [Chocolatey包管理器]( https://chocolatey.org/packages/make )。运行`choco install make` + +**注意** :如果您尝试在 Windows 命令提示符下使用 make 进行构建,您可能会遇到问题。建议使用上述提示(Git bash 或 MinGW),但是如果您只有命令提示符(或可能是 PowerShell),则可以使用 [set](https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/set_1) 命令,例如 `set TAGS=bindata`。 + +## 下载并克隆 Gitea 源代码 + +获取源代码的推荐方法是使用 `git clone`。 + +```bash +git clone https://github.com/go-gitea/gitea ``` + +(自从go modules出现后,不再需要构建 go 项目从 `$GOPATH` 中获取,因此不再推荐使用 `go get` 方法。) + +## 派生 Gitea + +如上所述下载主要的 Gitea 源代码。然后,派生 [Gitea 仓库](https://github.com/go-gitea/gitea), +并为您的本地仓库切换 git 远程源,或添加另一个远程源: + +```bash +# 将原来的 Gitea origin 重命名为 upstream git remote rename origin upstream -git remote add origin git@github.com:/gitea.git +git remote add origin "git@github.com:$GITHUB_USERNAME/gitea.git" git fetch --all --prune ``` -然后你就可以开始开发了。你可以看一下 `Makefile` 的内容。`make test` 可以运行测试程序, `make build` 将生成一个 `gitea` 可运行文件在根目录。如果你的提交比较复杂,尽量多写一些单元测试代码。 +或者: + +```bash +# 为我们的 fork 添加新的远程 +git remote add "$FORK_NAME" "git@github.com:$GITHUB_USERNAME/gitea.git" +git fetch --all --prune +``` + +为了能够创建合并请求,应将分叉存储库添加为 Gitea 本地仓库的远程,否则无法推送更改。 + +## 构建 Gitea(基本) + +看看我们的 +说明 +关于如何 从源代码构建 。 + +从源代码构建的最简单推荐方法是: + +```bash +TAGS="bindata sqlite sqlite_unlock_notify" make build +``` + +`build` 目标将同时执行 `frontend` 和 `backend` 子目标。如果存在 `bindata` 标签,资源文件将被编译成二进制文件。建议在进行前端开发时省略 `bindata` 标签,以便实时反映更改。 + +有关所有可用的 `make` 目标,请参阅 `make help`。另请参阅 [`.drone.yml`](https://github.com/go-gitea/gitea/blob/main/.drone.yml) 以了解我们的持续集成是如何工作的。 + +## 持续构建 + +要在源文件更改时运行并持续构建: + +```bash +# 对于前端和后端 +make watch + +# 或者:只看前端文件(html/js/css) +make watch-frontend + +# 或者:只看后端文件 (go) +make watch-backend +``` + +在 macOS 上,监视所有后端源文件可能会达到默认的打开文件限制,这可以通过当前 shell 的 `ulimit -n 12288` 或所有未来 shell 的 shell 启动文件来增加。 + +### 格式化、代码分析和拼写检查 + +我们的持续集成将拒绝未通过代码检查(包括格式检查、代码分析和拼写检查)的 PR。 + +你应该格式化你的代码: + +```bash +make fmt +``` + +并检查源代码: + +```bash +# lint 前端和后端代码 +make lint +# 仅 lint 后端代码 +make lint-backend +``` + +**注意** :`gofmt` 的结果取决于 `go` 的版本。您应该运行与持续集成相同的 go 版本。 + +### 处理 JS 和 CSS + +前端开发应遵循 [Guidelines for Frontend Development]({{ < 相关参考 "doc/developers/guidelines-frontend.en-us.md" > }}) + +要使用前端资源构建,请使用上面提到的“watch-frontend”目标或只构建一次: + +```bash +make build && ./gitea +``` + +在提交之前,确保 linters 通过: + +```bash +make lint-frontend +``` + +### 配置本地 ElasticSearch 实例 + +使用 docker 启动本地 ElasticSearch 实例: + +```sh +mkdir -p $(pwd) /data/elasticsearch +sudo chown -R 1000:1000 $(pwd) /data/elasticsearch +docker run --rm --memory= "4g" -p 127.0.0.1:9200:9200 -p 127.0.0.1:9300:9300 -e "discovery.type=single-node" -v "$(pwd)/data /elasticsearch:/usr/share/elasticsearch/data" docker.elastic.co/elasticsearch/elasticsearch:7.16.3 +``` + +配置`app.ini`: + +```ini +[indexer] +ISSUE_INDEXER_TYPE = elasticsearch +ISSUE_INDEXER_CONN_STR = http://elastic:changeme@localhost:9200 +REPO_INDEXER_ENABLED = true +REPO_INDEXER_TYPE = elasticsearch +REPO_INDEXER_CONN_STR = http://elastic:changeme@localhost:9200 +``` + +### 构建和添加 SVGs + +SVG 图标是使用 `make svg` 目标构建的,该目标将 `build/generate-svg.js` 中定义的图标源编译到输出目录 `public/img/svg` 中。可以在 `web_src/svg` 目录中添加自定义图标。 + +### 构建 Logo + +Gitea Logo的 PNG 和 SVG 版本是使用 `TAGS="gitea" make generate-images` 目标从单个 SVG 源文件 assets/logo.svg 构建的。要运行它,Node.js 和 npm 必须可用。 + +通过更新 `assets/logo.svg` 并运行 `make generate-images`,同样的过程也可用于从 SVG 源文件生成自定义 Logo PNG。忽略 gitea 编译选项将仅更新用户指定的 LOGO 文件。 + +### 更新 API + +创建新的 API 路由或修改现有的 API 路由时,您**必须** +更新和/或创建 [Swagger](https://swagger.io/docs/specification/2-0/what-is-swagger/) +这些使用 [go-swagger](https://goswagger.io/) 评论的文档。 +[规范]( https://goswagger.io/use/spec.html#annotation-syntax )中描述了这些注释的结构。 +如果您想了解更多有关 Swagger 结构的信息,可以查看 +[Swagger 2.0 文档](https://swagger.io/docs/specification/2-0/basic-structure/) +或与添加新 API 端点的先前 PR 进行比较,例如 [PR #5483](https://github.com/go-gitea/gitea/pull/5843/files#diff-2e0a7b644cf31e1c8ef7d76b444fe3aaR20) + +您应该注意不要破坏下游用户依赖的 API。在稳定的 API 上,一般来说添加是可以接受的,但删除 +或对 API 进行根本性更改将会被拒绝。 + +创建或更改 API 端点后,请用以下命令重新生成 Swagger 文档: + +```bash +make generate-swagger +``` + +您应该验证生成的 Swagger 文件并使用以下命令对其进行拼写检查: + +```bash +make swagger-validate misspell-check +``` + +您应该提交更改后的 swagger JSON 文件。持续集成服务器将使用以下方法检查是否已完成: + +```bash +make swagger-check +``` + +**注意** :请注意,您应该使用 Swagger 2.0 文档,而不是 OpenAPI 3 文档。 + +### 创建新的配置选项 + +创建新的配置选项时,将它们添加到 `modules/setting` 的对应文件。您应该将信息添加到 `custom/conf/app.ini` +并到 配置备忘单 +在 `docs/content/doc/advanced/config-cheat-sheet.en-us.md` 中找到 + +### 更改Logo + +更改 Gitea Logo SVG 时,您将需要运行并提交结果的: + +```bash +make generate-images +``` + +这将创建必要的 Gitea 图标和其他图标。 + +### 数据库迁移 + +如果您对数据库中的任何数据库持久结构进行重大更改 +`models/` 目录,您将需要进行新的迁移。可以找到这些 +在 `models/migrations/` 中。您可以确保您的迁移适用于主要 +数据库类型使用: + +```bash +make test-sqlite-migration # 将 SQLite 切换为适当的数据库 +``` + +## 测试 + +Gitea 运行两种类型的测试:单元测试和集成测试。 + +### 单元测试 + +`go test` 系统中的`*_test.go` 涵盖了单元测试。 +您可以设置环境变量 `GITEA_UNIT_TESTS_LOG_SQL=1` 以在详细模式下运行测试时显示所有 SQL 语句(即设置`GOTESTFLAGS=-v` 时)。 + +```bash +TAGS="bindata sqlite sqlite_unlock_notify" make test # Runs the unit tests +``` + +### 集成测试 + +单元测试不会也不能完全单独测试 Gitea。因此,我们编写了集成测试;但是,这些依赖于数据库。 + +```bash +TAGS="bindata sqlite sqlite_unlock_notify" make build test-sqlite +``` + +将在 SQLite 环境中运行集成测试。集成测试需要安装 `git lfs`。其他数据库测试可用,但 +可能需要适应当地环境。 + +看看 [`tests/integration/README.md`](https://github.com/go-gitea/gitea/blob/main/tests/integration/README.md) 有关更多信息以及如何运行单个测试。 + +### 测试 PR + +我们的持续集成将测试代码是否通过了单元测试,并且所有支持的数据库都将在 Docker 环境中通过集成测试。 +还将测试从几个最新版本的 Gitea 迁移。 + +请在PR中附带提交适当的单元测试和集成测试。 + +## 网站文档 + +该网站的文档位于 `docs/` 中。如果你改变了文档内容,你可以使用以下测试方法进行持续集成: + +```bash +# 来自 Gitea 中的 docs 目录 +make trans-copy clean build +``` + +运行此任务依赖于 [Hugo](https://gohugo.io/)。请注意:这可能会生成一些未跟踪的 Git 对象, +需要被清理干净。 + +## Visual Studio Code + +`contrib/ide/vscode` 中为 Visual Studio Code 提供了 `launch.json` 和 `tasks.json`。查看 +[`contrib/ide/README.md`](https://github.com/go-gitea/gitea/blob/main/contrib/ide/README.md) 了解更多信息。 + +## Goland + +单击 `/main.go` 中函数 `func main()` 上的 `Run Application` 箭头 +可以快速启动一个可调试的 Gitea 实例。 + +`Run/Debug Configuration` 中的 `Output Directory` 必须设置为 +gitea 项目目录(包含 `main.go` 和 `go.mod`), +否则,启动实例的工作目录是 GoLand 的临时目录 +并防止 Gitea 在开发环境中加载动态资源(例如:模板)。 + +要在 GoLand 中使用 SQLite 运行单元测试,请设置 `-tags sqlite,sqlite_unlock_notify` +在 `运行/调试配置` 的 `Go 工具参数` 中。 + +## 提交 PR + +对更改感到满意后,将它们推送并打开拉取请求。它建议您允许 Gitea Managers 和 Owners 修改您的 PR +分支,因为我们需要在合并之前将其更新为 main 和/或可能是能够直接帮助解决问题。 + +任何 PR 都需要 Gitea 维护者的两次批准,并且需要通过持续集成。看看我们的 +[CONTRIBUTING.md](https://github.com/go-gitea/gitea/blob/main/CONTRIBUTING.md) +文档。 + +如果您需要更多帮助,请访问 [Discord](https://discord.gg/gitea) #Develop 频道 +并在那里聊天。 -好了,到这里你已经设置好了所有的开发 Gitea 所需的环境。欢迎成为 Gitea 的 Contributor。 +现在,您已准备好 Hacking Gitea。 From b1e68f39e737f6d130ffa8b423ee7da3075b12d7 Mon Sep 17 00:00:00 2001 From: Giteabot Date: Mon, 6 Mar 2023 09:35:07 -0500 Subject: [PATCH 053/340] Properly flush unique queues on startup (#23154) (#23201) Backport #23154 There have been a number of reports of PRs being blocked whilst being checked which have been difficult to debug. In investigating #23050 I have realised that whilst the Warn there is somewhat of a miscall there was a real bug in the way that the LevelUniqueQueue was being restored on start-up of the PersistableChannelUniqueQueue. Next there is a conflict in the setting of the internal leveldb queue name - This wasn't being set so it was being overridden by other unique queues. This PR fixes these bugs and adds a testcase. Thanks to @brechtvl for noticing the second issue. Fix #23050 and others Signed-off-by: Andrew Thornton Co-authored-by: zeripath Co-authored-by: techknowlogick Co-authored-by: delvh --- modules/queue/queue_channel.go | 5 +- modules/queue/queue_disk_channel.go | 29 +- modules/queue/queue_disk_channel_test.go | 8 +- modules/queue/unique_queue_channel.go | 4 +- modules/queue/unique_queue_channel_test.go | 7 + modules/queue/unique_queue_disk_channel.go | 41 ++- .../queue/unique_queue_disk_channel_test.go | 259 ++++++++++++++++++ 7 files changed, 332 insertions(+), 21 deletions(-) create mode 100644 modules/queue/unique_queue_disk_channel_test.go diff --git a/modules/queue/queue_channel.go b/modules/queue/queue_channel.go index 6f75b8357eab..baac09739395 100644 --- a/modules/queue/queue_channel.go +++ b/modules/queue/queue_channel.go @@ -124,7 +124,10 @@ func (q *ChannelQueue) Shutdown() { log.Trace("ChannelQueue: %s Flushing", q.name) // We can't use Cleanup here because that will close the channel if err := q.FlushWithContext(q.terminateCtx); err != nil { - log.Warn("ChannelQueue: %s Terminated before completed flushing", q.name) + count := atomic.LoadInt64(&q.numInQueue) + if count > 0 { + log.Warn("ChannelQueue: %s Terminated before completed flushing", q.name) + } return } log.Debug("ChannelQueue: %s Flushed", q.name) diff --git a/modules/queue/queue_disk_channel.go b/modules/queue/queue_disk_channel.go index c7526714c65c..91f91f0dfc80 100644 --- a/modules/queue/queue_disk_channel.go +++ b/modules/queue/queue_disk_channel.go @@ -94,7 +94,8 @@ func NewPersistableChannelQueue(handle HandlerFunc, cfg, exemplar interface{}) ( }, Workers: 0, }, - DataDir: config.DataDir, + DataDir: config.DataDir, + QueueName: config.Name + "-level", } levelQueue, err := NewLevelQueue(wrappedHandle, levelCfg, exemplar) @@ -172,16 +173,18 @@ func (q *PersistableChannelQueue) Run(atShutdown, atTerminate func(func())) { atShutdown(q.Shutdown) atTerminate(q.Terminate) - if lq, ok := q.internal.(*LevelQueue); ok && lq.byteFIFO.Len(lq.shutdownCtx) != 0 { + if lq, ok := q.internal.(*LevelQueue); ok && lq.byteFIFO.Len(lq.terminateCtx) != 0 { // Just run the level queue - we shut it down once it's flushed go q.internal.Run(func(_ func()) {}, func(_ func()) {}) go func() { - for !q.IsEmpty() { - _ = q.internal.Flush(0) + for !lq.IsEmpty() { + _ = lq.Flush(0) select { case <-time.After(100 * time.Millisecond): - case <-q.internal.(*LevelQueue).shutdownCtx.Done(): - log.Warn("LevelQueue: %s shut down before completely flushed", q.internal.(*LevelQueue).Name()) + case <-lq.shutdownCtx.Done(): + if lq.byteFIFO.Len(lq.terminateCtx) > 0 { + log.Warn("LevelQueue: %s shut down before completely flushed", q.internal.(*LevelQueue).Name()) + } return } } @@ -316,10 +319,22 @@ func (q *PersistableChannelQueue) Shutdown() { // Redirect all remaining data in the chan to the internal channel log.Trace("PersistableChannelQueue: %s Redirecting remaining data", q.delayedStarter.name) close(q.channelQueue.dataChan) + countOK, countLost := 0, 0 for data := range q.channelQueue.dataChan { - _ = q.internal.Push(data) + err := q.internal.Push(data) + if err != nil { + log.Error("PersistableChannelQueue: %s Unable redirect %v due to: %v", q.delayedStarter.name, data, err) + countLost++ + } else { + countOK++ + } atomic.AddInt64(&q.channelQueue.numInQueue, -1) } + if countLost > 0 { + log.Warn("PersistableChannelQueue: %s %d will be restored on restart, %d lost", q.delayedStarter.name, countOK, countLost) + } else if countOK > 0 { + log.Warn("PersistableChannelQueue: %s %d will be restored on restart", q.delayedStarter.name, countOK) + } log.Trace("PersistableChannelQueue: %s Done Redirecting remaining data", q.delayedStarter.name) log.Debug("PersistableChannelQueue: %s Shutdown", q.delayedStarter.name) diff --git a/modules/queue/queue_disk_channel_test.go b/modules/queue/queue_disk_channel_test.go index 318610355e43..4f14a5d79df9 100644 --- a/modules/queue/queue_disk_channel_test.go +++ b/modules/queue/queue_disk_channel_test.go @@ -39,7 +39,7 @@ func TestPersistableChannelQueue(t *testing.T) { Workers: 1, BoostWorkers: 0, MaxWorkers: 10, - Name: "first", + Name: "test-queue", }, &testData{}) assert.NoError(t, err) @@ -135,7 +135,7 @@ func TestPersistableChannelQueue(t *testing.T) { Workers: 1, BoostWorkers: 0, MaxWorkers: 10, - Name: "second", + Name: "test-queue", }, &testData{}) assert.NoError(t, err) @@ -227,7 +227,7 @@ func TestPersistableChannelQueue_Pause(t *testing.T) { Workers: 1, BoostWorkers: 0, MaxWorkers: 10, - Name: "first", + Name: "test-queue", }, &testData{}) assert.NoError(t, err) @@ -433,7 +433,7 @@ func TestPersistableChannelQueue_Pause(t *testing.T) { Workers: 1, BoostWorkers: 0, MaxWorkers: 10, - Name: "second", + Name: "test-queue", }, &testData{}) assert.NoError(t, err) pausable, ok = queue.(Pausable) diff --git a/modules/queue/unique_queue_channel.go b/modules/queue/unique_queue_channel.go index c43bd1db3f7d..62c051aa3935 100644 --- a/modules/queue/unique_queue_channel.go +++ b/modules/queue/unique_queue_channel.go @@ -177,7 +177,9 @@ func (q *ChannelUniqueQueue) Shutdown() { go func() { log.Trace("ChannelUniqueQueue: %s Flushing", q.name) if err := q.FlushWithContext(q.terminateCtx); err != nil { - log.Warn("ChannelUniqueQueue: %s Terminated before completed flushing", q.name) + if !q.IsEmpty() { + log.Warn("ChannelUniqueQueue: %s Terminated before completed flushing", q.name) + } return } log.Debug("ChannelUniqueQueue: %s Flushed", q.name) diff --git a/modules/queue/unique_queue_channel_test.go b/modules/queue/unique_queue_channel_test.go index 9372694b87a6..824015b834fe 100644 --- a/modules/queue/unique_queue_channel_test.go +++ b/modules/queue/unique_queue_channel_test.go @@ -8,10 +8,13 @@ import ( "testing" "time" + "code.gitea.io/gitea/modules/log" + "github.com/stretchr/testify/assert" ) func TestChannelUniqueQueue(t *testing.T) { + _ = log.NewLogger(1000, "console", "console", `{"level":"warn","stacktracelevel":"NONE","stderr":true}`) handleChan := make(chan *testData) handle := func(data ...Data) []Data { for _, datum := range data { @@ -52,6 +55,8 @@ func TestChannelUniqueQueue(t *testing.T) { } func TestChannelUniqueQueue_Batch(t *testing.T) { + _ = log.NewLogger(1000, "console", "console", `{"level":"warn","stacktracelevel":"NONE","stderr":true}`) + handleChan := make(chan *testData) handle := func(data ...Data) []Data { for _, datum := range data { @@ -98,6 +103,8 @@ func TestChannelUniqueQueue_Batch(t *testing.T) { } func TestChannelUniqueQueue_Pause(t *testing.T) { + _ = log.NewLogger(1000, "console", "console", `{"level":"warn","stacktracelevel":"NONE","stderr":true}`) + lock := sync.Mutex{} var queue Queue var err error diff --git a/modules/queue/unique_queue_disk_channel.go b/modules/queue/unique_queue_disk_channel.go index 405726182dcb..cc8a807c6723 100644 --- a/modules/queue/unique_queue_disk_channel.go +++ b/modules/queue/unique_queue_disk_channel.go @@ -94,7 +94,8 @@ func NewPersistableChannelUniqueQueue(handle HandlerFunc, cfg, exemplar interfac }, Workers: 0, }, - DataDir: config.DataDir, + DataDir: config.DataDir, + QueueName: config.Name + "-level", } queue.channelQueue = channelUniqueQueue.(*ChannelUniqueQueue) @@ -209,17 +210,29 @@ func (q *PersistableChannelUniqueQueue) Run(atShutdown, atTerminate func(func()) atTerminate(q.Terminate) _ = q.channelQueue.AddWorkers(q.channelQueue.workers, 0) - if luq, ok := q.internal.(*LevelUniqueQueue); ok && luq.ByteFIFOUniqueQueue.byteFIFO.Len(luq.shutdownCtx) != 0 { + if luq, ok := q.internal.(*LevelUniqueQueue); ok && !luq.IsEmpty() { // Just run the level queue - we shut it down once it's flushed - go q.internal.Run(func(_ func()) {}, func(_ func()) {}) + go luq.Run(func(_ func()) {}, func(_ func()) {}) go func() { - _ = q.internal.Flush(0) - log.Debug("LevelUniqueQueue: %s flushed so shutting down", q.internal.(*LevelUniqueQueue).Name()) - q.internal.(*LevelUniqueQueue).Shutdown() - GetManager().Remove(q.internal.(*LevelUniqueQueue).qid) + _ = luq.Flush(0) + for !luq.IsEmpty() { + _ = luq.Flush(0) + select { + case <-time.After(100 * time.Millisecond): + case <-luq.shutdownCtx.Done(): + if luq.byteFIFO.Len(luq.terminateCtx) > 0 { + log.Warn("LevelUniqueQueue: %s shut down before completely flushed", luq.Name()) + } + return + } + } + log.Debug("LevelUniqueQueue: %s flushed so shutting down", luq.Name()) + luq.Shutdown() + GetManager().Remove(luq.qid) }() } else { log.Debug("PersistableChannelUniqueQueue: %s Skipping running the empty level queue", q.delayedStarter.name) + _ = q.internal.Flush(0) q.internal.(*LevelUniqueQueue).Shutdown() GetManager().Remove(q.internal.(*LevelUniqueQueue).qid) } @@ -285,8 +298,20 @@ func (q *PersistableChannelUniqueQueue) Shutdown() { // Redirect all remaining data in the chan to the internal channel close(q.channelQueue.dataChan) log.Trace("PersistableChannelUniqueQueue: %s Redirecting remaining data", q.delayedStarter.name) + countOK, countLost := 0, 0 for data := range q.channelQueue.dataChan { - _ = q.internal.Push(data) + err := q.internal.(*LevelUniqueQueue).Push(data) + if err != nil { + log.Error("PersistableChannelUniqueQueue: %s Unable redirect %v due to: %v", q.delayedStarter.name, data, err) + countLost++ + } else { + countOK++ + } + } + if countLost > 0 { + log.Warn("PersistableChannelUniqueQueue: %s %d will be restored on restart, %d lost", q.delayedStarter.name, countOK, countLost) + } else if countOK > 0 { + log.Warn("PersistableChannelUniqueQueue: %s %d will be restored on restart", q.delayedStarter.name, countOK) } log.Trace("PersistableChannelUniqueQueue: %s Done Redirecting remaining data", q.delayedStarter.name) diff --git a/modules/queue/unique_queue_disk_channel_test.go b/modules/queue/unique_queue_disk_channel_test.go new file mode 100644 index 000000000000..fd76163f4aac --- /dev/null +++ b/modules/queue/unique_queue_disk_channel_test.go @@ -0,0 +1,259 @@ +// Copyright 2023 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package queue + +import ( + "fmt" + "strconv" + "sync" + "testing" + "time" + + "code.gitea.io/gitea/modules/log" + + "github.com/stretchr/testify/assert" +) + +func TestPersistableChannelUniqueQueue(t *testing.T) { + tmpDir := t.TempDir() + fmt.Printf("TempDir %s\n", tmpDir) + _ = log.NewLogger(1000, "console", "console", `{"level":"warn","stacktracelevel":"NONE","stderr":true}`) + + // Common function to create the Queue + newQueue := func(name string, handle func(data ...Data) []Data) Queue { + q, err := NewPersistableChannelUniqueQueue(handle, + PersistableChannelUniqueQueueConfiguration{ + Name: name, + DataDir: tmpDir, + QueueLength: 200, + MaxWorkers: 1, + BlockTimeout: 1 * time.Second, + BoostTimeout: 5 * time.Minute, + BoostWorkers: 1, + Workers: 0, + }, "task-0") + assert.NoError(t, err) + return q + } + + // runs the provided queue and provides some timer function + type channels struct { + readyForShutdown chan struct{} // closed when shutdown functions have been assigned + readyForTerminate chan struct{} // closed when terminate functions have been assigned + signalShutdown chan struct{} // Should close to signal shutdown + doneShutdown chan struct{} // closed when shutdown function is done + queueTerminate []func() // list of atTerminate functions to call atTerminate - need to be accessed with lock + } + runQueue := func(q Queue, lock *sync.Mutex) *channels { + chans := &channels{ + readyForShutdown: make(chan struct{}), + readyForTerminate: make(chan struct{}), + signalShutdown: make(chan struct{}), + doneShutdown: make(chan struct{}), + } + go q.Run(func(atShutdown func()) { + go func() { + lock.Lock() + select { + case <-chans.readyForShutdown: + default: + close(chans.readyForShutdown) + } + lock.Unlock() + <-chans.signalShutdown + atShutdown() + close(chans.doneShutdown) + }() + }, func(atTerminate func()) { + lock.Lock() + defer lock.Unlock() + select { + case <-chans.readyForTerminate: + default: + close(chans.readyForTerminate) + } + chans.queueTerminate = append(chans.queueTerminate, atTerminate) + }) + + return chans + } + + // call to shutdown and terminate the queue associated with the channels + doTerminate := func(chans *channels, lock *sync.Mutex) { + <-chans.readyForTerminate + + lock.Lock() + callbacks := []func(){} + callbacks = append(callbacks, chans.queueTerminate...) + lock.Unlock() + + for _, callback := range callbacks { + callback() + } + } + + mapLock := sync.Mutex{} + executedInitial := map[string][]string{} + hasInitial := map[string][]string{} + + fillQueue := func(name string, done chan struct{}) { + t.Run("Initial Filling: "+name, func(t *testing.T) { + lock := sync.Mutex{} + + startAt100Queued := make(chan struct{}) + stopAt20Shutdown := make(chan struct{}) // stop and shutdown at the 20th item + + handle := func(data ...Data) []Data { + <-startAt100Queued + for _, datum := range data { + s := datum.(string) + mapLock.Lock() + executedInitial[name] = append(executedInitial[name], s) + mapLock.Unlock() + if s == "task-20" { + close(stopAt20Shutdown) + } + } + return nil + } + + q := newQueue(name, handle) + + // add 100 tasks to the queue + for i := 0; i < 100; i++ { + _ = q.Push("task-" + strconv.Itoa(i)) + } + close(startAt100Queued) + + chans := runQueue(q, &lock) + + <-chans.readyForShutdown + <-stopAt20Shutdown + close(chans.signalShutdown) + <-chans.doneShutdown + _ = q.Push("final") + + // check which tasks are still in the queue + for i := 0; i < 100; i++ { + if has, _ := q.(UniqueQueue).Has("task-" + strconv.Itoa(i)); has { + mapLock.Lock() + hasInitial[name] = append(hasInitial[name], "task-"+strconv.Itoa(i)) + mapLock.Unlock() + } + } + if has, _ := q.(UniqueQueue).Has("final"); has { + mapLock.Lock() + hasInitial[name] = append(hasInitial[name], "final") + mapLock.Unlock() + } else { + assert.Fail(t, "UnqueQueue %s should have \"final\"", name) + } + doTerminate(chans, &lock) + mapLock.Lock() + assert.Equal(t, 101, len(executedInitial[name])+len(hasInitial[name])) + mapLock.Unlock() + }) + close(done) + } + + doneA := make(chan struct{}) + doneB := make(chan struct{}) + + go fillQueue("QueueA", doneA) + go fillQueue("QueueB", doneB) + + <-doneA + <-doneB + + executedEmpty := map[string][]string{} + hasEmpty := map[string][]string{} + emptyQueue := func(name string, done chan struct{}) { + t.Run("Empty Queue: "+name, func(t *testing.T) { + lock := sync.Mutex{} + stop := make(chan struct{}) + + // collect the tasks that have been executed + handle := func(data ...Data) []Data { + lock.Lock() + for _, datum := range data { + mapLock.Lock() + executedEmpty[name] = append(executedEmpty[name], datum.(string)) + mapLock.Unlock() + if datum.(string) == "final" { + close(stop) + } + } + lock.Unlock() + return nil + } + + q := newQueue(name, handle) + chans := runQueue(q, &lock) + + <-chans.readyForShutdown + <-stop + close(chans.signalShutdown) + <-chans.doneShutdown + + // check which tasks are still in the queue + for i := 0; i < 100; i++ { + if has, _ := q.(UniqueQueue).Has("task-" + strconv.Itoa(i)); has { + mapLock.Lock() + hasEmpty[name] = append(hasEmpty[name], "task-"+strconv.Itoa(i)) + mapLock.Unlock() + } + } + doTerminate(chans, &lock) + + mapLock.Lock() + assert.Equal(t, 101, len(executedInitial[name])+len(executedEmpty[name])) + assert.Equal(t, 0, len(hasEmpty[name])) + mapLock.Unlock() + }) + close(done) + } + + doneA = make(chan struct{}) + doneB = make(chan struct{}) + + go emptyQueue("QueueA", doneA) + go emptyQueue("QueueB", doneB) + + <-doneA + <-doneB + + mapLock.Lock() + t.Logf("TestPersistableChannelUniqueQueue executedInitiallyA=%v, executedInitiallyB=%v, executedToEmptyA=%v, executedToEmptyB=%v", + len(executedInitial["QueueA"]), len(executedInitial["QueueB"]), len(executedEmpty["QueueA"]), len(executedEmpty["QueueB"])) + + // reset and rerun + executedInitial = map[string][]string{} + hasInitial = map[string][]string{} + executedEmpty = map[string][]string{} + hasEmpty = map[string][]string{} + mapLock.Unlock() + + doneA = make(chan struct{}) + doneB = make(chan struct{}) + + go fillQueue("QueueA", doneA) + go fillQueue("QueueB", doneB) + + <-doneA + <-doneB + + doneA = make(chan struct{}) + doneB = make(chan struct{}) + + go emptyQueue("QueueA", doneA) + go emptyQueue("QueueB", doneB) + + <-doneA + <-doneB + + mapLock.Lock() + t.Logf("TestPersistableChannelUniqueQueue executedInitiallyA=%v, executedInitiallyB=%v, executedToEmptyA=%v, executedToEmptyB=%v", + len(executedInitial["QueueA"]), len(executedInitial["QueueB"]), len(executedEmpty["QueueA"]), len(executedEmpty["QueueB"])) + mapLock.Unlock() +} From dcf1717793f92dc11ea3d65ef0f3bb25243905e6 Mon Sep 17 00:00:00 2001 From: Giteabot Date: Mon, 6 Mar 2023 11:32:40 -0500 Subject: [PATCH 054/340] Add context when rendering labels or emojis (#23281) (#23319) Backport #23281 This branch continues the work of #23092 and attempts to rid the codebase of any `nil` contexts when using a `RenderContext`. Anything that renders markdown or does post processing may call `markup.sha1CurrentPatternProcessor()`, and this runs `git.OpenRepository()`, which needs a context. It will panic if the context is `nil`. This branch attempts to _always_ include a context when creating a `RenderContext` to prevent future crashes. Co-authored-by: Jonathan Tran --- modules/csv/csv_test.go | 6 ++- modules/markup/console/console_test.go | 4 +- modules/markup/csv/csv_test.go | 4 +- modules/markup/html.go | 3 +- modules/markup/html_internal_test.go | 43 +++++++++++++++---- modules/markup/html_test.go | 14 ++++++ modules/markup/markdown/markdown_test.go | 23 ++++++---- modules/markup/orgmode/orgmode_test.go | 4 ++ modules/templates/helper.go | 21 ++++----- templates/projects/view.tmpl | 2 +- templates/repo/activity.tmpl | 14 +++--- templates/repo/commits_list.tmpl | 2 +- templates/repo/issue/labels/label.tmpl | 2 +- templates/repo/issue/labels/label_list.tmpl | 8 ++-- templates/repo/issue/list.tmpl | 4 +- templates/repo/issue/milestone_issues.tmpl | 4 +- templates/repo/issue/new_form.tmpl | 8 ++-- .../repo/issue/view_content/comments.tmpl | 8 ++-- .../repo/issue/view_content/sidebar.tmpl | 16 +++---- templates/repo/projects/view.tmpl | 2 +- templates/repo/settings/lfs_file_find.tmpl | 2 +- templates/shared/issuelist.tmpl | 4 +- templates/user/dashboard/feeds.tmpl | 14 +++--- 23 files changed, 136 insertions(+), 76 deletions(-) diff --git a/modules/csv/csv_test.go b/modules/csv/csv_test.go index c627597fa3c9..6b91a81fc479 100644 --- a/modules/csv/csv_test.go +++ b/modules/csv/csv_test.go @@ -11,6 +11,7 @@ import ( "strings" "testing" + "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/markup" "github.com/stretchr/testify/assert" @@ -229,7 +230,10 @@ John Doe john@doe.com This,note,had,a,lot,of,commas,to,test,delimiters`, } for n, c := range cases { - delimiter := determineDelimiter(&markup.RenderContext{RelativePath: c.filename}, []byte(decodeSlashes(t, c.csv))) + delimiter := determineDelimiter(&markup.RenderContext{ + Ctx: git.DefaultContext, + RelativePath: c.filename, + }, []byte(decodeSlashes(t, c.csv))) assert.EqualValues(t, c.expectedDelimiter, delimiter, "case %d: delimiter should be equal, expected '%c' got '%c'", n, c.expectedDelimiter, delimiter) } } diff --git a/modules/markup/console/console_test.go b/modules/markup/console/console_test.go index 506f86194cb9..2337d91ac544 100644 --- a/modules/markup/console/console_test.go +++ b/modules/markup/console/console_test.go @@ -7,6 +7,7 @@ import ( "strings" "testing" + "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/markup" "github.com/stretchr/testify/assert" @@ -23,7 +24,8 @@ func TestRenderConsole(t *testing.T) { canRender := render.CanRender("test", strings.NewReader(k)) assert.True(t, canRender) - err := render.Render(&markup.RenderContext{}, strings.NewReader(k), &buf) + err := render.Render(&markup.RenderContext{Ctx: git.DefaultContext}, + strings.NewReader(k), &buf) assert.NoError(t, err) assert.EqualValues(t, v, buf.String()) } diff --git a/modules/markup/csv/csv_test.go b/modules/markup/csv/csv_test.go index b9f5769be28b..8c07184b21ee 100644 --- a/modules/markup/csv/csv_test.go +++ b/modules/markup/csv/csv_test.go @@ -7,6 +7,7 @@ import ( "strings" "testing" + "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/markup" "github.com/stretchr/testify/assert" @@ -23,7 +24,8 @@ func TestRenderCSV(t *testing.T) { for k, v := range kases { var buf strings.Builder - err := render.Render(&markup.RenderContext{}, strings.NewReader(k), &buf) + err := render.Render(&markup.RenderContext{Ctx: git.DefaultContext}, + strings.NewReader(k), &buf) assert.NoError(t, err) assert.EqualValues(t, v, buf.String()) } diff --git a/modules/markup/html.go b/modules/markup/html.go index bcb38f99eb4a..76fc54cf465e 100644 --- a/modules/markup/html.go +++ b/modules/markup/html.go @@ -291,9 +291,10 @@ func RenderDescriptionHTML( // RenderEmoji for when we want to just process emoji and shortcodes // in various places it isn't already run through the normal markdown processor func RenderEmoji( + ctx *RenderContext, content string, ) (string, error) { - return renderProcessString(&RenderContext{}, emojiProcessors, content) + return renderProcessString(ctx, emojiProcessors, content) } var ( diff --git a/modules/markup/html_internal_test.go b/modules/markup/html_internal_test.go index 6746c40d1831..a048f1f52788 100644 --- a/modules/markup/html_internal_test.go +++ b/modules/markup/html_internal_test.go @@ -9,6 +9,7 @@ import ( "strings" "testing" + "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" @@ -70,8 +71,13 @@ var localMetas = map[string]string{ func TestRender_IssueIndexPattern(t *testing.T) { // numeric: render inputs without valid mentions test := func(s string) { - testRenderIssueIndexPattern(t, s, s, &RenderContext{}) - testRenderIssueIndexPattern(t, s, s, &RenderContext{Metas: numericMetas}) + testRenderIssueIndexPattern(t, s, s, &RenderContext{ + Ctx: git.DefaultContext, + }) + testRenderIssueIndexPattern(t, s, s, &RenderContext{ + Ctx: git.DefaultContext, + Metas: numericMetas, + }) } // should not render anything when there are no mentions @@ -119,7 +125,10 @@ func TestRender_IssueIndexPattern2(t *testing.T) { links[i] = numericIssueLink(util.URLJoin(TestRepoURL, path), "ref-issue", index, marker) } expectedNil := fmt.Sprintf(expectedFmt, links...) - testRenderIssueIndexPattern(t, s, expectedNil, &RenderContext{Metas: localMetas}) + testRenderIssueIndexPattern(t, s, expectedNil, &RenderContext{ + Ctx: git.DefaultContext, + Metas: localMetas, + }) class := "ref-issue" if isExternal { @@ -130,7 +139,10 @@ func TestRender_IssueIndexPattern2(t *testing.T) { links[i] = numericIssueLink(prefix, class, index, marker) } expectedNum := fmt.Sprintf(expectedFmt, links...) - testRenderIssueIndexPattern(t, s, expectedNum, &RenderContext{Metas: numericMetas}) + testRenderIssueIndexPattern(t, s, expectedNum, &RenderContext{ + Ctx: git.DefaultContext, + Metas: numericMetas, + }) } // should render freestanding mentions @@ -164,7 +176,10 @@ func TestRender_IssueIndexPattern3(t *testing.T) { // alphanumeric: render inputs without valid mentions test := func(s string) { - testRenderIssueIndexPattern(t, s, s, &RenderContext{Metas: alphanumericMetas}) + testRenderIssueIndexPattern(t, s, s, &RenderContext{ + Ctx: git.DefaultContext, + Metas: alphanumericMetas, + }) } test("") test("this is a test") @@ -194,7 +209,10 @@ func TestRender_IssueIndexPattern4(t *testing.T) { links[i] = externalIssueLink("https://someurl.com/someUser/someRepo/", "ref-issue ref-external-issue", name) } expected := fmt.Sprintf(expectedFmt, links...) - testRenderIssueIndexPattern(t, s, expected, &RenderContext{Metas: alphanumericMetas}) + testRenderIssueIndexPattern(t, s, expected, &RenderContext{ + Ctx: git.DefaultContext, + Metas: alphanumericMetas, + }) } test("OTT-1234 test", "%s test", "OTT-1234") test("test T-12 issue", "test %s issue", "T-12") @@ -214,7 +232,10 @@ func TestRender_IssueIndexPattern5(t *testing.T) { } expected := fmt.Sprintf(expectedFmt, links...) - testRenderIssueIndexPattern(t, s, expected, &RenderContext{Metas: metas}) + testRenderIssueIndexPattern(t, s, expected, &RenderContext{ + Ctx: git.DefaultContext, + Metas: metas, + }) } test("abc ISSUE-123 def", "abc %s def", @@ -235,7 +256,10 @@ func TestRender_IssueIndexPattern5(t *testing.T) { []string{"ISSUE-123"}, ) - testRenderIssueIndexPattern(t, "will not match", "will not match", &RenderContext{Metas: regexpMetas}) + testRenderIssueIndexPattern(t, "will not match", "will not match", &RenderContext{ + Ctx: git.DefaultContext, + Metas: regexpMetas, + }) } func testRenderIssueIndexPattern(t *testing.T, input, expected string, ctx *RenderContext) { @@ -255,6 +279,7 @@ func TestRender_AutoLink(t *testing.T) { test := func(input, expected string) { var buffer strings.Builder err := PostProcess(&RenderContext{ + Ctx: git.DefaultContext, URLPrefix: TestRepoURL, Metas: localMetas, }, strings.NewReader(input), &buffer) @@ -263,6 +288,7 @@ func TestRender_AutoLink(t *testing.T) { buffer.Reset() err = PostProcess(&RenderContext{ + Ctx: git.DefaultContext, URLPrefix: TestRepoURL, Metas: localMetas, IsWiki: true, @@ -292,6 +318,7 @@ func TestRender_FullIssueURLs(t *testing.T) { test := func(input, expected string) { var result strings.Builder err := postProcess(&RenderContext{ + Ctx: git.DefaultContext, URLPrefix: TestRepoURL, Metas: localMetas, }, []processor{fullIssuePatternProcessor}, strings.NewReader(input), &result) diff --git a/modules/markup/html_test.go b/modules/markup/html_test.go index aea1d9267682..f8b84485c06d 100644 --- a/modules/markup/html_test.go +++ b/modules/markup/html_test.go @@ -91,6 +91,7 @@ func TestRender_CrossReferences(t *testing.T) { test := func(input, expected string) { buffer, err := RenderString(&RenderContext{ + Ctx: git.DefaultContext, RelativePath: "a.md", URLPrefix: setting.AppSubURL, Metas: localMetas, @@ -135,6 +136,7 @@ func TestRender_links(t *testing.T) { test := func(input, expected string) { buffer, err := RenderString(&RenderContext{ + Ctx: git.DefaultContext, RelativePath: "a.md", URLPrefix: TestRepoURL, }, input) @@ -234,6 +236,7 @@ func TestRender_email(t *testing.T) { test := func(input, expected string) { res, err := RenderString(&RenderContext{ + Ctx: git.DefaultContext, RelativePath: "a.md", URLPrefix: TestRepoURL, }, input) @@ -292,6 +295,7 @@ func TestRender_emoji(t *testing.T) { test := func(input, expected string) { expected = strings.ReplaceAll(expected, "&", "&") buffer, err := RenderString(&RenderContext{ + Ctx: git.DefaultContext, RelativePath: "a.md", URLPrefix: TestRepoURL, }, input) @@ -355,11 +359,13 @@ func TestRender_ShortLinks(t *testing.T) { test := func(input, expected, expectedWiki string) { buffer, err := markdown.RenderString(&RenderContext{ + Ctx: git.DefaultContext, URLPrefix: tree, }, input) assert.NoError(t, err) assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(buffer)) buffer, err = markdown.RenderString(&RenderContext{ + Ctx: git.DefaultContext, URLPrefix: TestRepoURL, Metas: localMetas, IsWiki: true, @@ -461,12 +467,14 @@ func TestRender_RelativeImages(t *testing.T) { test := func(input, expected, expectedWiki string) { buffer, err := markdown.RenderString(&RenderContext{ + Ctx: git.DefaultContext, URLPrefix: tree, Metas: localMetas, }, input) assert.NoError(t, err) assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(buffer)) buffer, err = markdown.RenderString(&RenderContext{ + Ctx: git.DefaultContext, URLPrefix: TestRepoURL, Metas: localMetas, IsWiki: true, @@ -501,6 +509,7 @@ func Test_ParseClusterFuzz(t *testing.T) { var res strings.Builder err := PostProcess(&RenderContext{ + Ctx: git.DefaultContext, URLPrefix: "https://example.com", Metas: localMetas, }, strings.NewReader(data), &res) @@ -511,6 +520,7 @@ func Test_ParseClusterFuzz(t *testing.T) { res.Reset() err = PostProcess(&RenderContext{ + Ctx: git.DefaultContext, URLPrefix: "https://example.com", Metas: localMetas, }, strings.NewReader(data), &res) @@ -531,6 +541,7 @@ func TestIssue16020(t *testing.T) { var res strings.Builder err := PostProcess(&RenderContext{ + Ctx: git.DefaultContext, URLPrefix: "https://example.com", Metas: localMetas, }, strings.NewReader(data), &res) @@ -547,6 +558,7 @@ func BenchmarkEmojiPostprocess(b *testing.B) { for i := 0; i < b.N; i++ { var res strings.Builder err := PostProcess(&RenderContext{ + Ctx: git.DefaultContext, URLPrefix: "https://example.com", Metas: localMetas, }, strings.NewReader(data), &res) @@ -557,6 +569,7 @@ func BenchmarkEmojiPostprocess(b *testing.B) { func TestFuzz(t *testing.T) { s := "t/l/issues/8#/../../a" renderContext := RenderContext{ + Ctx: git.DefaultContext, URLPrefix: "https://example.com/go-gitea/gitea", Metas: map[string]string{ "user": "go-gitea", @@ -574,6 +587,7 @@ func TestIssue18471(t *testing.T) { var res strings.Builder err := PostProcess(&RenderContext{ + Ctx: git.DefaultContext, URLPrefix: "https://example.com", Metas: localMetas, }, strings.NewReader(data), &res) diff --git a/modules/markup/markdown/markdown_test.go b/modules/markup/markdown/markdown_test.go index bb458a65c1c2..0c7650a5ffab 100644 --- a/modules/markup/markdown/markdown_test.go +++ b/modules/markup/markdown/markdown_test.go @@ -52,12 +52,14 @@ func TestRender_StandardLinks(t *testing.T) { test := func(input, expected, expectedWiki string) { buffer, err := RenderString(&markup.RenderContext{ + Ctx: git.DefaultContext, URLPrefix: setting.AppSubURL, }, input) assert.NoError(t, err) assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(buffer)) buffer, err = RenderString(&markup.RenderContext{ + Ctx: git.DefaultContext, URLPrefix: setting.AppSubURL, IsWiki: true, }, input) @@ -81,6 +83,7 @@ func TestRender_Images(t *testing.T) { test := func(input, expected string) { buffer, err := RenderString(&markup.RenderContext{ + Ctx: git.DefaultContext, URLPrefix: setting.AppSubURL, }, input) assert.NoError(t, err) @@ -311,6 +314,7 @@ func TestTotal_RenderWiki(t *testing.T) { for i := 0; i < len(testCases); i += 2 { line, err := RenderString(&markup.RenderContext{ + Ctx: git.DefaultContext, URLPrefix: AppSubURL, IsWiki: true, }, testCases[i]) @@ -339,6 +343,7 @@ func TestTotal_RenderString(t *testing.T) { for i := 0; i < len(testCases); i += 2 { line, err := RenderString(&markup.RenderContext{ + Ctx: git.DefaultContext, URLPrefix: AppSubURL, }, testCases[i]) assert.NoError(t, err) @@ -348,17 +353,17 @@ func TestTotal_RenderString(t *testing.T) { func TestRender_RenderParagraphs(t *testing.T) { test := func(t *testing.T, str string, cnt int) { - res, err := RenderRawString(&markup.RenderContext{}, str) + res, err := RenderRawString(&markup.RenderContext{Ctx: git.DefaultContext}, str) assert.NoError(t, err) assert.Equal(t, cnt, strings.Count(res, "image1
    image2

    ` - res, err := RenderRawString(&markup.RenderContext{}, testcase) + res, err := RenderRawString(&markup.RenderContext{Ctx: git.DefaultContext}, testcase) assert.NoError(t, err) assert.Equal(t, expected, res) } @@ -407,7 +412,7 @@ func TestRenderEmojiInLinks_Issue12331(t *testing.T) { testcase := `[Link with emoji :moon: in text](https://gitea.io)` expected := `

    Link with emoji 🌔 in text

    ` - res, err := RenderString(&markup.RenderContext{}, testcase) + res, err := RenderString(&markup.RenderContext{Ctx: git.DefaultContext}, testcase) assert.NoError(t, err) assert.Equal(t, expected, res) } @@ -441,7 +446,7 @@ func TestColorPreview(t *testing.T) { } for _, test := range positiveTests { - res, err := RenderString(&markup.RenderContext{}, test.testcase) + res, err := RenderString(&markup.RenderContext{Ctx: git.DefaultContext}, test.testcase) assert.NoError(t, err, "Unexpected error in testcase: %q", test.testcase) assert.Equal(t, test.expected, res, "Unexpected result in testcase %q", test.testcase) @@ -461,7 +466,7 @@ func TestColorPreview(t *testing.T) { } for _, test := range negativeTests { - res, err := RenderString(&markup.RenderContext{}, test) + res, err := RenderString(&markup.RenderContext{Ctx: git.DefaultContext}, test) assert.NoError(t, err, "Unexpected error in testcase: %q", test) assert.NotContains(t, res, `` for _, label := range labels { // Protect against nil value in labels - shouldn't happen but would cause a panic if so @@ -396,7 +396,7 @@ func NewFuncMap() []template.FuncMap { continue } htmlCode += fmt.Sprintf("%s ", - repoLink, label.ID, RenderLabel(label)) + repoLink, label.ID, RenderLabel(ctx, label)) } htmlCode += "" return template.HTML(htmlCode) @@ -808,7 +808,7 @@ func RenderIssueTitle(ctx context.Context, text, urlPrefix string, metas map[str } // RenderLabel renders a label -func RenderLabel(label *issues_model.Label) string { +func RenderLabel(ctx context.Context, label *issues_model.Label) string { labelScope := label.ExclusiveScope() textColor := "#111" @@ -821,12 +821,12 @@ func RenderLabel(label *issues_model.Label) string { if labelScope == "" { // Regular label return fmt.Sprintf("
    %s
    ", - textColor, label.Color, description, RenderEmoji(label.Name)) + textColor, label.Color, description, RenderEmoji(ctx, label.Name)) } // Scoped label - scopeText := RenderEmoji(labelScope) - itemText := RenderEmoji(label.Name[len(labelScope)+1:]) + scopeText := RenderEmoji(ctx, labelScope) + itemText := RenderEmoji(ctx, label.Name[len(labelScope)+1:]) itemColor := label.Color scopeColor := label.Color @@ -869,8 +869,9 @@ func RenderLabel(label *issues_model.Label) string { } // RenderEmoji renders html text with emoji post processors -func RenderEmoji(text string) template.HTML { - renderedText, err := markup.RenderEmoji(template.HTMLEscapeString(text)) +func RenderEmoji(ctx context.Context, text string) template.HTML { + renderedText, err := markup.RenderEmoji(&markup.RenderContext{Ctx: ctx}, + template.HTMLEscapeString(text)) if err != nil { log.Error("RenderEmoji: %v", err) return template.HTML("") diff --git a/templates/projects/view.tmpl b/templates/projects/view.tmpl index b25cf2526ebe..eabeff49269b 100644 --- a/templates/projects/view.tmpl +++ b/templates/projects/view.tmpl @@ -234,7 +234,7 @@ {{if or .Labels .Assignees}}
    {{range .Labels}} - {{RenderLabel .}} + {{RenderLabel $.Context .}} {{end}}
    {{range .Assignees}} diff --git a/templates/repo/activity.tmpl b/templates/repo/activity.tmpl index 255951824d27..ae1d426bc074 100644 --- a/templates/repo/activity.tmpl +++ b/templates/repo/activity.tmpl @@ -129,7 +129,7 @@ {{$.locale.Tr "repo.activity.published_release_label"}} {{.TagName}} {{if not .IsTag}} - {{.Title | RenderEmoji}} + {{.Title | RenderEmoji $.Context}} {{end}} {{TimeSinceUnix .CreatedUnix $.locale}}

    @@ -149,7 +149,7 @@ {{range .Activity.MergedPRs}}

    {{$.locale.Tr "repo.activity.merged_prs_label"}} - #{{.Index}} {{.Issue.Title | RenderEmoji}} + #{{.Index}} {{.Issue.Title | RenderEmoji $.Context}} {{TimeSinceUnix .MergedUnix $.locale}}

    {{end}} @@ -168,7 +168,7 @@ {{range .Activity.OpenedPRs}}

    {{$.locale.Tr "repo.activity.opened_prs_label"}} - #{{.Index}} {{.Issue.Title | RenderEmoji}} + #{{.Index}} {{.Issue.Title | RenderEmoji $.Context}} {{TimeSinceUnix .Issue.CreatedUnix $.locale}}

    {{end}} @@ -187,7 +187,7 @@ {{range .Activity.ClosedIssues}}

    {{$.locale.Tr "repo.activity.closed_issue_label"}} - #{{.Index}} {{.Title | RenderEmoji}} + #{{.Index}} {{.Title | RenderEmoji $.Context}} {{TimeSinceUnix .ClosedUnix $.locale}}

    {{end}} @@ -206,7 +206,7 @@ {{range .Activity.OpenedIssues}}

    {{$.locale.Tr "repo.activity.new_issue_label"}} - #{{.Index}} {{.Title | RenderEmoji}} + #{{.Index}} {{.Title | RenderEmoji $.Context}} {{TimeSinceUnix .CreatedUnix $.locale}}

    {{end}} @@ -227,9 +227,9 @@ {{$.locale.Tr "repo.activity.unresolved_conv_label"}} #{{.Index}} {{if .IsPull}} - {{.Title | RenderEmoji}} + {{.Title | RenderEmoji $.Context}} {{else}} - {{.Title | RenderEmoji}} + {{.Title | RenderEmoji $.Context}} {{end}} {{TimeSinceUnix .UpdatedUnix $.locale}}

    diff --git a/templates/repo/commits_list.tmpl b/templates/repo/commits_list.tmpl index eaf86ab4e1fe..36333c554079 100644 --- a/templates/repo/commits_list.tmpl +++ b/templates/repo/commits_list.tmpl @@ -61,7 +61,7 @@ {{if $.PageIsWiki}} - {{.Summary | RenderEmoji}} + {{.Summary | RenderEmoji $.Context}} {{else}} {{$commitLink:= printf "%s/commit/%s" $commitRepoLink (PathEscape .ID.String)}} {{RenderCommitMessageLinkSubject $.Context .Message $commitRepoLink $commitLink $.Repository.ComposeMetas}} diff --git a/templates/repo/issue/labels/label.tmpl b/templates/repo/issue/labels/label.tmpl index 6e9177aec292..01016281ad3c 100644 --- a/templates/repo/issue/labels/label.tmpl +++ b/templates/repo/issue/labels/label.tmpl @@ -3,5 +3,5 @@ id="label_{{.label.ID}}" href="{{.root.RepoLink}}/{{if or .root.IsPull .root.Issue.IsPull}}pulls{{else}}issues{{end}}?labels={{.label.ID}}"{{/* FIXME: use .root.Issue.Link or create .root.Link */}} > - {{RenderLabel .label}} + {{RenderLabel $.Context .label}} diff --git a/templates/repo/issue/labels/label_list.tmpl b/templates/repo/issue/labels/label_list.tmpl index e8f00fa256ce..2c8ace8d7524 100644 --- a/templates/repo/issue/labels/label_list.tmpl +++ b/templates/repo/issue/labels/label_list.tmpl @@ -31,8 +31,8 @@
  • - {{RenderLabel .}} - {{if .Description}}
    {{.Description | RenderEmoji}}{{end}} + {{RenderLabel $.Context .}} + {{if .Description}}
    {{.Description | RenderEmoji $.Context}}{{end}}
    {{if $.PageIsOrgSettingsLabels}} @@ -70,8 +70,8 @@
  • - {{RenderLabel .}} - {{if .Description}}
    {{.Description | RenderEmoji}}{{end}} + {{RenderLabel $.Context .}} + {{if .Description}}
    {{.Description | RenderEmoji $.Context}}{{end}}
    @@ -231,7 +231,7 @@ {{end}} {{$previousExclusiveScope = $exclusiveScope}}
    - {{if contain $.SelLabelIDs .ID}}{{if $exclusiveScope}}{{svg "octicon-dot-fill"}}{{else}}{{svg "octicon-check"}}{{end}}{{end}} {{RenderLabel .}} + {{if contain $.SelLabelIDs .ID}}{{if $exclusiveScope}}{{svg "octicon-dot-fill"}}{{else}}{{svg "octicon-check"}}{{end}}{{end}} {{RenderLabel $.Context .}}
    {{end}}
  • diff --git a/templates/repo/issue/milestone_issues.tmpl b/templates/repo/issue/milestone_issues.tmpl index fca95974469f..46050a276893 100644 --- a/templates/repo/issue/milestone_issues.tmpl +++ b/templates/repo/issue/milestone_issues.tmpl @@ -58,7 +58,7 @@ {{.locale.Tr "repo.issues.filter_label_exclude" | Safe}} {{.locale.Tr "repo.issues.filter_label_no_select"}} {{range .Labels}} - {{if .IsExcluded}}{{svg "octicon-circle-slash"}}{{else if contain $.SelLabelIDs .ID}}{{svg "octicon-check"}}{{end}} {{RenderLabel .}} + {{if .IsExcluded}}{{svg "octicon-circle-slash"}}{{else if contain $.SelLabelIDs .ID}}{{svg "octicon-check"}}{{end}} {{RenderLabel $.Context .}} {{end}}
    @@ -161,7 +161,7 @@ diff --git a/templates/repo/issue/new_form.tmpl b/templates/repo/issue/new_form.tmpl index 8346d07a13c6..ac5aaa480188 100644 --- a/templates/repo/issue/new_form.tmpl +++ b/templates/repo/issue/new_form.tmpl @@ -60,8 +60,8 @@
    {{end}} {{$previousExclusiveScope = $exclusiveScope}} - {{if $exclusiveScope}}{{svg "octicon-dot-fill"}}{{else}}{{svg "octicon-check"}}{{end}}  {{RenderLabel .}} - {{if .Description}}
    {{.Description | RenderEmoji}}{{end}}
    + {{if $exclusiveScope}}{{svg "octicon-dot-fill"}}{{else}}{{svg "octicon-check"}}{{end}}  {{RenderLabel $.Context .}} + {{if .Description}}
    {{.Description | RenderEmoji $.Context}}{{end}}
    {{end}}
    @@ -72,8 +72,8 @@
    {{end}} {{$previousExclusiveScope = $exclusiveScope}} - {{if $exclusiveScope}}{{svg "octicon-dot-fill"}}{{else}}{{svg "octicon-check"}}{{end}}  {{RenderLabel .}} - {{if .Description}}
    {{.Description | RenderEmoji}}{{end}}
    + {{if $exclusiveScope}}{{svg "octicon-dot-fill"}}{{else}}{{svg "octicon-check"}}{{end}}  {{RenderLabel $.Context .}} + {{if .Description}}
    {{.Description | RenderEmoji $.Context}}{{end}}
    {{end}} {{else}}
    {{.locale.Tr "repo.issues.new.no_items"}}
    diff --git a/templates/repo/issue/view_content/comments.tmpl b/templates/repo/issue/view_content/comments.tmpl index 94b46bd9f13a..bc4188678057 100644 --- a/templates/repo/issue/view_content/comments.tmpl +++ b/templates/repo/issue/view_content/comments.tmpl @@ -180,11 +180,11 @@ {{template "shared/user/authorlink" .Poster}} {{if and .AddedLabels (not .RemovedLabels)}} - {{$.locale.TrN (len .AddedLabels) "repo.issues.add_label" "repo.issues.add_labels" (RenderLabels .AddedLabels $.RepoLink) $createdStr | Safe}} + {{$.locale.TrN (len .AddedLabels) "repo.issues.add_label" "repo.issues.add_labels" (RenderLabels $.Context .AddedLabels $.RepoLink) $createdStr | Safe}} {{else if and (not .AddedLabels) .RemovedLabels}} - {{$.locale.TrN (len .RemovedLabels) "repo.issues.remove_label" "repo.issues.remove_labels" (RenderLabels .RemovedLabels $.RepoLink) $createdStr | Safe}} + {{$.locale.TrN (len .RemovedLabels) "repo.issues.remove_label" "repo.issues.remove_labels" (RenderLabels $.Context .RemovedLabels $.RepoLink) $createdStr | Safe}} {{else}} - {{$.locale.Tr "repo.issues.add_remove_labels" (RenderLabels .AddedLabels $.RepoLink) (RenderLabels .RemovedLabels $.RepoLink) $createdStr | Safe}} + {{$.locale.Tr "repo.issues.add_remove_labels" (RenderLabels $.Context .AddedLabels $.RepoLink) (RenderLabels $.Context .RemovedLabels $.RepoLink) $createdStr | Safe}} {{end}}
    @@ -231,7 +231,7 @@ {{template "shared/user/avatarlink" Dict "Context" $.Context "user" .Poster}} {{template "shared/user/authorlink" .Poster}} - {{$.locale.Tr "repo.issues.change_title_at" (.OldTitle|RenderEmoji) (.NewTitle|RenderEmoji) $createdStr | Safe}} + {{$.locale.Tr "repo.issues.change_title_at" (.OldTitle|RenderEmoji $.Context) (.NewTitle|RenderEmoji $.Context) $createdStr | Safe}}
    {{else if eq .Type 11}} diff --git a/templates/repo/issue/view_content/sidebar.tmpl b/templates/repo/issue/view_content/sidebar.tmpl index d9c506243705..0728f5390a18 100644 --- a/templates/repo/issue/view_content/sidebar.tmpl +++ b/templates/repo/issue/view_content/sidebar.tmpl @@ -130,8 +130,8 @@
    {{end}} {{$previousExclusiveScope = $exclusiveScope}} - {{if $exclusiveScope}}{{svg "octicon-dot-fill"}}{{else}}{{svg "octicon-check"}}{{end}}  {{RenderLabel .}} - {{if .Description}}
    {{.Description | RenderEmoji}}{{end}}
    + {{if $exclusiveScope}}{{svg "octicon-dot-fill"}}{{else}}{{svg "octicon-check"}}{{end}}  {{RenderLabel $.Context .}} + {{if .Description}}
    {{.Description | RenderEmoji $.Context}}{{end}}
    {{end}}
    {{$previousExclusiveScope := "_no_scope"}} @@ -141,8 +141,8 @@
    {{end}} {{$previousExclusiveScope = $exclusiveScope}} - {{if $exclusiveScope}}{{svg "octicon-dot-fill"}}{{else}}{{svg "octicon-check"}}{{end}}  {{RenderLabel .}} - {{if .Description}}
    {{.Description | RenderEmoji}}{{end}}
    + {{if $exclusiveScope}}{{svg "octicon-dot-fill"}}{{else}}{{svg "octicon-check"}}{{end}}  {{RenderLabel $.Context .}} + {{if .Description}}
    {{.Description | RenderEmoji $.Context}}{{end}}
    {{end}} {{else}}
    {{.locale.Tr "repo.issues.new.no_items"}}
    @@ -487,8 +487,8 @@ {{range .BlockingDependencies}}
    - - #{{.Issue.Index}} {{.Issue.Title | RenderEmoji}} + + #{{.Issue.Index}} {{.Issue.Title | RenderEmoji $.Context}}
    {{.Repository.OwnerName}}/{{.Repository.Name}} @@ -514,8 +514,8 @@ {{range .BlockedByDependencies}}
    - - #{{.Issue.Index}} {{.Issue.Title | RenderEmoji}} + + #{{.Issue.Index}} {{.Issue.Title | RenderEmoji $.Context}}
    {{.Repository.OwnerName}}/{{.Repository.Name}} diff --git a/templates/repo/projects/view.tmpl b/templates/repo/projects/view.tmpl index a4ada8735356..0c49c1d02579 100644 --- a/templates/repo/projects/view.tmpl +++ b/templates/repo/projects/view.tmpl @@ -245,7 +245,7 @@ {{if or .Labels .Assignees}}
    {{range .Labels}} - {{RenderLabel .}} + {{RenderLabel $.Context .}} {{end}}
    {{range .Assignees}} diff --git a/templates/repo/settings/lfs_file_find.tmpl b/templates/repo/settings/lfs_file_find.tmpl index d5983ca1cc8d..81cb6498374a 100644 --- a/templates/repo/settings/lfs_file_find.tmpl +++ b/templates/repo/settings/lfs_file_find.tmpl @@ -19,7 +19,7 @@ - {{.Summary | RenderEmoji}} + {{.Summary | RenderEmoji $.Context}} diff --git a/templates/shared/issuelist.tmpl b/templates/shared/issuelist.tmpl index a43047c79de9..6f3fd0f9167d 100644 --- a/templates/shared/issuelist.tmpl +++ b/templates/shared/issuelist.tmpl @@ -34,7 +34,7 @@
    - {{RenderEmoji .Title | RenderCodeBlock}} + {{RenderEmoji $.Context .Title | RenderCodeBlock}} {{if .IsPull}} {{if (index $.CommitStatuses .PullRequest.ID)}} {{template "repo/commit_statuses" dict "Status" (index $.CommitLastStatus .PullRequest.ID) "Statuses" (index $.CommitStatuses .PullRequest.ID) "root" $}} @@ -42,7 +42,7 @@ {{end}} {{range .Labels}} - {{RenderLabel .}} + {{RenderLabel $.Context .}} {{end}}
    diff --git a/templates/user/dashboard/feeds.tmpl b/templates/user/dashboard/feeds.tmpl index 3f156249ffa6..f2dc5d00ad82 100644 --- a/templates/user/dashboard/feeds.tmpl +++ b/templates/user/dashboard/feeds.tmpl @@ -72,7 +72,7 @@ {{$index := index .GetIssueInfos 0}} {{$.locale.Tr "action.comment_pull" ((printf "%s/pulls/%s" .GetRepoLink $index) |Escape) $index (.ShortRepoPath|Escape) | Str2html}} {{else if eq .GetOpType 24}} - {{$linkText := .Content | RenderEmoji}} + {{$linkText := .Content | RenderEmoji $.Context}} {{$.locale.Tr "action.publish_release" (.GetRepoLink|Escape) ((printf "%s/releases/tag/%s" .GetRepoLink .GetTag)|Escape) (.ShortRepoPath|Escape) $linkText | Str2html}} {{else if eq .GetOpType 25}} {{$index := index .GetIssueInfos 0}} @@ -99,20 +99,20 @@
{{else if eq .GetOpType 6}} - {{index .GetIssueInfos 1 | RenderEmoji | RenderCodeBlock}} + {{index .GetIssueInfos 1 | RenderEmoji $.Context | RenderCodeBlock}} {{else if eq .GetOpType 7}} - {{index .GetIssueInfos 1 | RenderEmoji | RenderCodeBlock}} + {{index .GetIssueInfos 1 | RenderEmoji $.Context | RenderCodeBlock}} {{else if or (eq .GetOpType 10) (eq .GetOpType 21) (eq .GetOpType 22) (eq .GetOpType 23)}} - {{.GetIssueTitle | RenderEmoji | RenderCodeBlock}} + {{.GetIssueTitle | RenderEmoji $.Context | RenderCodeBlock}} {{$comment := index .GetIssueInfos 1}} - {{if gt (len $comment) 0}}

{{$comment | RenderEmoji}}

{{end}} + {{if gt (len $comment) 0}}

{{$comment | RenderEmoji $.Context}}

{{end}} {{else if eq .GetOpType 11}}

{{index .GetIssueInfos 1}}

{{else if or (eq .GetOpType 12) (eq .GetOpType 13) (eq .GetOpType 14) (eq .GetOpType 15)}} - {{.GetIssueTitle | RenderEmoji | RenderCodeBlock}} + {{.GetIssueTitle | RenderEmoji $.Context | RenderCodeBlock}} {{else if eq .GetOpType 25}}

{{$.locale.Tr "action.review_dismissed_reason"}}

-

{{index .GetIssueInfos 2 | RenderEmoji}}

+

{{index .GetIssueInfos 2 | RenderEmoji $.Context}}

{{end}}

{{TimeSince .GetCreate $.locale}}

From 233a3997064ee1a72f3bcc802546e6213d871f5b Mon Sep 17 00:00:00 2001 From: Giteabot Date: Mon, 6 Mar 2023 13:05:35 -0500 Subject: [PATCH 055/340] Fix broken code editor diff preview (#23307) (#23320) Backport #23307 Close #23265, the code editor diff preview has been broken for long time. * Fix the regression for `data-line-num` * `.code-diff` is necessary to show the line number * Fix the regression for #12434 * The diff: [12434](https://github.com/go-gitea/gitea/pull/12434/files?diff=unified&w=1) * It hides the Type(4) (aka HunkHeader) for unexpected cases. Diff with ignoring whitespaces: https://github.com/go-gitea/gitea/pull/23307/files?diff=unified&w=1 Before: see the issue #23265 After: ![image](https://user-images.githubusercontent.com/2114189/222942810-286dc9af-0b39-4e9d-8585-8c299b881241.png) Co-authored-by: wxiaoguang --- services/gitdiff/gitdiff.go | 2 +- templates/repo/diff/section_unified.tmpl | 63 +++++++++++++----------- templates/repo/editor/diff_preview.tmpl | 2 +- 3 files changed, 35 insertions(+), 32 deletions(-) diff --git a/services/gitdiff/gitdiff.go b/services/gitdiff/gitdiff.go index 4a74c1a8944e..c50e8137ab18 100644 --- a/services/gitdiff/gitdiff.go +++ b/services/gitdiff/gitdiff.go @@ -474,7 +474,7 @@ func ParsePatch(maxLines, maxLineCharacters, maxFiles int, reader io.Reader, ski sb := strings.Builder{} // OK let's set a reasonable buffer size. - // This should be let's say at least the size of maxLineCharacters or 4096 whichever is larger. + // This should be at least the size of maxLineCharacters or 4096 whichever is larger. readerSize := maxLineCharacters if readerSize < 4096 { readerSize = 4096 diff --git a/templates/repo/diff/section_unified.tmpl b/templates/repo/diff/section_unified.tmpl index 63cd510221fb..e0ec85f9a6ac 100644 --- a/templates/repo/diff/section_unified.tmpl +++ b/templates/repo/diff/section_unified.tmpl @@ -1,9 +1,9 @@ {{$file := .file}} {{range $j, $section := $file.Sections}} {{range $k, $line := $section.Lines}} - {{if or $.root.AfterCommitID (ne .GetType 4)}} - - {{if eq .GetType 4}} + + {{if eq .GetType 4}} + {{if $.root.AfterCommitID}} {{if or (eq $line.GetExpandDirection 3) (eq $line.GetExpandDirection 5)}} @@ -22,35 +22,38 @@ {{end}} {{else}} - - + {{/* for code file preview page or comment diffs on pull comment pages, do not show the expansion arrows */}} + {{end}} - {{$inlineDiff := $section.GetComputedInlineDiffFor $line $.root.locale -}} - {{if $inlineDiff.EscapeStatus.Escaped}}{{end}} - - {{if eq .GetType 4}} - {{/* - */}}{{template "repo/diff/section_code" dict "diff" $inlineDiff "locale" $.root.locale}}{{/* - */}} - {{else}} - {{/* - */}}{{if and $.root.SignedUserID $.root.PageIsPullFiles}}{{/* - */}}{{/* - */}}{{svg "octicon-plus"}}{{/* - */}}{{/* - */}}{{end}}{{/* - */}}{{template "repo/diff/section_code" dict "diff" $inlineDiff "locale" $.root.locale}}{{/* - */}} - {{end}} - - {{if gt (len $line.Comments) 0}} - - - - {{template "repo/diff/conversation" mergeinto $.root "comments" $line.Comments}} - - + {{else}} + + + {{end}} + {{$inlineDiff := $section.GetComputedInlineDiffFor $line $.root.locale -}} + {{if $inlineDiff.EscapeStatus.Escaped}}{{end}} + + {{if eq .GetType 4}} + {{/* + */}}{{template "repo/diff/section_code" dict "diff" $inlineDiff "locale" $.root.locale}}{{/* + */}} + {{else}} + {{/* + */}}{{if and $.root.SignedUserID $.root.PageIsPullFiles}}{{/* + */}}{{/* + */}}{{svg "octicon-plus"}}{{/* + */}}{{/* + */}}{{end}}{{/* + */}}{{template "repo/diff/section_code" dict "diff" $inlineDiff "locale" $.root.locale}}{{/* + */}} {{end}} + + {{if gt (len $line.Comments) 0}} + + + + {{template "repo/diff/conversation" mergeinto $.root "comments" $line.Comments}} + + {{end}} {{end}} {{end}} diff --git a/templates/repo/editor/diff_preview.tmpl b/templates/repo/editor/diff_preview.tmpl index e6956648ca8b..e2e922be343c 100644 --- a/templates/repo/editor/diff_preview.tmpl +++ b/templates/repo/editor/diff_preview.tmpl @@ -1,6 +1,6 @@
-
+
{{template "repo/diff/section_unified" dict "file" .File "root" $}} From af4767df5c061a21a68b442e223446303b5d77de Mon Sep 17 00:00:00 2001 From: Giteabot Date: Mon, 6 Mar 2023 13:59:53 -0500 Subject: [PATCH 056/340] Scoped labels: don't require holding alt key to remove (#23303) (#23331) Backport #23303 Alt doesn't work on all browsers, the simplest solution for v1.19 is to just not require it and toggle the label by just clicking. Part of #22974 Co-authored-by: Brecht Van Lommel --- web_src/js/features/repo-legacy.js | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/web_src/js/features/repo-legacy.js b/web_src/js/features/repo-legacy.js index 22113af169e3..5173a5b59907 100644 --- a/web_src/js/features/repo-legacy.js +++ b/web_src/js/features/repo-legacy.js @@ -145,7 +145,6 @@ export function initRepoCommentForm() { const clickedItem = $(this); const scope = $(this).attr('data-scope'); - const canRemoveScope = e.altKey; $(this).parent().find('.item').each(function () { if (scope) { @@ -153,11 +152,7 @@ export function initRepoCommentForm() { if ($(this).attr('data-scope') !== scope) { return true; } - if ($(this).is(clickedItem)) { - if (!canRemoveScope && $(this).hasClass('checked')) { - return true; - } - } else if (!$(this).hasClass('checked')) { + if (!$(this).is(clickedItem) && !$(this).hasClass('checked')) { return true; } } else if (!$(this).is(clickedItem)) { From 2f7bbdf8c9cd8c36bfbb39b7cd477d4be09926ba Mon Sep 17 00:00:00 2001 From: Giteabot Date: Mon, 6 Mar 2023 14:48:04 -0500 Subject: [PATCH 057/340] Fix incorrect project links and use symlink icon for org-wide projects (#23325) (#23336) Backport #23325 Fix displaying same projects icons between user/repo projects. And fix incorrect projects links. A part of https://github.com/go-gitea/gitea/pull/22865. ![image](https://user-images.githubusercontent.com/18380374/223044279-7b620ff1-d88a-4146-97e6-531bbf269761.png) ![image](https://user-images.githubusercontent.com/18380374/223044390-42911e3f-1f6b-439f-8441-4f3ebf99ea13.png) ![image](https://user-images.githubusercontent.com/18380374/223044437-5cad5391-0f95-4c8b-b0a3-32e263e2854f.png) Co-authored-by: yp05327 <576951401@qq.com> --- templates/org/menu.tmpl | 2 +- templates/projects/list.tmpl | 4 ++-- templates/repo/issue/new_form.tmpl | 12 ++++++------ templates/repo/projects/list.tmpl | 2 +- templates/shared/issuelist.tmpl | 4 ++-- templates/user/overview/header.tmpl | 2 +- templates/user/profile.tmpl | 2 +- 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/templates/org/menu.tmpl b/templates/org/menu.tmpl index 7ca47cd32c56..25f459c09c56 100644 --- a/templates/org/menu.tmpl +++ b/templates/org/menu.tmpl @@ -4,7 +4,7 @@ {{svg "octicon-repo"}} {{.locale.Tr "user.repositories"}} - {{svg "octicon-project"}} {{.locale.Tr "user.projects"}} + {{svg "octicon-project-symlink"}} {{.locale.Tr "user.projects"}} {{if .IsPackageEnabled}} diff --git a/templates/projects/list.tmpl b/templates/projects/list.tmpl index 8d9594e2b477..489189ec45a1 100644 --- a/templates/projects/list.tmpl +++ b/templates/projects/list.tmpl @@ -12,7 +12,7 @@ {{template "base/alert" .}}
{{if not .LatestPullRequest}} {{if .IsIncluded}} - + {{svg "octicon-git-pull-request"}} {{$.locale.Tr "repo.branch.included"}} - + {{else if and (not .IsDeleted) $.AllowsPulls (gt .CommitsAhead 0)}} @@ -123,13 +123,13 @@ {{end}} {{if and $.IsWriter (not $.IsMirror) (not $.Repository.IsArchived) (not .IsProtected)}} {{if .IsDeleted}} - {{else}} - {{end}} From e5a51eca45ff6e6ef600081b4046f0eb73dd48da Mon Sep 17 00:00:00 2001 From: Giteabot Date: Tue, 14 Mar 2023 16:09:52 -0400 Subject: [PATCH 087/340] Remove wrongly added column on migration test fixtures (#23456) (#23470) Backport #23456 by @lunny Fix https://drone.gitea.io/go-gitea/gitea/69418/3/8 Migration fixtures are in `models/migrations/fixtures`, every folder will be used only by the test with the same name. For `Test_DeleteOrphanedIssueLabels`, the fixture should keep consistent as the database structure at that time. So the newly added `exclusive` is not right. Just revert the change in https://github.com/go-gitea/gitea/pull/22585/files#diff-f8db9cbbaa10bf7b27eb726884454db821a4b4f8cb9a0d50435555908761bbcb Co-authored-by: Lunny Xiao Co-authored-by: techknowlogick --- .../fixtures/Test_DeleteOrphanedIssueLabels/label.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/models/migrations/fixtures/Test_DeleteOrphanedIssueLabels/label.yml b/models/migrations/fixtures/Test_DeleteOrphanedIssueLabels/label.yml index 085b7f0882d5..d651c87d5b0d 100644 --- a/models/migrations/fixtures/Test_DeleteOrphanedIssueLabels/label.yml +++ b/models/migrations/fixtures/Test_DeleteOrphanedIssueLabels/label.yml @@ -4,7 +4,6 @@ org_id: 0 name: label1 color: '#abcdef' - exclusive: false num_issues: 2 num_closed_issues: 0 @@ -14,7 +13,6 @@ org_id: 0 name: label2 color: '#000000' - exclusive: false num_issues: 1 num_closed_issues: 1 - @@ -23,7 +21,6 @@ org_id: 3 name: orglabel3 color: '#abcdef' - exclusive: false num_issues: 0 num_closed_issues: 0 @@ -33,7 +30,6 @@ org_id: 3 name: orglabel4 color: '#000000' - exclusive: false num_issues: 1 num_closed_issues: 0 @@ -43,6 +39,5 @@ org_id: 0 name: pull-test-label color: '#000000' - exclusive: false num_issues: 0 num_closed_issues: 0 From c698a6fc5db489fa60784c6d498e810975056229 Mon Sep 17 00:00:00 2001 From: Giteabot Date: Tue, 14 Mar 2023 19:58:38 -0400 Subject: [PATCH 088/340] Scoped label display and documentation tweaks (#23430) (#23433) Backport #23430 by @brechtvl * Fix scoped label left and right part breaking across lines. * Remove slanted divider in scoped label display, make it straight. After using this for a while, this feels more visually noisy than helpful. * Reduce contrast between scope and item to reduce probability of unreadable text on background. * Change documentation to remove mention of non-exclusive scoped labels. Co-authored-by: Brecht Van Lommel Co-authored-by: Lunny Xiao Co-authored-by: John Olheiser --- docs/content/doc/usage/labels.en-us.md | 8 +++----- modules/templates/helper.go | 4 +--- web_src/less/_repository.less | 15 ++------------- 3 files changed, 6 insertions(+), 21 deletions(-) diff --git a/docs/content/doc/usage/labels.en-us.md b/docs/content/doc/usage/labels.en-us.md index bf07c074edc6..8e5ff1cf8d9f 100644 --- a/docs/content/doc/usage/labels.en-us.md +++ b/docs/content/doc/usage/labels.en-us.md @@ -23,17 +23,15 @@ For repositories, labels can be created by going to `Issues` and clicking on `La For organizations, you can define organization-wide labels that are shared with all organization repositories, including both already-existing repositories as well as newly created ones. Organization-wide labels can be created in the organization `Settings`. -Labels have a mandatory name, a mandatory color, an optional description, and must either be exclusive or not (see `Scoped labels` below). +Labels have a mandatory name, a mandatory color, an optional description, and must either be exclusive or not (see `Scoped Labels` below). When you create a repository, you can ensure certain labels exist by using the `Issue Labels` option. This option lists a number of available label sets that are [configured globally on your instance](../customizing-gitea/#labels). Its contained labels will all be created as well while creating the repository. ## Scoped Labels -A scoped label is a label that contains `/` in its name (not at either end of the name). For example labels `kind/bug` and `kind/enhancement` both have scope `kind`. Such labels will display the scope with slightly darker color. +Scoped labels are used to ensure at most a single label with the same scope is assigned to an issue or pull request. For example, if labels `kind/bug` and `kind/enhancement` have the Exclusive option set, an issue can only be classified as a bug or an enhancement. -The scope of a label is determined based on the **last** `/`, so for example the scope of label `scope/subscope/item` is `scope/subscope`. - -Scoped labels can be marked as exclusive. This ensures at most a single label with the same scope is assigned to an issue or pull request. For example, if `kind/bug` and `kind/enhancement` are marked exclusive, an issue can only be classified as a bug or an enhancement. +A scoped label must contain `/` in its name (not at either end of the name). The scope of a label is determined based on the **last** `/`, so for example the scope of label `scope/subscope/item` is `scope/subscope`. ## Filtering by Label diff --git a/modules/templates/helper.go b/modules/templates/helper.go index 19893c7c9d4d..822bbbd9b17c 100644 --- a/modules/templates/helper.go +++ b/modules/templates/helper.go @@ -834,7 +834,7 @@ func RenderLabel(ctx context.Context, label *issues_model.Label) string { // Make scope and item background colors slightly darker and lighter respectively. // More contrast needed with higher luminance, empirically tweaked. luminance := (0.299*r + 0.587*g + 0.114*b) / 255 - contrast := 0.01 + luminance*0.06 + contrast := 0.01 + luminance*0.03 // Ensure we add the same amount of contrast also near 0 and 1. darken := contrast + math.Max(luminance+contrast-1.0, 0.0) lighten := contrast + math.Max(contrast-luminance, 0.0) @@ -859,12 +859,10 @@ func RenderLabel(ctx context.Context, label *issues_model.Label) string { return fmt.Sprintf(""+ "
%s
"+ - "
 
"+ "
%s
"+ "
", description, textColor, scopeColor, scopeText, - itemColor, scopeColor, textColor, itemColor, itemText) } diff --git a/web_src/less/_repository.less b/web_src/less/_repository.less index b5d9a1029f45..27e11e714e74 100644 --- a/web_src/less/_repository.less +++ b/web_src/less/_repository.less @@ -2831,11 +2831,11 @@ .labels-list .label { margin: 2px 0; - display: inline-block !important; + display: inline-flex !important; line-height: 1.3em; // there is a `font-size: 1.25em` for inside emoji, so here the line-height needs to be larger slightly } -// Scoped labels with different colors on left and right, and slanted divider in the middle +// Scoped labels with different colors on left and right .scope-parent { background: none !important; padding: 0 !important; @@ -2844,23 +2844,12 @@ .ui.label.scope-left { border-bottom-right-radius: 0; border-top-right-radius: 0; - padding-right: 0; - margin-right: 0; -} - -.ui.label.scope-middle { - width: 12px; - border-radius: 0; - padding-left: 0; - padding-right: 0; - margin-left: 0; margin-right: 0; } .ui.label.scope-right { border-bottom-left-radius: 0; border-top-left-radius: 0; - padding-left: 0; margin-left: 0; } From 28af02eea013135f29ca3b917b50dfa54afe3bdf Mon Sep 17 00:00:00 2001 From: Giteabot Date: Tue, 14 Mar 2023 21:40:43 -0400 Subject: [PATCH 089/340] Fix due date being wrong on issue list (#23475) (#23477) Backport #23475 by @yardenshoham Exactly like #22302 but in the issue list page Co-authored-by: Yarden Shoham Co-authored-by: Lunny Xiao --- templates/shared/issuelist.tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/shared/issuelist.tmpl b/templates/shared/issuelist.tmpl index 16bb3c1ec7fe..ae9cb55d44df 100644 --- a/templates/shared/issuelist.tmpl +++ b/templates/shared/issuelist.tmpl @@ -108,7 +108,7 @@ {{svg "octicon-calendar" 14 "gt-mr-2"}} - + {{end}} From 31efbafbe3047cdaff8abe6ae6719e257556307c Mon Sep 17 00:00:00 2001 From: Giteabot Date: Tue, 14 Mar 2023 22:43:10 -0400 Subject: [PATCH 090/340] Convert GitHub event on actions and fix some pull_request events. (#23037) (#23471) Backport #23037 by @lunny Follow #22680 Partially Fix #22958, on pull_request, `opened`, `reopened`, `synchronize` supported, `edited` hasn't been supported yet because Gitea doesn't trigger that events. Co-authored-by: Lunny Xiao Co-authored-by: yp05327 <576951401@qq.com> --- modules/actions/github.go | 41 +++++ modules/actions/workflows.go | 285 +++++++++++++++++++++-------------- 2 files changed, 212 insertions(+), 114 deletions(-) create mode 100644 modules/actions/github.go diff --git a/modules/actions/github.go b/modules/actions/github.go new file mode 100644 index 000000000000..bcde9a0f552e --- /dev/null +++ b/modules/actions/github.go @@ -0,0 +1,41 @@ +// Copyright 2023 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package actions + +import ( + webhook_module "code.gitea.io/gitea/modules/webhook" + + "github.com/nektos/act/pkg/jobparser" +) + +const ( + githubEventPullRequest = "pull_request" + githubEventPullRequestTarget = "pull_request_target" + githubEventPullRequestReviewComment = "pull_request_review_comment" + githubEventPullRequestReview = "pull_request_review" + githubEventRegistryPackage = "registry_package" + githubEventCreate = "create" + githubEventDelete = "delete" + githubEventFork = "fork" + githubEventPush = "push" + githubEventIssues = "issues" + githubEventIssueComment = "issue_comment" + githubEventRelease = "release" + githubEventPullRequestComment = "pull_request_comment" +) + +func convertFromGithubEvent(evt *jobparser.Event) string { + switch evt.Name { + case githubEventPullRequest, githubEventPullRequestTarget, githubEventPullRequestReview, + githubEventPullRequestReviewComment: + return string(webhook_module.HookEventPullRequest) + case githubEventRegistryPackage: + return string(webhook_module.HookEventPackage) + case githubEventCreate, githubEventDelete, githubEventFork, githubEventPush, + githubEventIssues, githubEventIssueComment, githubEventRelease, githubEventPullRequestComment: + fallthrough + default: + return evt.Name + } +} diff --git a/modules/actions/workflows.go b/modules/actions/workflows.go index 7f0e6e456436..6f4d98d52d39 100644 --- a/modules/actions/workflows.go +++ b/modules/actions/workflows.go @@ -72,9 +72,7 @@ func DetectWorkflows(commit *git.Commit, triggedEvent webhook_module.HookEventTy continue } for _, evt := range events { - if evt.Name != triggedEvent.Event() { - continue - } + log.Trace("detect workflow %q for event %#v matching %q", entry.Name(), evt, triggedEvent) if detectMatched(commit, triggedEvent, payload, evt) { workflows[entry.Name()] = content } @@ -85,138 +83,197 @@ func DetectWorkflows(commit *git.Commit, triggedEvent webhook_module.HookEventTy } func detectMatched(commit *git.Commit, triggedEvent webhook_module.HookEventType, payload api.Payloader, evt *jobparser.Event) bool { - if len(evt.Acts) == 0 { - return true + if convertFromGithubEvent(evt) != string(triggedEvent) { + return false } switch triggedEvent { - case webhook_module.HookEventCreate: - fallthrough - case webhook_module.HookEventDelete: - fallthrough - case webhook_module.HookEventFork: - log.Warn("unsupported event %q", triggedEvent.Event()) - return false + case webhook_module.HookEventCreate, + webhook_module.HookEventDelete, + webhook_module.HookEventFork, + webhook_module.HookEventIssueAssign, + webhook_module.HookEventIssueLabel, + webhook_module.HookEventIssueMilestone, + webhook_module.HookEventPullRequestAssign, + webhook_module.HookEventPullRequestLabel, + webhook_module.HookEventPullRequestMilestone, + webhook_module.HookEventPullRequestComment, + webhook_module.HookEventPullRequestReviewApproved, + webhook_module.HookEventPullRequestReviewRejected, + webhook_module.HookEventPullRequestReviewComment, + webhook_module.HookEventWiki, + webhook_module.HookEventRepository, + webhook_module.HookEventRelease, + webhook_module.HookEventPackage: + if len(evt.Acts) != 0 { + log.Warn("Ignore unsupported %s event arguments %q", triggedEvent, evt.Acts) + } + // no special filter parameters for these events, just return true if name matched + return true + case webhook_module.HookEventPush: - pushPayload := payload.(*api.PushPayload) - matchTimes := 0 - // all acts conditions should be satisfied - for cond, vals := range evt.Acts { - switch cond { - case "branches", "tags": - refShortName := git.RefName(pushPayload.Ref).ShortName() + return matchPushEvent(commit, payload.(*api.PushPayload), evt) + + case webhook_module.HookEventIssues: + return matchIssuesEvent(commit, payload.(*api.IssuePayload), evt) + + case webhook_module.HookEventPullRequest, webhook_module.HookEventPullRequestSync: + return matchPullRequestEvent(commit, payload.(*api.PullRequestPayload), evt) + + case webhook_module.HookEventIssueComment: + return matchIssueCommentEvent(commit, payload.(*api.IssueCommentPayload), evt) + + default: + log.Warn("unsupported event %q", triggedEvent) + return false + } +} + +func matchPushEvent(commit *git.Commit, pushPayload *api.PushPayload, evt *jobparser.Event) bool { + // with no special filter parameters + if len(evt.Acts) == 0 { + return true + } + + matchTimes := 0 + // all acts conditions should be satisfied + for cond, vals := range evt.Acts { + switch cond { + case "branches", "tags": + refShortName := git.RefName(pushPayload.Ref).ShortName() + for _, val := range vals { + if glob.MustCompile(val, '/').Match(refShortName) { + matchTimes++ + break + } + } + case "paths": + filesChanged, err := commit.GetFilesChangedSinceCommit(pushPayload.Before) + if err != nil { + log.Error("GetFilesChangedSinceCommit [commit_sha1: %s]: %v", commit.ID.String(), err) + } else { for _, val := range vals { - if glob.MustCompile(val, '/').Match(refShortName) { + matched := false + for _, file := range filesChanged { + if glob.MustCompile(val, '/').Match(file) { + matched = true + break + } + } + if matched { matchTimes++ break } } - case "paths": - filesChanged, err := commit.GetFilesChangedSinceCommit(pushPayload.Before) - if err != nil { - log.Error("GetFilesChangedSinceCommit [commit_sha1: %s]: %v", commit.ID.String(), err) - } else { - for _, val := range vals { - matched := false - for _, file := range filesChanged { - if glob.MustCompile(val, '/').Match(file) { - matched = true - break - } - } - if matched { - matchTimes++ - break - } - } + } + default: + log.Warn("push event unsupported condition %q", cond) + } + } + return matchTimes == len(evt.Acts) +} + +func matchIssuesEvent(commit *git.Commit, issuePayload *api.IssuePayload, evt *jobparser.Event) bool { + // with no special filter parameters + if len(evt.Acts) == 0 { + return true + } + + matchTimes := 0 + // all acts conditions should be satisfied + for cond, vals := range evt.Acts { + switch cond { + case "types": + for _, val := range vals { + if glob.MustCompile(val, '/').Match(string(issuePayload.Action)) { + matchTimes++ + break } - default: - log.Warn("unsupported condition %q", cond) } + default: + log.Warn("issue event unsupported condition %q", cond) } - return matchTimes == len(evt.Acts) + } + return matchTimes == len(evt.Acts) +} - case webhook_module.HookEventIssues: - fallthrough - case webhook_module.HookEventIssueAssign: - fallthrough - case webhook_module.HookEventIssueLabel: - fallthrough - case webhook_module.HookEventIssueMilestone: - fallthrough - case webhook_module.HookEventIssueComment: - fallthrough - case webhook_module.HookEventPullRequest: - prPayload := payload.(*api.PullRequestPayload) - matchTimes := 0 - // all acts conditions should be satisfied - for cond, vals := range evt.Acts { - switch cond { - case "types": - for _, val := range vals { - if glob.MustCompile(val, '/').Match(string(prPayload.Action)) { - matchTimes++ - break - } +func matchPullRequestEvent(commit *git.Commit, prPayload *api.PullRequestPayload, evt *jobparser.Event) bool { + // with no special filter parameters + if len(evt.Acts) == 0 { + // defaultly, only pull request opened and synchronized will trigger workflow + return prPayload.Action == api.HookIssueSynchronized || prPayload.Action == api.HookIssueOpened + } + + matchTimes := 0 + // all acts conditions should be satisfied + for cond, vals := range evt.Acts { + switch cond { + case "types": + action := prPayload.Action + if prPayload.Action == api.HookIssueSynchronized { + action = "synchronize" + } + log.Trace("matching pull_request %s with %v", action, vals) + for _, val := range vals { + if glob.MustCompile(val, '/').Match(string(action)) { + matchTimes++ + break + } + } + case "branches": + refShortName := git.RefName(prPayload.PullRequest.Base.Ref).ShortName() + for _, val := range vals { + if glob.MustCompile(val, '/').Match(refShortName) { + matchTimes++ + break } - case "branches": - refShortName := git.RefName(prPayload.PullRequest.Base.Ref).ShortName() + } + case "paths": + filesChanged, err := commit.GetFilesChangedSinceCommit(prPayload.PullRequest.Base.Ref) + if err != nil { + log.Error("GetFilesChangedSinceCommit [commit_sha1: %s]: %v", commit.ID.String(), err) + } else { for _, val := range vals { - if glob.MustCompile(val, '/').Match(refShortName) { + matched := false + for _, file := range filesChanged { + if glob.MustCompile(val, '/').Match(file) { + matched = true + break + } + } + if matched { matchTimes++ break } } - case "paths": - filesChanged, err := commit.GetFilesChangedSinceCommit(prPayload.PullRequest.Base.Ref) - if err != nil { - log.Error("GetFilesChangedSinceCommit [commit_sha1: %s]: %v", commit.ID.String(), err) - } else { - for _, val := range vals { - matched := false - for _, file := range filesChanged { - if glob.MustCompile(val, '/').Match(file) { - matched = true - break - } - } - if matched { - matchTimes++ - break - } - } + } + default: + log.Warn("pull request event unsupported condition %q", cond) + } + } + return matchTimes == len(evt.Acts) +} + +func matchIssueCommentEvent(commit *git.Commit, issueCommentPayload *api.IssueCommentPayload, evt *jobparser.Event) bool { + // with no special filter parameters + if len(evt.Acts) == 0 { + return true + } + + matchTimes := 0 + // all acts conditions should be satisfied + for cond, vals := range evt.Acts { + switch cond { + case "types": + for _, val := range vals { + if glob.MustCompile(val, '/').Match(string(issueCommentPayload.Action)) { + matchTimes++ + break } - default: - log.Warn("unsupported condition %q", cond) } + default: + log.Warn("issue comment unsupported condition %q", cond) } - return matchTimes == len(evt.Acts) - case webhook_module.HookEventPullRequestAssign: - fallthrough - case webhook_module.HookEventPullRequestLabel: - fallthrough - case webhook_module.HookEventPullRequestMilestone: - fallthrough - case webhook_module.HookEventPullRequestComment: - fallthrough - case webhook_module.HookEventPullRequestReviewApproved: - fallthrough - case webhook_module.HookEventPullRequestReviewRejected: - fallthrough - case webhook_module.HookEventPullRequestReviewComment: - fallthrough - case webhook_module.HookEventPullRequestSync: - fallthrough - case webhook_module.HookEventWiki: - fallthrough - case webhook_module.HookEventRepository: - fallthrough - case webhook_module.HookEventRelease: - fallthrough - case webhook_module.HookEventPackage: - fallthrough - default: - log.Warn("unsupported event %q", triggedEvent.Event()) } - return false + return matchTimes == len(evt.Acts) } From 5feb31f2197c3672a2ea8efc2b4226e498ab7674 Mon Sep 17 00:00:00 2001 From: Giteabot Date: Wed, 15 Mar 2023 02:21:59 -0400 Subject: [PATCH 091/340] Bump webpack from 5.75.0 to 5.76.0 (#23484) (#23487) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Backport #23484 by @dependabot[bot] Bumps [webpack](https://github.com/webpack/webpack) from 5.75.0 to 5.76.0.
Release notes

Sourced from webpack's releases.

v5.76.0

Bugfixes

Features

Security

Repo Changes

New Contributors

Full Changelog: https://github.com/webpack/webpack/compare/v5.75.0...v5.76.0

Commits
  • 97b1718 Merge pull request #16781 from askoufis/loader-context-target-type
  • b84efe6 Merge pull request #16759 from ryanwilsonperkin/real-content-hash-regex-perf
  • c98e9e0 Merge pull request #16493 from piwysocki/patch-1
  • 5f34acf feat: Add target to LoaderContext type
  • b7fc4d8 Merge pull request #16703 from ryanwilsonperkin/ryanwilsonperkin/fix-16160
  • 63ea82d Merge branch 'webpack:main' into patch-1
  • 4ba2252 Merge pull request #16446 from akhilgkrishnan/patch-1
  • 1acd635 Merge pull request #16613 from jakebailey/ts-logo
  • 302eb37 Merge pull request #16614 from jakebailey/html5-logo
  • cfdb1df Improve performance of hashRegExp lookup
  • Additional commits viewable in compare view
Maintainer changes

This version was pushed to npm by evilebottnawi, a new releaser for webpack since your current version.


[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=webpack&package-manager=npm_and_yarn&previous-version=5.75.0&new-version=5.76.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) - `@dependabot use these labels` will set the current labels as the default for future PRs for this repo and language - `@dependabot use these reviewers` will set the current reviewers as the default for future PRs for this repo and language - `@dependabot use these assignees` will set the current assignees as the default for future PRs for this repo and language - `@dependabot use this milestone` will set the current milestone as the default for future PRs for this repo and language You can disable automated security fix PRs for this repo from the [Security Alerts page](https://github.com/go-gitea/gitea/network/alerts).
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 14 +++++++------- package.json | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7ec6d09d1996..e8dbdea8e9b6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -45,7 +45,7 @@ "vue-bar-graph": "2.0.0", "vue-loader": "17.0.1", "vue3-calendar-heatmap": "2.0.0", - "webpack": "5.75.0", + "webpack": "5.76.0", "webpack-cli": "5.0.1", "workbox-routing": "6.5.4", "workbox-strategies": "6.5.4", @@ -9413,9 +9413,9 @@ } }, "node_modules/webpack": { - "version": "5.75.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.75.0.tgz", - "integrity": "sha512-piaIaoVJlqMsPtX/+3KTTO6jfvrSYgauFVdt8cr9LTHKmcq/AMd4mhzsiP7ZF/PGRNPGA8336jldh9l2Kt2ogQ==", + "version": "5.76.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.76.0.tgz", + "integrity": "sha512-l5sOdYBDunyf72HW8dF23rFtWq/7Zgvt/9ftMof71E/yUb1YLOBmTgA2K4vQthB3kotMrSj609txVE0dnr2fjA==", "dependencies": { "@types/eslint-scope": "^3.7.3", "@types/estree": "^0.0.51", @@ -16847,9 +16847,9 @@ "dev": true }, "webpack": { - "version": "5.75.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.75.0.tgz", - "integrity": "sha512-piaIaoVJlqMsPtX/+3KTTO6jfvrSYgauFVdt8cr9LTHKmcq/AMd4mhzsiP7ZF/PGRNPGA8336jldh9l2Kt2ogQ==", + "version": "5.76.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.76.0.tgz", + "integrity": "sha512-l5sOdYBDunyf72HW8dF23rFtWq/7Zgvt/9ftMof71E/yUb1YLOBmTgA2K4vQthB3kotMrSj609txVE0dnr2fjA==", "requires": { "@types/eslint-scope": "^3.7.3", "@types/estree": "^0.0.51", diff --git a/package.json b/package.json index c4457fe9708f..9ced009da887 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,7 @@ "vue-bar-graph": "2.0.0", "vue-loader": "17.0.1", "vue3-calendar-heatmap": "2.0.0", - "webpack": "5.75.0", + "webpack": "5.76.0", "webpack-cli": "5.0.1", "workbox-routing": "6.5.4", "workbox-strategies": "6.5.4", From 527bbf67e85ea20a35269c4d700cdcb04c65aaab Mon Sep 17 00:00:00 2001 From: Giteabot Date: Wed, 15 Mar 2023 05:34:05 -0400 Subject: [PATCH 092/340] Fix 'View File' button in code search (#23478) (#23483) Backport #23478 by @silverwind - Right-align 'View File' button - Add 'role' attribute to button link Before: Screenshot 2023-03-14 at 22 02 16 After: Screenshot 2023-03-14 at 22 02 33 Co-authored-by: silverwind Co-authored-by: Lunny Xiao Co-authored-by: KN4CK3R --- templates/code/searchresults.tmpl | 6 +++--- templates/repo/search.tmpl | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/templates/code/searchresults.tmpl b/templates/code/searchresults.tmpl index 74721a5a674d..684e2860bff4 100644 --- a/templates/code/searchresults.tmpl +++ b/templates/code/searchresults.tmpl @@ -11,15 +11,15 @@ {{range $result := .SearchResults}} {{$repo := (index $.RepoMaps .RepoID)}}
-

- +

+ {{$repo.FullName}} {{if $repo.IsArchived}} {{$.locale.Tr "repo.desc.archived"}} {{end}} - {{.Filename}} - {{$.locale.Tr "repo.diff.view_file"}} + {{$.locale.Tr "repo.diff.view_file"}}

diff --git a/templates/repo/search.tmpl b/templates/repo/search.tmpl index 21f758e4a902..ff4e218e2def 100644 --- a/templates/repo/search.tmpl +++ b/templates/repo/search.tmpl @@ -39,9 +39,9 @@