Skip to content

Commit 54b3d7c

Browse files
authored
Merge branch 'main' into fix-owner-team-accessmode
2 parents 878feae + 5cc0801 commit 54b3d7c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+929
-863
lines changed

build/backport-locales.go

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ func main() {
6262

6363
// use old en-US as the base, and copy the new translations to the old locales
6464
enUsOld := inisOld["options/locale/locale_en-US.ini"]
65+
brokenWarned := map[string]bool{}
6566
for path, iniOld := range inisOld {
6667
if iniOld == enUsOld {
6768
continue
@@ -77,11 +78,14 @@ func main() {
7778
if secNew.HasKey(keyEnUs.Name()) {
7879
oldStr := secOld.Key(keyEnUs.Name()).String()
7980
newStr := secNew.Key(keyEnUs.Name()).String()
80-
if oldStr != "" && strings.Count(oldStr, "%") != strings.Count(newStr, "%") {
81-
fmt.Printf("WARNING: locale %s [%s]%s has different number of arguments, skipping\n", path, secEnUS.Name(), keyEnUs.Name())
82-
fmt.Printf("\told: %s\n", oldStr)
83-
fmt.Printf("\tnew: %s\n", newStr)
84-
fmt.Println("---- ")
81+
broken := oldStr != "" && strings.Count(oldStr, "%") != strings.Count(newStr, "%")
82+
broken = broken || strings.Contains(oldStr, "\n") || strings.Contains(oldStr, "\n")
83+
if broken {
84+
brokenWarned[secOld.Name()+"."+keyEnUs.Name()] = true
85+
fmt.Println("----")
86+
fmt.Printf("WARNING: skip broken locale: %s , [%s] %s\n", path, secEnUS.Name(), keyEnUs.Name())
87+
fmt.Printf("\told: %s\n", strings.ReplaceAll(oldStr, "\n", "\\n"))
88+
fmt.Printf("\tnew: %s\n", strings.ReplaceAll(newStr, "\n", "\\n"))
8589
continue
8690
}
8791
secOld.Key(keyEnUs.Name()).SetValue(newStr)
@@ -90,4 +94,25 @@ func main() {
9094
}
9195
mustNoErr(iniOld.SaveTo(path))
9296
}
97+
98+
fmt.Println("========")
99+
100+
for path, iniNew := range inisNew {
101+
for _, sec := range iniNew.Sections() {
102+
for _, key := range sec.Keys() {
103+
str := sec.Key(key.Name()).String()
104+
broken := strings.Contains(str, "\n")
105+
broken = broken || strings.HasPrefix(str, "`") != strings.HasSuffix(str, "`")
106+
broken = broken || strings.HasPrefix(str, "\"`")
107+
broken = broken || strings.HasPrefix(str, "`\"")
108+
broken = broken || strings.Count(str, `"`)%2 == 1
109+
broken = broken || strings.Count(str, "`")%2 == 1
110+
if broken && !brokenWarned[sec.Name()+"."+key.Name()] {
111+
fmt.Printf("WARNING: found broken locale: %s , [%s] %s\n", path, sec.Name(), key.Name())
112+
fmt.Printf("\tstr: %s\n", strings.ReplaceAll(str, "\n", "\\n"))
113+
fmt.Println("----")
114+
}
115+
}
116+
}
117+
}
93118
}

custom/conf/app.example.ini

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -947,10 +947,10 @@ ROUTER = console
947947
;USE_COMPAT_SSH_URI = false
948948
;;
949949
;; Close issues as long as a commit on any branch marks it as fixed
950-
;; Comma separated list of globally disabled repo units. Allowed values: repo.issues, repo.ext_issues, repo.pulls, repo.wiki, repo.ext_wiki, repo.projects, repo.packages
950+
;; Comma separated list of globally disabled repo units. Allowed values: repo.issues, repo.ext_issues, repo.pulls, repo.wiki, repo.ext_wiki, repo.projects, repo.packages, repo.actions.
951951
;DISABLED_REPO_UNITS =
952952
;;
953-
;; Comma separated list of default new repo units. Allowed values: repo.code, repo.releases, repo.issues, repo.pulls, repo.wiki, repo.projects, repo.packages.
953+
;; Comma separated list of default new repo units. Allowed values: repo.code, repo.releases, repo.issues, repo.pulls, repo.wiki, repo.projects, repo.packages, repo.actions.
954954
;; Note: Code and Releases can currently not be deactivated. If you specify default repo units you should still list them for future compatibility.
955955
;; External wiki and issue tracker can't be enabled by default as it requires additional settings.
956956
;; Disabled repo units will not be added to new repositories regardless if it is in the default list.

docs/content/doc/administration/config-cheat-sheet.en-us.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,8 @@ In addition there is _`StaticRootPath`_ which can be set as a built-in at build
103103
- `DEFAULT_CLOSE_ISSUES_VIA_COMMITS_IN_ANY_BRANCH`: **false**: Close an issue if a commit on a non default branch marks it as closed.
104104
- `ENABLE_PUSH_CREATE_USER`: **false**: Allow users to push local repositories to Gitea and have them automatically created for a user.
105105
- `ENABLE_PUSH_CREATE_ORG`: **false**: Allow users to push local repositories to Gitea and have them automatically created for an org.
106-
- `DISABLED_REPO_UNITS`: **_empty_**: Comma separated list of globally disabled repo units. Allowed values: \[repo.issues, repo.ext_issues, repo.pulls, repo.wiki, repo.ext_wiki, repo.projects\]
107-
- `DEFAULT_REPO_UNITS`: **repo.code,repo.releases,repo.issues,repo.pulls,repo.wiki,repo.projects,repo.packages**: Comma separated list of default new repo units. Allowed values: \[repo.code, repo.releases, repo.issues, repo.pulls, repo.wiki, repo.projects\]. Note: Code and Releases can currently not be deactivated. If you specify default repo units you should still list them for future compatibility. External wiki and issue tracker can't be enabled by default as it requires additional settings. Disabled repo units will not be added to new repositories regardless if it is in the default list.
106+
- `DISABLED_REPO_UNITS`: **_empty_**: Comma separated list of globally disabled repo units. Allowed values: \[repo.issues, repo.ext_issues, repo.pulls, repo.wiki, repo.ext_wiki, repo.projects, repo.packages, repo.actions\]
107+
- `DEFAULT_REPO_UNITS`: **repo.code,repo.releases,repo.issues,repo.pulls,repo.wiki,repo.projects,repo.packages**: Comma separated list of default new repo units. Allowed values: \[repo.code, repo.releases, repo.issues, repo.pulls, repo.wiki, repo.projects, repo.packages, repo.actions\]. Note: Code and Releases can currently not be deactivated. If you specify default repo units you should still list them for future compatibility. External wiki and issue tracker can't be enabled by default as it requires additional settings. Disabled repo units will not be added to new repositories regardless if it is in the default list.
108108
- `DEFAULT_FORK_REPO_UNITS`: **repo.code,repo.pulls**: Comma separated list of default forked repo units. The set of allowed values and rules is the same as `DEFAULT_REPO_UNITS`.
109109
- `PREFIX_ARCHIVE_FILES`: **true**: Prefix archive files by placing them in a directory named after the repository.
110110
- `DISABLE_MIGRATIONS`: **false**: Disable migrating feature.

models/unit/unit.go

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,11 @@ func validateDefaultRepoUnits(defaultUnits, settingDefaultUnits []Type) []Type {
151151

152152
// LoadUnitConfig load units from settings
153153
func LoadUnitConfig() {
154-
DisabledRepoUnits = FindUnitTypes(setting.Repository.DisabledRepoUnits...)
154+
var invalidKeys []string
155+
DisabledRepoUnits, invalidKeys = FindUnitTypes(setting.Repository.DisabledRepoUnits...)
156+
if len(invalidKeys) > 0 {
157+
log.Warn("Invalid keys in disabled repo units: %s", strings.Join(invalidKeys, ", "))
158+
}
155159
// Check that must units are not disabled
156160
for i, disabledU := range DisabledRepoUnits {
157161
if !disabledU.CanDisable() {
@@ -160,9 +164,15 @@ func LoadUnitConfig() {
160164
}
161165
}
162166

163-
setDefaultRepoUnits := FindUnitTypes(setting.Repository.DefaultRepoUnits...)
167+
setDefaultRepoUnits, invalidKeys := FindUnitTypes(setting.Repository.DefaultRepoUnits...)
168+
if len(invalidKeys) > 0 {
169+
log.Warn("Invalid keys in default repo units: %s", strings.Join(invalidKeys, ", "))
170+
}
164171
DefaultRepoUnits = validateDefaultRepoUnits(DefaultRepoUnits, setDefaultRepoUnits)
165-
setDefaultForkRepoUnits := FindUnitTypes(setting.Repository.DefaultForkRepoUnits...)
172+
setDefaultForkRepoUnits, invalidKeys := FindUnitTypes(setting.Repository.DefaultForkRepoUnits...)
173+
if len(invalidKeys) > 0 {
174+
log.Warn("Invalid keys in default fork repo units: %s", strings.Join(invalidKeys, ", "))
175+
}
166176
DefaultForkRepoUnits = validateDefaultRepoUnits(DefaultForkRepoUnits, setDefaultForkRepoUnits)
167177
}
168178

@@ -312,7 +322,7 @@ var (
312322

313323
UnitActions = Unit{
314324
TypeActions,
315-
"actions.actions",
325+
"repo.actions",
316326
"/actions",
317327
"actions.unit.desc",
318328
7,
@@ -334,22 +344,19 @@ var (
334344
}
335345
)
336346

337-
// FindUnitTypes give the unit key names and return unit
338-
func FindUnitTypes(nameKeys ...string) (res []Type) {
347+
// FindUnitTypes give the unit key names and return valid unique units and invalid keys
348+
func FindUnitTypes(nameKeys ...string) (res []Type, invalidKeys []string) {
349+
m := map[Type]struct{}{}
339350
for _, key := range nameKeys {
340-
var found bool
341-
for t, u := range Units {
342-
if strings.EqualFold(key, u.NameKey) {
343-
res = append(res, t)
344-
found = true
345-
break
346-
}
347-
}
348-
if !found {
349-
res = append(res, TypeInvalid)
351+
t := TypeFromKey(key)
352+
if t == TypeInvalid {
353+
invalidKeys = append(invalidKeys, key)
354+
} else if _, ok := m[t]; !ok {
355+
res = append(res, t)
356+
m[t] = struct{}{}
350357
}
351358
}
352-
return res
359+
return res, invalidKeys
353360
}
354361

355362
// TypeFromKey give the unit key name and return unit

models/unit/unit_test.go

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// Copyright 2023 The Gitea Authors. All rights reserved.
2+
// SPDX-License-Identifier: MIT
3+
4+
package unit
5+
6+
import (
7+
"testing"
8+
9+
"code.gitea.io/gitea/modules/setting"
10+
11+
"github.com/stretchr/testify/assert"
12+
)
13+
14+
func TestLoadUnitConfig(t *testing.T) {
15+
defer func(disabledRepoUnits, defaultRepoUnits, defaultForkRepoUnits []Type) {
16+
DisabledRepoUnits = disabledRepoUnits
17+
DefaultRepoUnits = defaultRepoUnits
18+
DefaultForkRepoUnits = defaultForkRepoUnits
19+
}(DisabledRepoUnits, DefaultRepoUnits, DefaultForkRepoUnits)
20+
defer func(disabledRepoUnits, defaultRepoUnits, defaultForkRepoUnits []string) {
21+
setting.Repository.DisabledRepoUnits = disabledRepoUnits
22+
setting.Repository.DefaultRepoUnits = defaultRepoUnits
23+
setting.Repository.DefaultForkRepoUnits = defaultForkRepoUnits
24+
}(setting.Repository.DisabledRepoUnits, setting.Repository.DefaultRepoUnits, setting.Repository.DefaultForkRepoUnits)
25+
26+
t.Run("regular", func(t *testing.T) {
27+
setting.Repository.DisabledRepoUnits = []string{"repo.issues"}
28+
setting.Repository.DefaultRepoUnits = []string{"repo.code", "repo.releases", "repo.issues", "repo.pulls"}
29+
setting.Repository.DefaultForkRepoUnits = []string{"repo.releases"}
30+
LoadUnitConfig()
31+
assert.Equal(t, []Type{TypeIssues}, DisabledRepoUnits)
32+
assert.Equal(t, []Type{TypeCode, TypeReleases, TypePullRequests}, DefaultRepoUnits)
33+
assert.Equal(t, []Type{TypeCode, TypeReleases}, DefaultForkRepoUnits)
34+
})
35+
t.Run("invalid", func(t *testing.T) {
36+
setting.Repository.DisabledRepoUnits = []string{"repo.issues", "invalid.1"}
37+
setting.Repository.DefaultRepoUnits = []string{"repo.code", "invalid.2", "repo.releases", "repo.issues", "repo.pulls"}
38+
setting.Repository.DefaultForkRepoUnits = []string{"invalid.3", "repo.releases"}
39+
LoadUnitConfig()
40+
assert.Equal(t, []Type{TypeIssues}, DisabledRepoUnits)
41+
assert.Equal(t, []Type{TypeCode, TypeReleases, TypePullRequests}, DefaultRepoUnits)
42+
assert.Equal(t, []Type{TypeCode, TypeReleases}, DefaultForkRepoUnits)
43+
})
44+
t.Run("duplicate", func(t *testing.T) {
45+
setting.Repository.DisabledRepoUnits = []string{"repo.issues", "repo.issues"}
46+
setting.Repository.DefaultRepoUnits = []string{"repo.code", "repo.releases", "repo.issues", "repo.pulls", "repo.code"}
47+
setting.Repository.DefaultForkRepoUnits = []string{"repo.releases", "repo.releases"}
48+
LoadUnitConfig()
49+
assert.Equal(t, []Type{TypeIssues}, DisabledRepoUnits)
50+
assert.Equal(t, []Type{TypeCode, TypeReleases, TypePullRequests}, DefaultRepoUnits)
51+
assert.Equal(t, []Type{TypeCode, TypeReleases}, DefaultForkRepoUnits)
52+
})
53+
}

modules/context/context.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -628,7 +628,9 @@ func (ctx *Context) Value(key interface{}) interface{} {
628628
if key == git.RepositoryContextKey && ctx.Repo != nil {
629629
return ctx.Repo.GitRepo
630630
}
631-
631+
if key == translation.ContextKey && ctx.Locale != nil {
632+
return ctx.Locale
633+
}
632634
return ctx.Req.Context().Value(key)
633635
}
634636

modules/markup/html.go

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"code.gitea.io/gitea/modules/regexplru"
2323
"code.gitea.io/gitea/modules/setting"
2424
"code.gitea.io/gitea/modules/templates/vars"
25+
"code.gitea.io/gitea/modules/translation"
2526
"code.gitea.io/gitea/modules/util"
2627

2728
"golang.org/x/net/html"
@@ -97,14 +98,30 @@ var issueFullPattern *regexp.Regexp
9798
// Once for to prevent races
9899
var issueFullPatternOnce sync.Once
99100

101+
// regexp for full links to hash comment in pull request files changed tab
102+
var filesChangedFullPattern *regexp.Regexp
103+
104+
// Once for to prevent races
105+
var filesChangedFullPatternOnce sync.Once
106+
100107
func getIssueFullPattern() *regexp.Regexp {
101108
issueFullPatternOnce.Do(func() {
109+
// example: https://domain/org/repo/pulls/27#hash
102110
issueFullPattern = regexp.MustCompile(regexp.QuoteMeta(setting.AppURL) +
103111
`[\w_.-]+/[\w_.-]+/(?:issues|pulls)/((?:\w{1,10}-)?[1-9][0-9]*)([\?|#](\S+)?)?\b`)
104112
})
105113
return issueFullPattern
106114
}
107115

116+
func getFilesChangedFullPattern() *regexp.Regexp {
117+
filesChangedFullPatternOnce.Do(func() {
118+
// example: https://domain/org/repo/pulls/27/files#hash
119+
filesChangedFullPattern = regexp.MustCompile(regexp.QuoteMeta(setting.AppURL) +
120+
`[\w_.-]+/[\w_.-]+/pulls/((?:\w{1,10}-)?[1-9][0-9]*)/files([\?|#](\S+)?)?\b`)
121+
})
122+
return filesChangedFullPattern
123+
}
124+
108125
// CustomLinkURLSchemes allows for additional schemes to be detected when parsing links within text
109126
func CustomLinkURLSchemes(schemes []string) {
110127
schemes = append(schemes, "http", "https")
@@ -793,15 +810,30 @@ func fullIssuePatternProcessor(ctx *RenderContext, node *html.Node) {
793810
if ctx.Metas == nil {
794811
return
795812
}
796-
797813
next := node.NextSibling
798814
for node != nil && node != next {
799815
m := getIssueFullPattern().FindStringSubmatchIndex(node.Data)
800816
if m == nil {
801817
return
802818
}
819+
820+
mDiffView := getFilesChangedFullPattern().FindStringSubmatchIndex(node.Data)
821+
// leave it as it is if the link is from "Files Changed" tab in PR Diff View https://domain/org/repo/pulls/27/files
822+
if mDiffView != nil {
823+
return
824+
}
825+
803826
link := node.Data[m[0]:m[1]]
804-
id := "#" + node.Data[m[2]:m[3]]
827+
text := "#" + node.Data[m[2]:m[3]]
828+
// if m[4] and m[5] is not -1, then link is to a comment
829+
// indicate that in the text by appending (comment)
830+
if m[4] != -1 && m[5] != -1 {
831+
if locale, ok := ctx.Ctx.Value(translation.ContextKey).(translation.Locale); ok {
832+
text += " " + locale.Tr("repo.from_comment")
833+
} else {
834+
text += " (comment)"
835+
}
836+
}
805837

806838
// extract repo and org name from matched link like
807839
// http://localhost:3000/gituser/myrepo/issues/1
@@ -810,12 +842,10 @@ func fullIssuePatternProcessor(ctx *RenderContext, node *html.Node) {
810842
matchRepo := linkParts[len(linkParts)-3]
811843

812844
if matchOrg == ctx.Metas["user"] && matchRepo == ctx.Metas["repo"] {
813-
// TODO if m[4]:m[5] is not nil, then link is to a comment,
814-
// and we should indicate that in the text somehow
815-
replaceContent(node, m[0], m[1], createLink(link, id, "ref-issue"))
845+
replaceContent(node, m[0], m[1], createLink(link, text, "ref-issue"))
816846
} else {
817-
orgRepoID := matchOrg + "/" + matchRepo + id
818-
replaceContent(node, m[0], m[1], createLink(link, orgRepoID, "ref-issue"))
847+
text = matchOrg + "/" + matchRepo + text
848+
replaceContent(node, m[0], m[1], createLink(link, text, "ref-issue"))
819849
}
820850
node = node.NextSibling.NextSibling
821851
}

modules/markup/html_internal_test.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -330,13 +330,17 @@ func TestRender_FullIssueURLs(t *testing.T) {
330330
test("Look here http://localhost:3000/person/repo/issues/4",
331331
`Look here <a href="http://localhost:3000/person/repo/issues/4" class="ref-issue">person/repo#4</a>`)
332332
test("http://localhost:3000/person/repo/issues/4#issuecomment-1234",
333-
`<a href="http://localhost:3000/person/repo/issues/4#issuecomment-1234" class="ref-issue">person/repo#4</a>`)
333+
`<a href="http://localhost:3000/person/repo/issues/4#issuecomment-1234" class="ref-issue">person/repo#4 (comment)</a>`)
334334
test("http://localhost:3000/gogits/gogs/issues/4",
335335
`<a href="http://localhost:3000/gogits/gogs/issues/4" class="ref-issue">#4</a>`)
336336
test("http://localhost:3000/gogits/gogs/issues/4 test",
337337
`<a href="http://localhost:3000/gogits/gogs/issues/4" class="ref-issue">#4</a> test`)
338338
test("http://localhost:3000/gogits/gogs/issues/4?a=1&b=2#comment-123 test",
339-
`<a href="http://localhost:3000/gogits/gogs/issues/4?a=1&amp;b=2#comment-123" class="ref-issue">#4</a> test`)
339+
`<a href="http://localhost:3000/gogits/gogs/issues/4?a=1&amp;b=2#comment-123" class="ref-issue">#4 (comment)</a> test`)
340+
test("http://localhost:3000/testOrg/testOrgRepo/pulls/2/files#issuecomment-24",
341+
"http://localhost:3000/testOrg/testOrgRepo/pulls/2/files#issuecomment-24")
342+
test("http://localhost:3000/testOrg/testOrgRepo/pulls/2/files",
343+
"http://localhost:3000/testOrg/testOrgRepo/pulls/2/files")
340344
}
341345

342346
func TestRegExp_sha1CurrentPattern(t *testing.T) {

modules/translation/translation.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ import (
1818
"golang.org/x/text/language"
1919
)
2020

21+
type contextKey struct{}
22+
23+
var ContextKey interface{} = &contextKey{}
24+
2125
// Locale represents an interface to translation
2226
type Locale interface {
2327
Language() string

options/locale/locale_en-US.ini

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1057,6 +1057,7 @@ issues = Issues
10571057
pulls = Pull Requests
10581058
project_board = Projects
10591059
packages = Packages
1060+
actions = Actions
10601061
labels = Labels
10611062
org_labels_desc = Organization level labels that can be used with <strong>all repositories</strong> under this organization
10621063
org_labels_desc_manage = manage
@@ -1103,6 +1104,7 @@ download_file = Download file
11031104
normal_view = Normal View
11041105
line = line
11051106
lines = lines
1107+
from_comment = (comment)
11061108

11071109
editor.add_file = Add File
11081110
editor.new_file = New File

package-lock.json

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
"@citation-js/plugin-csl": "0.6.7",
1313
"@citation-js/plugin-software-formats": "0.6.1",
1414
"@claviska/jquery-minicolors": "2.3.6",
15+
"@github/markdown-toolbar-element": "2.1.1",
1516
"@mcaptcha/vanilla-glue": "0.1.0-alpha-3",
1617
"@primer/octicons": "18.3.0",
1718
"@vue/compiler-sfc": "3.2.47",

routers/api/v1/org/team.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ func GetTeam(ctx *context.APIContext) {
135135
}
136136

137137
func attachTeamUnits(team *organization.Team, units []string) {
138-
unitTypes := unit_model.FindUnitTypes(units...)
138+
unitTypes, _ := unit_model.FindUnitTypes(units...)
139139
team.Units = make([]*organization.TeamUnit, 0, len(units))
140140
for _, tp := range unitTypes {
141141
team.Units = append(team.Units, &organization.TeamUnit{

0 commit comments

Comments
 (0)