Skip to content

Commit 2cba695

Browse files
authored
Merge branch 'master' into slight-performance-improvement-for-last-commit-cache
2 parents 0a5988a + df416f2 commit 2cba695

Some content is hidden

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

71 files changed

+1367
-750
lines changed

Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,9 +210,10 @@ git-check:
210210
.PHONY: node-check
211211
node-check:
212212
$(eval NODE_VERSION := $(shell printf "%03d%03d%03d" $(shell node -v | cut -c2- | tr '.' ' ');))
213+
$(eval MIN_NODE_VER_FMT := $(shell printf "%g.%g.%g" $(shell echo $(MIN_NODE_VERSION) | grep -o ...)))
213214
$(eval NPM_MISSING := $(shell hash npm > /dev/null 2>&1 || echo 1))
214215
@if [ "$(NODE_VERSION)" -lt "$(MIN_NODE_VERSION)" -o "$(NPM_MISSING)" = "1" ]; then \
215-
echo "Gitea requires Node.js 10 or greater and npm to build. You can get it at https://nodejs.org/en/download/"; \
216+
echo "Gitea requires Node.js $(MIN_NODE_VER_FMT) or greater and npm to build. You can get it at https://nodejs.org/en/download/"; \
216217
exit 1; \
217218
fi
218219

contrib/pr/checkout.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ func runPR() {
114114

115115
log.Printf("[PR] Setting up router\n")
116116
//routers.GlobalInit()
117-
external.RegisterParsers()
117+
external.RegisterRenderers()
118118
markup.Init()
119119
c := routes.NormalRoutes()
120120

docs/content/doc/advanced/customizing-gitea.en-us.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ environment variable; this can be used to override the default path to something
4242
`GITEA_CUSTOM` might, for example, be set by an init script. You can check whether the value
4343
is set under the "Configuration" tab on the site administration page.
4444

45-
- [List of Environment Variables](https://docs.gitea.io/en-us/specific-variables/)
45+
- [List of Environment Variables](https://docs.gitea.io/en-us/environment-variables/)
4646

4747
**Note:** Gitea must perform a full restart to see configuration changes.
4848

docs/content/doc/developers/api-usage.en-us.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,9 @@ API Reference guide is auto-generated by swagger and available on:
7979
or on
8080
[gitea demo instance](https://try.gitea.io/api/swagger)
8181

82+
The OpenAPI document is at:
83+
`https://gitea.your.host/swagger.v1.json`
84+
8285
## Listing your issued tokens via the API
8386

8487
As mentioned in

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,4 @@ If you found a bug, please create an [issue on GitHub](https://github.com/go-git
3333

3434
## Chinese Support
3535

36-
Support for the Chinese language is provided at [gocn.vip](https://gocn.vip/topic/gitea).
36+
Support for the Chinese language is provided at [Our discourse](https://discourse.gitea.io/c/5-category/5).

docs/content/doc/help/seek-help.zh-cn.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,6 @@ menu:
1818
如果您在使用或者开发过程中遇到问题,请到以下渠道咨询:
1919

2020
-[Github issue](https://github.com/go-gitea/gitea/issues)提问(因为项目维护人员来自世界各地,为保证沟通顺畅,请使用英文提问)
21-
- 中文问题到[gocn.vip](https://gocn.vip/topic/gitea)提问
21+
- 中文问题到 [Gitea 论坛](https://discourse.gitea.io/c/5-category/5)提问
2222
- 访问 [Discord server - 英文](https://discord.gg/Gitea)
2323
- 加入 QQ群 328432459 获得进一步的支持

integrations/git_clone_wiki_test.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// Copyright 2021 The Gitea Authors. All rights reserved.
2+
// Use of this source code is governed by a MIT-style
3+
// license that can be found in the LICENSE file.
4+
5+
package integrations
6+
7+
import (
8+
"context"
9+
"fmt"
10+
"io/ioutil"
11+
"net/url"
12+
"path/filepath"
13+
"testing"
14+
15+
"code.gitea.io/gitea/modules/git"
16+
"code.gitea.io/gitea/modules/util"
17+
"github.com/stretchr/testify/assert"
18+
)
19+
20+
func assertFileExist(t *testing.T, p string) {
21+
exist, err := util.IsExist(p)
22+
assert.NoError(t, err)
23+
assert.True(t, exist)
24+
}
25+
26+
func assertFileEqual(t *testing.T, p string, content []byte) {
27+
bs, err := ioutil.ReadFile(p)
28+
assert.NoError(t, err)
29+
assert.EqualValues(t, content, bs)
30+
}
31+
32+
func TestRepoCloneWiki(t *testing.T) {
33+
onGiteaRun(t, func(t *testing.T, u *url.URL) {
34+
defer prepareTestEnv(t)()
35+
36+
dstPath, err := ioutil.TempDir("", "clone_wiki")
37+
assert.NoError(t, err)
38+
39+
r := fmt.Sprintf("%suser2/repo1.wiki.git", u.String())
40+
u, _ = url.Parse(r)
41+
u.User = url.UserPassword("user2", userPassword)
42+
t.Run("Clone", func(t *testing.T) {
43+
assert.NoError(t, git.CloneWithArgs(context.Background(), u.String(), dstPath, allowLFSFilters(), git.CloneRepoOptions{}))
44+
assertFileEqual(t, filepath.Join(dstPath, "Home.md"), []byte("# Home page\n\nThis is the home page!\n"))
45+
assertFileExist(t, filepath.Join(dstPath, "Page-With-Image.md"))
46+
assertFileExist(t, filepath.Join(dstPath, "Page-With-Spaced-Name.md"))
47+
assertFileExist(t, filepath.Join(dstPath, "images"))
48+
assertFileExist(t, filepath.Join(dstPath, "jpeg.jpg"))
49+
})
50+
})
51+
}

models/avatar.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ func LibravatarURL(email string) (*url.URL, error) {
8181
}
8282

8383
// HashedAvatarLink returns an avatar link for a provided email
84-
func HashedAvatarLink(email string) string {
84+
func HashedAvatarLink(email string, size int) string {
8585
lowerEmail := strings.ToLower(strings.TrimSpace(email))
8686
sum := fmt.Sprintf("%x", md5.Sum([]byte(lowerEmail)))
8787
_, _ = cache.GetString("Avatar:"+sum, func() (string, error) {
@@ -108,6 +108,9 @@ func HashedAvatarLink(email string) string {
108108
}
109109
return lowerEmail, nil
110110
})
111+
if size > 0 {
112+
return setting.AppSubURL + "/avatar/" + url.PathEscape(sum) + "?size=" + strconv.Itoa(size)
113+
}
111114
return setting.AppSubURL + "/avatar/" + url.PathEscape(sum)
112115
}
113116

@@ -129,7 +132,7 @@ func SizedAvatarLink(email string, size int) string {
129132
// This is the slow path that would need to call LibravatarURL() which
130133
// does DNS lookups. Avoid it by issuing a redirect so we don't block
131134
// the template render with network requests.
132-
return HashedAvatarLink(email)
135+
return HashedAvatarLink(email, size)
133136
} else if !setting.DisableGravatar {
134137
// copy GravatarSourceURL, because we will modify its Path.
135138
copyOfGravatarSourceURL := *setting.GravatarSourceURL

models/issue_comment.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import (
1616

1717
"code.gitea.io/gitea/modules/git"
1818
"code.gitea.io/gitea/modules/log"
19+
"code.gitea.io/gitea/modules/markup"
1920
"code.gitea.io/gitea/modules/markup/markdown"
2021
"code.gitea.io/gitea/modules/references"
2122
"code.gitea.io/gitea/modules/structs"
@@ -1178,8 +1179,13 @@ func findCodeComments(e Engine, opts FindCommentsOptions, issue *Issue, currentU
11781179
return nil, err
11791180
}
11801181

1181-
comment.RenderedContent = string(markdown.Render([]byte(comment.Content), issue.Repo.Link(),
1182-
issue.Repo.ComposeMetas()))
1182+
var err error
1183+
if comment.RenderedContent, err = markdown.RenderString(&markup.RenderContext{
1184+
URLPrefix: issue.Repo.Link(),
1185+
Metas: issue.Repo.ComposeMetas(),
1186+
}, comment.Content); err != nil {
1187+
return nil, err
1188+
}
11831189
}
11841190
return comments[:n], nil
11851191
}

models/migrations/v156.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ func fixPublisherIDforTagReleases(x *xorm.Engine) error {
8888
repo = new(Repository)
8989
has, err := sess.ID(release.RepoID).Get(repo)
9090
if err != nil {
91+
log.Error("Error whilst loading repository[%d] for release[%d] with tag name %s", release.RepoID, release.ID, release.TagName)
9192
return err
9293
} else if !has {
9394
log.Warn("Release[%d] is orphaned and refers to non-existing repository %d", release.ID, release.RepoID)
@@ -99,28 +100,37 @@ func fixPublisherIDforTagReleases(x *xorm.Engine) error {
99100
// v120.go migration may not have been run correctly - we'll just replicate it here
100101
// because this appears to be a common-ish problem.
101102
if _, err := sess.Exec("UPDATE repository SET owner_name = (SELECT name FROM `user` WHERE `user`.id = repository.owner_id)"); err != nil {
103+
log.Error("Error whilst updating repository[%d] owner name", repo.ID)
102104
return err
103105
}
104106

105107
if _, err := sess.ID(release.RepoID).Get(repo); err != nil {
108+
log.Error("Error whilst loading repository[%d] for release[%d] with tag name %s", release.RepoID, release.ID, release.TagName)
106109
return err
107110
}
108111
}
109112
gitRepo, err = git.OpenRepository(repoPath(repo.OwnerName, repo.Name))
110113
if err != nil {
114+
log.Error("Error whilst opening git repo for %-v", repo)
111115
return err
112116
}
113117
}
114118

115119
commit, err := gitRepo.GetTagCommit(release.TagName)
116120
if err != nil {
121+
if git.IsErrNotExist(err) {
122+
log.Warn("Unable to find commit %s for Tag: %s in %-v. Cannot update publisher ID.", err.(*git.ErrNotExist).ID, release.TagName, repo)
123+
continue
124+
}
125+
log.Error("Error whilst getting commit for Tag: %s in %-v.", release.TagName, repo)
117126
return fmt.Errorf("GetTagCommit: %v", err)
118127
}
119128

120129
if user == nil || !strings.EqualFold(user.Email, commit.Author.Email) {
121130
user = new(User)
122131
_, err = sess.Where("email=?", commit.Author.Email).Get(user)
123132
if err != nil {
133+
log.Error("Error whilst getting commit author by email: %s for Tag: %s in %-v.", commit.Author.Email, release.TagName, repo)
124134
return err
125135
}
126136

@@ -133,6 +143,7 @@ func fixPublisherIDforTagReleases(x *xorm.Engine) error {
133143

134144
release.PublisherID = user.ID
135145
if _, err := sess.ID(release.ID).Cols("publisher_id").Update(release); err != nil {
146+
log.Error("Error whilst updating publisher[%d] for release[%d] with tag name %s", release.PublisherID, release.ID, release.TagName)
136147
return err
137148
}
138149
}

models/repo.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -863,7 +863,10 @@ func (repo *Repository) getUsersWithAccessMode(e Engine, mode AccessMode) (_ []*
863863

864864
// DescriptionHTML does special handles to description and return HTML string.
865865
func (repo *Repository) DescriptionHTML() template.HTML {
866-
desc, err := markup.RenderDescriptionHTML([]byte(repo.Description), repo.HTMLURL(), repo.ComposeMetas())
866+
desc, err := markup.RenderDescriptionHTML(&markup.RenderContext{
867+
URLPrefix: repo.HTMLURL(),
868+
Metas: repo.ComposeMetas(),
869+
}, repo.Description)
867870
if err != nil {
868871
log.Error("Failed to render description for %s (ID: %d): %v", repo.Name, repo.ID, err)
869872
return template.HTML(markup.Sanitize(repo.Description))

models/repo_generate.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,14 @@
55
package models
66

77
import (
8+
"bufio"
9+
"bytes"
810
"strconv"
911
"strings"
1012

1113
"code.gitea.io/gitea/modules/git"
1214
"code.gitea.io/gitea/modules/log"
1315
"code.gitea.io/gitea/modules/storage"
14-
"code.gitea.io/gitea/modules/util"
1516

1617
"github.com/gobwas/glob"
1718
)
@@ -49,9 +50,9 @@ func (gt GiteaTemplate) Globs() []glob.Glob {
4950
}
5051

5152
gt.globs = make([]glob.Glob, 0)
52-
lines := strings.Split(string(util.NormalizeEOL(gt.Content)), "\n")
53-
for _, line := range lines {
54-
line = strings.TrimSpace(line)
53+
scanner := bufio.NewScanner(bytes.NewReader(gt.Content))
54+
for scanner.Scan() {
55+
line := strings.TrimSpace(scanner.Text())
5556
if line == "" || strings.HasPrefix(line, "#") {
5657
continue
5758
}

models/user_avatar.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,14 +82,19 @@ func (u *User) RealSizedAvatarLink(size int) string {
8282
if u.Avatar == "" {
8383
return DefaultAvatarLink()
8484
}
85+
if size > 0 {
86+
return setting.AppSubURL + "/avatars/" + u.Avatar + "?size=" + strconv.Itoa(size)
87+
}
8588
return setting.AppSubURL + "/avatars/" + u.Avatar
8689
case setting.DisableGravatar, setting.OfflineMode:
8790
if u.Avatar == "" {
8891
if err := u.GenerateRandomAvatar(); err != nil {
8992
log.Error("GenerateRandomAvatar: %v", err)
9093
}
9194
}
92-
95+
if size > 0 {
96+
return setting.AppSubURL + "/avatars/" + u.Avatar + "?size=" + strconv.Itoa(size)
97+
}
9398
return setting.AppSubURL + "/avatars/" + u.Avatar
9499
}
95100
return SizedAvatarLink(u.AvatarEmail, size)

modules/charset/charset.go

Lines changed: 31 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ package charset
77
import (
88
"bytes"
99
"fmt"
10+
"io"
11+
"io/ioutil"
1012
"strings"
1113
"unicode/utf8"
1214

@@ -21,6 +23,33 @@ import (
2123
// UTF8BOM is the utf-8 byte-order marker
2224
var UTF8BOM = []byte{'\xef', '\xbb', '\xbf'}
2325

26+
// ToUTF8WithFallbackReader detects the encoding of content and coverts to UTF-8 reader if possible
27+
func ToUTF8WithFallbackReader(rd io.Reader) io.Reader {
28+
var buf = make([]byte, 2048)
29+
n, err := rd.Read(buf)
30+
if err != nil {
31+
return rd
32+
}
33+
34+
charsetLabel, err := DetectEncoding(buf[:n])
35+
if err != nil || charsetLabel == "UTF-8" {
36+
return io.MultiReader(bytes.NewReader(RemoveBOMIfPresent(buf[:n])), rd)
37+
}
38+
39+
encoding, _ := charset.Lookup(charsetLabel)
40+
if encoding == nil {
41+
return io.MultiReader(bytes.NewReader(buf[:n]), rd)
42+
}
43+
44+
return transform.NewReader(
45+
io.MultiReader(
46+
bytes.NewReader(RemoveBOMIfPresent(buf[:n])),
47+
rd,
48+
),
49+
encoding.NewDecoder(),
50+
)
51+
}
52+
2453
// ToUTF8WithErr converts content to UTF8 encoding
2554
func ToUTF8WithErr(content []byte) (string, error) {
2655
charsetLabel, err := DetectEncoding(content)
@@ -49,24 +78,8 @@ func ToUTF8WithErr(content []byte) (string, error) {
4978

5079
// ToUTF8WithFallback detects the encoding of content and coverts to UTF-8 if possible
5180
func ToUTF8WithFallback(content []byte) []byte {
52-
charsetLabel, err := DetectEncoding(content)
53-
if err != nil || charsetLabel == "UTF-8" {
54-
return RemoveBOMIfPresent(content)
55-
}
56-
57-
encoding, _ := charset.Lookup(charsetLabel)
58-
if encoding == nil {
59-
return content
60-
}
61-
62-
// If there is an error, we concatenate the nicely decoded part and the
63-
// original left over. This way we won't lose data.
64-
result, n, err := transform.Bytes(encoding.NewDecoder(), content)
65-
if err != nil {
66-
return append(result, content[n:]...)
67-
}
68-
69-
return RemoveBOMIfPresent(result)
81+
bs, _ := ioutil.ReadAll(ToUTF8WithFallbackReader(bytes.NewReader(content)))
82+
return bs
7083
}
7184

7285
// ToUTF8 converts content to UTF8 encoding and ignore error

modules/csv/csv.go

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ package csv
77
import (
88
"bytes"
99
"encoding/csv"
10+
stdcsv "encoding/csv"
1011
"errors"
12+
"io"
1113
"regexp"
1214
"strings"
1315

@@ -18,17 +20,31 @@ import (
1820
var quoteRegexp = regexp.MustCompile(`["'][\s\S]+?["']`)
1921

2022
// CreateReader creates a csv.Reader with the given delimiter.
21-
func CreateReader(rawBytes []byte, delimiter rune) *csv.Reader {
22-
rd := csv.NewReader(bytes.NewReader(rawBytes))
23+
func CreateReader(input io.Reader, delimiter rune) *stdcsv.Reader {
24+
rd := stdcsv.NewReader(input)
2325
rd.Comma = delimiter
2426
rd.TrimLeadingSpace = true
2527
return rd
2628
}
2729

2830
// CreateReaderAndGuessDelimiter tries to guess the field delimiter from the content and creates a csv.Reader.
29-
func CreateReaderAndGuessDelimiter(rawBytes []byte) *csv.Reader {
30-
delimiter := guessDelimiter(rawBytes)
31-
return CreateReader(rawBytes, delimiter)
31+
func CreateReaderAndGuessDelimiter(rd io.Reader) (*stdcsv.Reader, error) {
32+
var data = make([]byte, 1e4)
33+
size, err := rd.Read(data)
34+
if err != nil {
35+
return nil, err
36+
}
37+
38+
delimiter := guessDelimiter(data[:size])
39+
40+
var newInput io.Reader
41+
if size < 1e4 {
42+
newInput = bytes.NewReader(data[:size])
43+
} else {
44+
newInput = io.MultiReader(bytes.NewReader(data), rd)
45+
}
46+
47+
return CreateReader(newInput, delimiter), nil
3248
}
3349

3450
// guessDelimiter scores the input CSV data against delimiters, and returns the best match.

0 commit comments

Comments
 (0)