Skip to content

Commit a58278f

Browse files
authored
Merge branch 'main' into lock-pin-fetch
2 parents bf79406 + bb31f36 commit a58278f

File tree

95 files changed

+525
-422
lines changed

Some content is hidden

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

95 files changed

+525
-422
lines changed

.devcontainer/devcontainer.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
"ghcr.io/devcontainers/features/node:1": {
77
"version":"20"
88
},
9-
"ghcr.io/devcontainers/features/git-lfs:1.1.0": {}
9+
"ghcr.io/devcontainers/features/git-lfs:1.1.0": {},
10+
"ghcr.io/devcontainers-contrib/features/poetry:2": {},
11+
"ghcr.io/devcontainers/features/python:1": {}
1012
},
1113
"customizations": {
1214
"vscode": {

custom/conf/app.example.ini

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -344,9 +344,6 @@ NAME = gitea
344344
USER = root
345345
;PASSWD = ;Use PASSWD = `your password` for quoting if you use special characters in the password.
346346
;SSL_MODE = false ; either "false" (default), "true", or "skip-verify"
347-
;CHARSET = utf8mb4 ;either "utf8" or "utf8mb4", default is "utf8mb4".
348-
;;
349-
;; NOTICE: for "utf8mb4" you must use MySQL InnoDB > 5.6. Gitea is unable to check this.
350347
;;
351348
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
352349
;;

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -443,7 +443,6 @@ The following configuration set `Content-Type: application/vnd.android.package-a
443443
- `SQLITE_TIMEOUT`: **500**: Query timeout for SQLite3 only.
444444
- `SQLITE_JOURNAL_MODE`: **""**: Change journal mode for SQlite3. Can be used to enable [WAL mode](https://www.sqlite.org/wal.html) when high load causes write congestion. See [SQlite3 docs](https://www.sqlite.org/pragma.html#pragma_journal_mode) for possible values. Defaults to the default for the database file, often DELETE.
445445
- `ITERATE_BUFFER_SIZE`: **50**: Internal buffer size for iterating.
446-
- `CHARSET`: **utf8mb4**: For MySQL only, either "utf8" or "utf8mb4". NOTICE: for "utf8mb4" you must use MySQL InnoDB > 5.6. Gitea is unable to check this.
447446
- `PATH`: **data/gitea.db**: For SQLite3 only, the database file path.
448447
- `LOG_SQL`: **true**: Log the executed SQL.
449448
- `DB_RETRIES`: **10**: How many ORM init / DB connect attempts allowed.

docs/content/doc/help/faq.en-us.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -396,8 +396,6 @@ Please run `gitea convert`, or run `ALTER DATABASE database_name CHARACTER SET u
396396
for the database_name and run `ALTER TABLE table_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;`
397397
for each table in the database.
398398

399-
You will also need to change the app.ini database charset to `CHARSET=utf8mb4`.
400-
401399
## Why are Emoji displaying only as placeholders or in monochrome
402400

403401
Gitea requires the system or browser to have one of the supported Emoji fonts installed, which are Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol, Noto Color Emoji and Twemoji Mozilla. Generally, the operating system should already provide one of these fonts, but especially on Linux, it may be necessary to install them manually.

models/issues/comment_code.go

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,11 @@ import (
1818
type CodeComments map[string]map[int64][]*Comment
1919

2020
// FetchCodeComments will return a 2d-map: ["Path"]["Line"] = Comments at line
21-
func FetchCodeComments(ctx context.Context, issue *Issue, currentUser *user_model.User) (CodeComments, error) {
22-
return fetchCodeCommentsByReview(ctx, issue, currentUser, nil)
21+
func FetchCodeComments(ctx context.Context, issue *Issue, currentUser *user_model.User, showOutdatedComments bool) (CodeComments, error) {
22+
return fetchCodeCommentsByReview(ctx, issue, currentUser, nil, showOutdatedComments)
2323
}
2424

25-
func fetchCodeCommentsByReview(ctx context.Context, issue *Issue, currentUser *user_model.User, review *Review) (CodeComments, error) {
25+
func fetchCodeCommentsByReview(ctx context.Context, issue *Issue, currentUser *user_model.User, review *Review, showOutdatedComments bool) (CodeComments, error) {
2626
pathToLineToComment := make(CodeComments)
2727
if review == nil {
2828
review = &Review{ID: 0}
@@ -33,7 +33,7 @@ func fetchCodeCommentsByReview(ctx context.Context, issue *Issue, currentUser *u
3333
ReviewID: review.ID,
3434
}
3535

36-
comments, err := findCodeComments(ctx, opts, issue, currentUser, review)
36+
comments, err := findCodeComments(ctx, opts, issue, currentUser, review, showOutdatedComments)
3737
if err != nil {
3838
return nil, err
3939
}
@@ -47,15 +47,17 @@ func fetchCodeCommentsByReview(ctx context.Context, issue *Issue, currentUser *u
4747
return pathToLineToComment, nil
4848
}
4949

50-
func findCodeComments(ctx context.Context, opts FindCommentsOptions, issue *Issue, currentUser *user_model.User, review *Review) ([]*Comment, error) {
50+
func findCodeComments(ctx context.Context, opts FindCommentsOptions, issue *Issue, currentUser *user_model.User, review *Review, showOutdatedComments bool) ([]*Comment, error) {
5151
var comments CommentList
5252
if review == nil {
5353
review = &Review{ID: 0}
5454
}
5555
conds := opts.ToConds()
56-
if review.ID == 0 {
56+
57+
if !showOutdatedComments && review.ID == 0 {
5758
conds = conds.And(builder.Eq{"invalidated": false})
5859
}
60+
5961
e := db.GetEngine(ctx)
6062
if err := e.Where(conds).
6163
Asc("comment.created_unix").
@@ -118,12 +120,12 @@ func findCodeComments(ctx context.Context, opts FindCommentsOptions, issue *Issu
118120
}
119121

120122
// FetchCodeCommentsByLine fetches the code comments for a given treePath and line number
121-
func FetchCodeCommentsByLine(ctx context.Context, issue *Issue, currentUser *user_model.User, treePath string, line int64) ([]*Comment, error) {
123+
func FetchCodeCommentsByLine(ctx context.Context, issue *Issue, currentUser *user_model.User, treePath string, line int64, showOutdatedComments bool) ([]*Comment, error) {
122124
opts := FindCommentsOptions{
123125
Type: CommentTypeCode,
124126
IssueID: issue.ID,
125127
TreePath: treePath,
126128
Line: line,
127129
}
128-
return findCodeComments(ctx, opts, issue, currentUser, nil)
130+
return findCodeComments(ctx, opts, issue, currentUser, nil, showOutdatedComments)
129131
}

models/issues/comment_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,15 +50,15 @@ func TestFetchCodeComments(t *testing.T) {
5050

5151
issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2})
5252
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
53-
res, err := issues_model.FetchCodeComments(db.DefaultContext, issue, user)
53+
res, err := issues_model.FetchCodeComments(db.DefaultContext, issue, user, false)
5454
assert.NoError(t, err)
5555
assert.Contains(t, res, "README.md")
5656
assert.Contains(t, res["README.md"], int64(4))
5757
assert.Len(t, res["README.md"][4], 1)
5858
assert.Equal(t, int64(4), res["README.md"][4][0].ID)
5959

6060
user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
61-
res, err = issues_model.FetchCodeComments(db.DefaultContext, issue, user2)
61+
res, err = issues_model.FetchCodeComments(db.DefaultContext, issue, user2, false)
6262
assert.NoError(t, err)
6363
assert.Len(t, res, 1)
6464
}

models/issues/review.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ func (r *Review) LoadCodeComments(ctx context.Context) (err error) {
141141
if err = r.loadIssue(ctx); err != nil {
142142
return
143143
}
144-
r.CodeComments, err = fetchCodeCommentsByReview(ctx, r.Issue, nil, r)
144+
r.CodeComments, err = fetchCodeCommentsByReview(ctx, r.Issue, nil, r, false)
145145
return err
146146
}
147147

models/user/setting_keys.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ const (
88
SettingsKeyHiddenCommentTypes = "issue.hidden_comment_types"
99
// SettingsKeyDiffWhitespaceBehavior is the setting key for whitespace behavior of diff
1010
SettingsKeyDiffWhitespaceBehavior = "diff.whitespace_behaviour"
11+
// SettingsKeyShowOutdatedComments is the setting key wether or not to show outdated comments in PRs
12+
SettingsKeyShowOutdatedComments = "comment_code.show_outdated"
1113
// UserActivityPubPrivPem is user's private key
1214
UserActivityPubPrivPem = "activitypub.priv_pem"
1315
// UserActivityPubPubPem is user's public key

modules/repository/generate.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -372,12 +372,12 @@ func GenerateRepository(ctx context.Context, doer, owner *user_model.User, templ
372372
return generateRepo, nil
373373
}
374374

375+
var fileNameSanitizeRegexp = regexp.MustCompile(`(?i)\.\.|[<>:\"/\\|?*\x{0000}-\x{001F}]|^(con|prn|aux|nul|com\d|lpt\d)$`)
376+
375377
// Sanitize user input to valid OS filenames
376378
//
377379
// Based on https://github.com/sindresorhus/filename-reserved-regex
378380
// Adds ".." to prevent directory traversal
379381
func fileNameSanitize(s string) string {
380-
re := regexp.MustCompile(`(?i)\.\.|[<>:\"/\\|?*\x{0000}-\x{001F}]|^(con|prn|aux|nul|com\d|lpt\d)$`)
381-
382-
return strings.TrimSpace(re.ReplaceAllString(s, "_"))
382+
return strings.TrimSpace(fileNameSanitizeRegexp.ReplaceAllString(s, "_"))
383383
}

modules/setting/database.go

Lines changed: 9 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@ import (
1212
"path/filepath"
1313
"strings"
1414
"time"
15-
16-
"code.gitea.io/gitea/modules/log"
1715
)
1816

1917
var (
@@ -36,7 +34,7 @@ var (
3634
SSLMode string
3735
Path string
3836
LogSQL bool
39-
Charset string
37+
MysqlCharset string
4038
Timeout int // seconds
4139
SQLiteJournalMode string
4240
DBConnectRetries int
@@ -60,11 +58,6 @@ func LoadDBSetting() {
6058
func loadDBSetting(rootCfg ConfigProvider) {
6159
sec := rootCfg.Section("database")
6260
Database.Type = DatabaseType(sec.Key("DB_TYPE").String())
63-
defaultCharset := "utf8"
64-
65-
if Database.Type.IsMySQL() {
66-
defaultCharset = "utf8mb4"
67-
}
6861

6962
Database.Host = sec.Key("HOST").String()
7063
Database.Name = sec.Key("NAME").String()
@@ -74,10 +67,7 @@ func loadDBSetting(rootCfg ConfigProvider) {
7467
}
7568
Database.Schema = sec.Key("SCHEMA").String()
7669
Database.SSLMode = sec.Key("SSL_MODE").MustString("disable")
77-
Database.Charset = sec.Key("CHARSET").In(defaultCharset, []string{"utf8", "utf8mb4"})
78-
if Database.Type.IsMySQL() && defaultCharset != "utf8mb4" {
79-
log.Error("Deprecated database mysql charset utf8 support, please use utf8mb4 or convert utf8 to utf8mb4.")
80-
}
70+
Database.MysqlCharset = sec.Key("MYSQL_CHARSET").MustString("utf8mb4") // do not document it, end users won't need it.
8171

8272
Database.Path = sec.Key("PATH").MustString(filepath.Join(AppDataPath, "gitea.db"))
8373
Database.Timeout = sec.Key("SQLITE_TIMEOUT").MustInt(500)
@@ -101,9 +91,9 @@ func loadDBSetting(rootCfg ConfigProvider) {
10191
// DBConnStr returns database connection string
10292
func DBConnStr() (string, error) {
10393
var connStr string
104-
Param := "?"
105-
if strings.Contains(Database.Name, Param) {
106-
Param = "&"
94+
paramSep := "?"
95+
if strings.Contains(Database.Name, paramSep) {
96+
paramSep = "&"
10797
}
10898
switch Database.Type {
10999
case "mysql":
@@ -116,15 +106,15 @@ func DBConnStr() (string, error) {
116106
tls = "false"
117107
}
118108
connStr = fmt.Sprintf("%s:%s@%s(%s)/%s%scharset=%s&parseTime=true&tls=%s",
119-
Database.User, Database.Passwd, connType, Database.Host, Database.Name, Param, Database.Charset, tls)
109+
Database.User, Database.Passwd, connType, Database.Host, Database.Name, paramSep, Database.MysqlCharset, tls)
120110
case "postgres":
121-
connStr = getPostgreSQLConnectionString(Database.Host, Database.User, Database.Passwd, Database.Name, Param, Database.SSLMode)
111+
connStr = getPostgreSQLConnectionString(Database.Host, Database.User, Database.Passwd, Database.Name, paramSep, Database.SSLMode)
122112
case "mssql":
123113
host, port := ParseMSSQLHostPort(Database.Host)
124114
connStr = fmt.Sprintf("server=%s; port=%s; database=%s; user id=%s; password=%s;", host, port, Database.Name, Database.User, Database.Passwd)
125115
case "sqlite3":
126116
if !EnableSQLite3 {
127-
return "", errors.New("this binary version does not build support for SQLite3")
117+
return "", errors.New("this Gitea binary was not built with SQLite3 support")
128118
}
129119
if err := os.MkdirAll(path.Dir(Database.Path), os.ModePerm); err != nil {
130120
return "", fmt.Errorf("Failed to create directories: %w", err)
@@ -136,7 +126,7 @@ func DBConnStr() (string, error) {
136126
connStr = fmt.Sprintf("file:%s?cache=shared&mode=rwc&_busy_timeout=%d&_txlock=immediate%s",
137127
Database.Path, Database.Timeout, journalMode)
138128
default:
139-
return "", fmt.Errorf("Unknown database type: %s", Database.Type)
129+
return "", fmt.Errorf("unknown database type: %s", Database.Type)
140130
}
141131

142132
return connStr, nil

modules/structs/repo.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ import (
1010

1111
// Permission represents a set of permissions
1212
type Permission struct {
13-
Admin bool `json:"admin"`
14-
Push bool `json:"push"`
15-
Pull bool `json:"pull"`
13+
Admin bool `json:"admin"` // Admin indicates if the user is an administrator of the repository.
14+
Push bool `json:"push"` // Push indicates if the user can push code to the repository.
15+
Pull bool `json:"pull"` // Pull indicates if the user can pull code from the repository.
1616
}
1717

1818
// InternalTracker represents settings for internal tracker

modules/templates/util_render.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,16 +81,16 @@ func RenderCommitMessageLinkSubject(ctx context.Context, msg, urlPrefix, urlDefa
8181

8282
// RenderCommitBody extracts the body of a commit message without its title.
8383
func RenderCommitBody(ctx context.Context, msg, urlPrefix string, metas map[string]string) template.HTML {
84-
msgLine := strings.TrimRightFunc(msg, unicode.IsSpace)
84+
msgLine := strings.TrimSpace(msg)
8585
lineEnd := strings.IndexByte(msgLine, '\n')
8686
if lineEnd > 0 {
8787
msgLine = msgLine[lineEnd+1:]
8888
} else {
89-
return template.HTML("")
89+
return ""
9090
}
9191
msgLine = strings.TrimLeftFunc(msgLine, unicode.IsSpace)
9292
if len(msgLine) == 0 {
93-
return template.HTML("")
93+
return ""
9494
}
9595

9696
renderedMessage, err := markup.RenderCommitMessage(&markup.RenderContext{

modules/templates/util_render_test.go

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// Copyright 2023 The Gitea Authors. All rights reserved.
2+
// SPDX-License-Identifier: MIT
3+
4+
package templates
5+
6+
import (
7+
"context"
8+
"html/template"
9+
"testing"
10+
11+
"github.com/stretchr/testify/assert"
12+
)
13+
14+
func TestRenderCommitBody(t *testing.T) {
15+
type args struct {
16+
ctx context.Context
17+
msg string
18+
urlPrefix string
19+
metas map[string]string
20+
}
21+
tests := []struct {
22+
name string
23+
args args
24+
want template.HTML
25+
}{
26+
{
27+
name: "multiple lines",
28+
args: args{
29+
ctx: context.Background(),
30+
msg: "first line\nsecond line",
31+
},
32+
want: "second line",
33+
},
34+
{
35+
name: "multiple lines with leading newlines",
36+
args: args{
37+
ctx: context.Background(),
38+
msg: "\n\n\n\nfirst line\nsecond line",
39+
},
40+
want: "second line",
41+
},
42+
{
43+
name: "multiple lines with trailing newlines",
44+
args: args{
45+
ctx: context.Background(),
46+
msg: "first line\nsecond line\n\n\n",
47+
},
48+
want: "second line",
49+
},
50+
}
51+
for _, tt := range tests {
52+
t.Run(tt.name, func(t *testing.T) {
53+
assert.Equalf(t, tt.want, RenderCommitBody(tt.args.ctx, tt.args.msg, tt.args.urlPrefix, tt.args.metas), "RenderCommitBody(%v, %v, %v, %v)", tt.args.ctx, tt.args.msg, tt.args.urlPrefix, tt.args.metas)
54+
})
55+
}
56+
}

modules/util/path.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,8 @@ func isOSWindows() bool {
222222
return runtime.GOOS == "windows"
223223
}
224224

225+
var driveLetterRegexp = regexp.MustCompile("/[A-Za-z]:/")
226+
225227
// FileURLToPath extracts the path information from a file://... url.
226228
func FileURLToPath(u *url.URL) (string, error) {
227229
if u.Scheme != "file" {
@@ -235,8 +237,7 @@ func FileURLToPath(u *url.URL) (string, error) {
235237
}
236238

237239
// If it looks like there's a Windows drive letter at the beginning, strip off the leading slash.
238-
re := regexp.MustCompile("/[A-Za-z]:/")
239-
if re.MatchString(path) {
240+
if driveLetterRegexp.MatchString(path) {
240241
return path[1:], nil
241242
}
242243
return path, nil

options/locale/locale_en-US.ini

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -197,11 +197,9 @@ host = Host
197197
user = Username
198198
password = Password
199199
db_name = Database Name
200-
db_helper = Note to MySQL users: please use the InnoDB storage engine and if you use "utf8mb4", your InnoDB version must be greater than 5.6 .
201200
db_schema = Schema
202201
db_schema_helper = Leave blank for database default ("public").
203202
ssl_mode = SSL
204-
charset = Charset
205203
path = Path
206204
sqlite_helper = File path for the SQLite3 database.<br>Enter an absolute path if you run Gitea as a service.
207205
reinstall_error = You are trying to install into an existing Gitea database
@@ -664,7 +662,7 @@ comment_type_group_project = Project
664662
comment_type_group_issue_ref = Issue reference
665663
saved_successfully = Your settings were saved successfully.
666664
privacy = Privacy
667-
keep_activity_private = Hide the activity from the profile page
665+
keep_activity_private = Hide Activity from profile page
668666
keep_activity_private_popup = Makes the activity visible only for you and the admins
669667

670668
lookup_avatar_by_mail = Look Up Avatar by Email Address
@@ -1613,6 +1611,9 @@ issues.review.pending.tooltip = This comment is not currently visible to other u
16131611
issues.review.review = Review
16141612
issues.review.reviewers = Reviewers
16151613
issues.review.outdated = Outdated
1614+
issues.review.outdated_description = Content has changed since this comment was made
1615+
issues.review.option.show_outdated_comments = Show outdated comments
1616+
issues.review.option.hide_outdated_comments = Hide outdated comments
16161617
issues.review.show_outdated = Show outdated
16171618
issues.review.hide_outdated = Hide outdated
16181619
issues.review.show_resolved = Show resolved

0 commit comments

Comments
 (0)