Skip to content

Commit f5c33da

Browse files
authored
Merge branch 'main' into various-small-fixes
2 parents e639975 + 6e7d28c commit f5c33da

25 files changed

+169
-19
lines changed

.gitattributes

+1
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@
55
/.eslintrc linguist-language=YAML
66
/.stylelintrc linguist-language=YAML
77
/web_src/fomantic/build/** linguist-generated
8+
Dockerfile.* linguist-language=Dockerfile

custom/conf/app.example.ini

+4
Original file line numberDiff line numberDiff line change
@@ -1587,6 +1587,10 @@ PATH =
15871587
;AVATAR_MAX_WIDTH = 4096
15881588
;AVATAR_MAX_HEIGHT = 3072
15891589
;;
1590+
;; The multiplication factor for rendered avatar images.
1591+
;; Larger values result in finer rendering on HiDPI devices.
1592+
;AVATAR_RENDERED_SIZE_FACTOR = 3
1593+
;;
15901594
;; Maximum allowed file size for uploaded avatars.
15911595
;; This is to limit the amount of RAM used when resizing the image.
15921596
;AVATAR_MAX_FILE_SIZE = 1048576

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

+1
Original file line numberDiff line numberDiff line change
@@ -710,6 +710,7 @@ Define allowed algorithms and their minimum key length (use -1 to disable a type
710710
- `AVATAR_MAX_WIDTH`: **4096**: Maximum avatar image width in pixels.
711711
- `AVATAR_MAX_HEIGHT`: **3072**: Maximum avatar image height in pixels.
712712
- `AVATAR_MAX_FILE_SIZE`: **1048576** (1Mb): Maximum avatar image file size in bytes.
713+
- `AVATAR_RENDERED_SIZE_FACTOR`: **3**: The multiplication factor for rendered avatar images. Larger values result in finer rendering on HiDPI devices.
713714

714715
- `REPOSITORY_AVATAR_STORAGE_TYPE`: **default**: Storage type defined in `[storage.xxx]`. Default is `default` which will read `[storage]` if no section `[storage]` will be a type `local`.
715716
- `REPOSITORY_AVATAR_UPLOAD_PATH`: **data/repo-avatars**: Path to store repository avatar image files.
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
3a810dbf6b96afaa8c5f69a8b6ec1dabfca7368b
1+
59e2c41e8f5140bb0182acebec17c8ad9831cc62

integrations/nonascii_branches_test.go

+36
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package integrations
66

77
import (
88
"net/http"
9+
"net/url"
910
"path"
1011
"testing"
1112

@@ -159,6 +160,41 @@ func TestNonasciiBranches(t *testing.T) {
159160
to: "tag/%D0%81/%E4%BA%BA",
160161
status: http.StatusOK,
161162
},
163+
{
164+
from: "Plus+Is+Not+Space/%25%252525mightnotplaywell",
165+
to: "branch/Plus+Is+Not+Space/%25%252525mightnotplaywell",
166+
status: http.StatusOK,
167+
},
168+
{
169+
from: "Plus+Is+Not+Space/%25253Fisnotaquestion%25253F",
170+
to: "branch/Plus+Is+Not+Space/%25253Fisnotaquestion%25253F",
171+
status: http.StatusOK,
172+
},
173+
{
174+
from: "Plus+Is+Not+Space/" + url.PathEscape("%3Fis?and#afile"),
175+
to: "branch/Plus+Is+Not+Space/" + url.PathEscape("%3Fis?and#afile"),
176+
status: http.StatusOK,
177+
},
178+
{
179+
from: "Plus+Is+Not+Space/10%25.md",
180+
to: "branch/Plus+Is+Not+Space/10%25.md",
181+
status: http.StatusOK,
182+
},
183+
{
184+
from: "Plus+Is+Not+Space/" + url.PathEscape("This+file%20has 1space"),
185+
to: "branch/Plus+Is+Not+Space/" + url.PathEscape("This+file%20has 1space"),
186+
status: http.StatusOK,
187+
},
188+
{
189+
from: "Plus+Is+Not+Space/" + url.PathEscape("This+file%2520has 2 spaces"),
190+
to: "branch/Plus+Is+Not+Space/" + url.PathEscape("This+file%2520has 2 spaces"),
191+
status: http.StatusOK,
192+
},
193+
{
194+
from: "Plus+Is+Not+Space/" + url.PathEscape("£15&$6.txt"),
195+
to: "branch/Plus+Is+Not+Space/" + url.PathEscape("£15&$6.txt"),
196+
status: http.StatusOK,
197+
},
162198
}
163199

164200
defer prepareTestEnv(t)()

models/avatars/avatar.go

-3
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,6 @@ import (
2121
// DefaultAvatarPixelSize is the default size in pixels of a rendered avatar
2222
const DefaultAvatarPixelSize = 28
2323

24-
// AvatarRenderedSizeFactor is the factor by which the default size is increased for finer rendering
25-
const AvatarRenderedSizeFactor = 4
26-
2724
// EmailHash represents a pre-generated hash map (mainly used by LibravatarURL, it queries email server's DNS records)
2825
type EmailHash struct {
2926
Hash string `xorm:"pk varchar(32)"`

models/repo/repo.go

+10
Original file line numberDiff line numberDiff line change
@@ -690,6 +690,16 @@ func getTemplateRepo(e db.Engine, repo *Repository) (*Repository, error) {
690690
return getRepositoryByID(e, repo.TemplateID)
691691
}
692692

693+
// TemplateRepo returns the repository, which is template of this repository
694+
func (repo *Repository) TemplateRepo() *Repository {
695+
repo, err := GetTemplateRepo(repo)
696+
if err != nil {
697+
log.Error("TemplateRepo: %v", err)
698+
return nil
699+
}
700+
return repo
701+
}
702+
693703
func countRepositories(userID int64, private bool) int64 {
694704
sess := db.GetEngine(db.DefaultContext).Where("id > 0")
695705

modules/context/context.go

+4
Original file line numberDiff line numberDiff line change
@@ -609,6 +609,10 @@ func Contexter() func(next http.Handler) http.Handler {
609609
var locale = middleware.Locale(resp, req)
610610
var startTime = time.Now()
611611
var link = setting.AppSubURL + strings.TrimSuffix(req.URL.EscapedPath(), "/")
612+
613+
chiCtx := chi.RouteContext(req.Context())
614+
chiCtx.RoutePath = req.URL.EscapedPath()
615+
612616
var ctx = Context{
613617
Resp: NewResponse(resp),
614618
Cache: mc.GetCache(),

modules/repository/commits.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
user_model "code.gitea.io/gitea/models/user"
1414
"code.gitea.io/gitea/modules/git"
1515
"code.gitea.io/gitea/modules/log"
16+
"code.gitea.io/gitea/modules/setting"
1617
api "code.gitea.io/gitea/modules/structs"
1718
)
1819

@@ -141,7 +142,7 @@ func (pc *PushCommits) AvatarLink(email string) string {
141142
return avatar
142143
}
143144

144-
size := avatars.DefaultAvatarPixelSize * avatars.AvatarRenderedSizeFactor
145+
size := avatars.DefaultAvatarPixelSize * setting.Avatar.RenderedSizeFactor
145146

146147
u, ok := pc.emailUsers[email]
147148
if !ok {

modules/repository/commits_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -124,13 +124,13 @@ func TestPushCommits_AvatarLink(t *testing.T) {
124124
}
125125

126126
assert.Equal(t,
127-
"https://secure.gravatar.com/avatar/ab53a2911ddf9b4817ac01ddcd3d975f?d=identicon&s=112",
127+
"https://secure.gravatar.com/avatar/ab53a2911ddf9b4817ac01ddcd3d975f?d=identicon&s=84",
128128
pushCommits.AvatarLink("user2@example.com"))
129129

130130
assert.Equal(t,
131131
"https://secure.gravatar.com/avatar/"+
132132
fmt.Sprintf("%x", md5.Sum([]byte("nonexistent@example.com")))+
133-
"?d=identicon&s=112",
133+
"?d=identicon&s=84",
134134
pushCommits.AvatarLink("nonexistent@example.com"))
135135
}
136136

modules/setting/picture.go

+9-6
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,15 @@ var (
1818
Avatar = struct {
1919
Storage
2020

21-
MaxWidth int
22-
MaxHeight int
23-
MaxFileSize int64
21+
MaxWidth int
22+
MaxHeight int
23+
MaxFileSize int64
24+
RenderedSizeFactor int
2425
}{
25-
MaxWidth: 4096,
26-
MaxHeight: 3072,
27-
MaxFileSize: 1048576,
26+
MaxWidth: 4096,
27+
MaxHeight: 3072,
28+
MaxFileSize: 1048576,
29+
RenderedSizeFactor: 3,
2830
}
2931

3032
GravatarSource string
@@ -55,6 +57,7 @@ func newPictureService() {
5557
Avatar.MaxWidth = sec.Key("AVATAR_MAX_WIDTH").MustInt(4096)
5658
Avatar.MaxHeight = sec.Key("AVATAR_MAX_HEIGHT").MustInt(3072)
5759
Avatar.MaxFileSize = sec.Key("AVATAR_MAX_FILE_SIZE").MustInt64(1048576)
60+
Avatar.RenderedSizeFactor = sec.Key("AVATAR_RENDERED_SIZE_FACTOR").MustInt(3)
5861

5962
switch source := sec.Key("GRAVATAR_SOURCE").MustString("gravatar"); source {
6063
case "duoshuo":

modules/templates/helper.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -557,17 +557,17 @@ func Avatar(item interface{}, others ...interface{}) template.HTML {
557557

558558
switch t := item.(type) {
559559
case *user_model.User:
560-
src := t.AvatarLinkWithSize(size * avatars.AvatarRenderedSizeFactor)
560+
src := t.AvatarLinkWithSize(size * setting.Avatar.RenderedSizeFactor)
561561
if src != "" {
562562
return AvatarHTML(src, size, class, t.DisplayName())
563563
}
564564
case *models.Collaborator:
565-
src := t.AvatarLinkWithSize(size * avatars.AvatarRenderedSizeFactor)
565+
src := t.AvatarLinkWithSize(size * setting.Avatar.RenderedSizeFactor)
566566
if src != "" {
567567
return AvatarHTML(src, size, class, t.DisplayName())
568568
}
569569
case *models.Organization:
570-
src := t.AsUser().AvatarLinkWithSize(size * avatars.AvatarRenderedSizeFactor)
570+
src := t.AsUser().AvatarLinkWithSize(size * setting.Avatar.RenderedSizeFactor)
571571
if src != "" {
572572
return AvatarHTML(src, size, class, t.AsUser().DisplayName())
573573
}
@@ -596,7 +596,7 @@ func RepoAvatar(repo *repo_model.Repository, others ...interface{}) template.HTM
596596
// AvatarByEmail renders avatars by email address. args: email, name, size (int), class (string)
597597
func AvatarByEmail(email string, name string, others ...interface{}) template.HTML {
598598
size, class := parseOthers(avatars.DefaultAvatarPixelSize, "ui avatar image", others...)
599-
src := avatars.GenerateEmailAvatarFastLink(email, size*avatars.AvatarRenderedSizeFactor)
599+
src := avatars.GenerateEmailAvatarFastLink(email, size*setting.Avatar.RenderedSizeFactor)
600600

601601
if src != "" {
602602
return AvatarHTML(src, size, class, name)

options/locale/locale_en-US.ini

+6
Original file line numberDiff line numberDiff line change
@@ -1726,6 +1726,12 @@ settings.pulls.default_delete_branch_after_merge = Delete pull request branch af
17261726
settings.projects_desc = Enable Repository Projects
17271727
settings.admin_settings = Administrator Settings
17281728
settings.admin_enable_health_check = Enable Repository Health Checks (git fsck)
1729+
settings.admin_code_indexer = Code Indexer
1730+
settings.admin_stats_indexer = Code Statistics Indexer
1731+
settings.admin_indexer_commit_sha = Last Indexed SHA
1732+
settings.admin_indexer_unindexed = Unindexed
1733+
settings.reindex_button = Add to Reindex Queue
1734+
settings.reindex_requested=Reindex Requested
17291735
settings.admin_enable_close_issues_via_commit_in_any_branch = Close an issue via a commit made in a non default branch
17301736
settings.danger_zone = Danger Zone
17311737
settings.new_owner_has_same_repo = The new owner already has a repository with same name. Please choose another name.

routers/web/repo/setting.go

+47
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ import (
2424
"code.gitea.io/gitea/modules/base"
2525
"code.gitea.io/gitea/modules/context"
2626
"code.gitea.io/gitea/modules/git"
27+
"code.gitea.io/gitea/modules/indexer/code"
28+
"code.gitea.io/gitea/modules/indexer/stats"
2729
"code.gitea.io/gitea/modules/lfs"
2830
"code.gitea.io/gitea/modules/log"
2931
"code.gitea.io/gitea/modules/repository"
@@ -67,6 +69,23 @@ func Settings(ctx *context.Context) {
6769
signing, _ := asymkey_service.SigningKey(ctx.Repo.Repository.RepoPath())
6870
ctx.Data["SigningKeyAvailable"] = len(signing) > 0
6971
ctx.Data["SigningSettings"] = setting.Repository.Signing
72+
ctx.Data["CodeIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
73+
if ctx.User.IsAdmin {
74+
if setting.Indexer.RepoIndexerEnabled {
75+
status, err := repo_model.GetIndexerStatus(ctx.Repo.Repository, repo_model.RepoIndexerTypeCode)
76+
if err != nil {
77+
ctx.ServerError("repo.indexer_status", err)
78+
return
79+
}
80+
ctx.Data["CodeIndexerStatus"] = status
81+
}
82+
status, err := repo_model.GetIndexerStatus(ctx.Repo.Repository, repo_model.RepoIndexerTypeStats)
83+
if err != nil {
84+
ctx.ServerError("repo.indexer_status", err)
85+
return
86+
}
87+
ctx.Data["StatsIndexerStatus"] = status
88+
}
7089
pushMirrors, err := repo_model.GetPushMirrorsByRepoID(ctx.Repo.Repository.ID)
7190
if err != nil {
7291
ctx.ServerError("GetPushMirrorsByRepoID", err)
@@ -515,6 +534,34 @@ func SettingsPost(ctx *context.Context) {
515534
ctx.Flash.Success(ctx.Tr("repo.settings.update_settings_success"))
516535
ctx.Redirect(ctx.Repo.RepoLink + "/settings")
517536

537+
case "admin_index":
538+
if !ctx.User.IsAdmin {
539+
ctx.Error(http.StatusForbidden)
540+
return
541+
}
542+
543+
switch form.RequestReindexType {
544+
case "stats":
545+
if err := stats.UpdateRepoIndexer(ctx.Repo.Repository); err != nil {
546+
ctx.ServerError("UpdateStatsRepondexer", err)
547+
return
548+
}
549+
case "code":
550+
if !setting.Indexer.RepoIndexerEnabled {
551+
ctx.Error(http.StatusForbidden)
552+
return
553+
}
554+
code.UpdateRepoIndexer(ctx.Repo.Repository)
555+
default:
556+
ctx.NotFound("", nil)
557+
return
558+
}
559+
560+
log.Trace("Repository reindex for %s requested: %s/%s", form.RequestReindexType, ctx.Repo.Owner.Name, repo.Name)
561+
562+
ctx.Flash.Success(ctx.Tr("repo.settings.reindex_requested"))
563+
ctx.Redirect(ctx.Repo.RepoLink + "/settings")
564+
518565
case "convert":
519566
if !ctx.Repo.IsOwner() {
520567
ctx.Error(http.StatusNotFound)

services/forms/repo_form.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,8 @@ type RepoSettingForm struct {
161161
TrustModel string
162162

163163
// Admin settings
164-
EnableHealthCheck bool
164+
EnableHealthCheck bool
165+
RequestReindexType string
165166
}
166167

167168
// Validate validates the fields

templates/repo/settings/options.tmpl

+40-1
Original file line numberDiff line numberDiff line change
@@ -558,11 +558,50 @@
558558
</div>
559559
</div>
560560

561-
<div class="ui divider"></div>
562561
<div class="field">
563562
<button class="ui green button">{{$.i18n.Tr "repo.settings.update_settings"}}</button>
564563
</div>
565564
</form>
565+
566+
<div class="ui divider"></div>
567+
<form class="ui form" method="post">
568+
{{.CsrfTokenHtml}}
569+
<input type="hidden" name="action" value="admin_index">
570+
{{if .CodeIndexerEnabled}}
571+
<h4 class="ui header">{{.i18n.Tr "repo.settings.admin_code_indexer"}}</h4>
572+
<div class="inline fields">
573+
<label>{{.i18n.Tr "repo.settings.admin_indexer_commit_sha"}}</label>
574+
<span class="field">
575+
{{if .CodeIndexerStatus}}
576+
<a rel="nofollow" class="ui sha label" href="{{.RepoLink}}/commit/{{.CodeIndexerStatus.CommitSha}}">
577+
<span class="shortsha">{{ShortSha .CodeIndexerStatus.CommitSha}}</span>
578+
</a>
579+
{{else}}
580+
<span>{{.i18n.Tr "repo.settings.admin_indexer_unindexed"}}</span>
581+
{{end}}
582+
</span>
583+
<div class="field">
584+
<button class="ui green button" name="request_reindex_type" value="code">{{$.i18n.Tr "repo.settings.reindex_button"}}</button>
585+
</div>
586+
</div>
587+
{{end}}
588+
<h4 class="ui header">{{.i18n.Tr "repo.settings.admin_stats_indexer"}}</h4>
589+
<div class="inline fields">
590+
<label>{{.i18n.Tr "repo.settings.admin_indexer_commit_sha"}}</label>
591+
<span class="field">
592+
{{if .StatsIndexerStatus}}
593+
<a rel="nofollow" class="ui sha label" href="{{.RepoLink}}/commit/{{.StatsIndexerStatus.CommitSha}}">
594+
<span class="shortsha">{{ShortSha .StatsIndexerStatus.CommitSha}}</span>
595+
</a>
596+
{{else}}
597+
<span>{{.i18n.Tr "repo.settings.admin_indexer_unindexed"}}</span>
598+
{{end}}
599+
</span>
600+
<div class="field">
601+
<button class="ui green button" name="request_reindex_type" value="stats">{{$.i18n.Tr "repo.settings.reindex_button"}}</button>
602+
</div>
603+
</div>
604+
</form>
566605
</div>
567606
{{end}}
568607

0 commit comments

Comments
 (0)