0
0
mirror of https://github.com/go-gitea/gitea.git synced 2026-05-16 12:37:25 +02:00

refactor handling of -1 from base to business logic and UI for sizelimit working

This commit is contained in:
DmitryFrolovTri 2026-01-21 09:44:52 +00:00
parent 7942523c3f
commit c16ad5643a
No known key found for this signature in database
GPG Key ID: 0FBA4D49377CDDC3
8 changed files with 64 additions and 48 deletions

View File

@ -93,21 +93,18 @@ func CreateTimeLimitCode[T time.Time | string](data string, minutes int, startTi
// FileSize calculates the file size and generate user-friendly string.
func FileSize(s int64) string {
if s == -1 {
return "-1"
}
return humanize.IBytes(uint64(s))
}
// Get FileSize bytes value from String.
// GetFileSize gets FileSize bytes value from String.
func GetFileSize(s string) (int64, error) {
s = strings.TrimSpace(s)
if s == "-1" {
return -1, nil
// default to bytes if no unit is provided
if _, err := strconv.ParseInt(s, 10, 64); err == nil {
s += " B"
}
v, err := humanize.ParseBytes(s)
iv := int64(v)
return iv, err
return int64(v), err
}
// StringsToInt64s converts a slice of string to a slice of int64.

View File

@ -6,6 +6,7 @@ package setting
import (
"os/exec"
"path/filepath"
"strconv"
"strings"
"code.gitea.io/gitea/modules/log"
@ -284,6 +285,32 @@ func UpdateGlobalRepositoryLimit(gitSizeMax, lfsSizeMax int64) {
Repository.LFSSizeMax = lfsSizeMax
}
// FormatRepositorySizeLimit formats a repository size limit for display.
// Returns "-1" for disabled limits (when sizeInBytes is -1),
// otherwise returns human-readable size using base.FileSize.
func FormatRepositorySizeLimit(sizeInBytes int64) string {
if sizeInBytes == -1 {
return "-1"
}
return humanize.IBytes(uint64(sizeInBytes))
}
// ParseRepositorySizeLimit parses a repository size limit string.
// Accepts "-1" to disable the limit, otherwise parses as a byte size.
// Returns the size in bytes or an error if parsing fails.
func ParseRepositorySizeLimit(s string) (int64, error) {
s = strings.TrimSpace(s)
if s == "-1" {
return -1, nil
}
// default to bytes if no unit is provided
if _, err := strconv.ParseInt(s, 10, 64); err == nil {
s += " B"
}
v, err := humanize.ParseBytes(s)
return int64(v), err
}
func parseSize(sec ConfigSection, key string, def int64) int64 {
v := sec.Key(key).MustString("")
if v == "" {

View File

@ -3067,6 +3067,7 @@
"repos.git_size_max_helper": "Maximum Git size allowed for a single repository. Set to -1 for unlimited.",
"repos.lfs_size_max": "Max LFS Size (Global)",
"repos.lfs_size_max_helper": "Maximum LFS size allowed for a single repository. Set to -1 for unlimited.",
"repos.update_settings": "Update Settings",
"repos.update_success": "Global repository limits have been updated.",
"packages.package_manage_panel": "Package Management",
"packages.total_size": "Total Size: %s",

View File

@ -835,8 +835,8 @@ func HookPreReceive(ctx *gitea_context.PrivateContext) {
repo.OwnerName, repo.Name,
base.FileSize(predictedGitAfter), base.FileSize(currentGit), base.FileSize(gitDelta),
base.FileSize(predictedLFSAfter), base.FileSize(currentLFS), base.FileSize(lfsDelta),
base.FileSize(setting.Repository.GitSizeMax),
base.FileSize(setting.Repository.LFSSizeMax),
setting.FormatRepositorySizeLimit(setting.Repository.GitSizeMax),
setting.FormatRepositorySizeLimit(setting.Repository.LFSSizeMax),
)
}

View File

@ -11,7 +11,6 @@ import (
"code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/templates"
@ -33,8 +32,11 @@ func Repos(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("admin.repositories")
ctx.Data["PageIsAdminRepositories"] = true
ctx.Data["GitSizeMax"] = base.FileSize(setting.Repository.GitSizeMax)
ctx.Data["LFSSizeMax"] = base.FileSize(setting.Repository.LFSSizeMax)
gitSizeStr := setting.FormatRepositorySizeLimit(setting.Repository.GitSizeMax)
lfsSizeStr := setting.FormatRepositorySizeLimit(setting.Repository.LFSSizeMax)
log.Trace("Repos: GitSizeMax=%d -> %s, LFSSizeMax=%d -> %s", setting.Repository.GitSizeMax, gitSizeStr, setting.Repository.LFSSizeMax, lfsSizeStr)
ctx.Data["GitSizeMax"] = gitSizeStr
ctx.Data["LFSSizeMax"] = lfsSizeStr
explore.RenderRepoSearch(ctx, &explore.RepoSearchOptions{
Private: true,
@ -52,7 +54,7 @@ func UpdateRepoPost(ctx *context.Context) {
ctx.Data["GitSizeMax"] = form.GitSizeMax
ctx.Data["LFSSizeMax"] = form.LFSSizeMax
gitSizeMax, err := base.GetFileSize(form.GitSizeMax)
gitSizeMax, err := setting.ParseRepositorySizeLimit(form.GitSizeMax)
if err != nil {
ctx.Data["Err_Git_Size_Max"] = form.GitSizeMax
explore.RenderRepoSearch(ctx, &explore.RepoSearchOptions{
@ -64,7 +66,7 @@ func UpdateRepoPost(ctx *context.Context) {
return
}
lfsSizeMax, err := base.GetFileSize(form.LFSSizeMax)
lfsSizeMax, err := setting.ParseRepositorySizeLimit(form.LFSSizeMax)
if err != nil {
ctx.Data["Err_LFS_Size_Max"] = form.LFSSizeMax
explore.RenderRepoSearch(ctx, &explore.RepoSearchOptions{
@ -77,6 +79,7 @@ func UpdateRepoPost(ctx *context.Context) {
}
setting.UpdateGlobalRepositoryLimit(gitSizeMax, lfsSizeMax)
log.Trace("UpdateRepoPost: After update, setting.Repository.GitSizeMax=%d, LFSSizeMax=%d", setting.Repository.GitSizeMax, setting.Repository.LFSSizeMax)
ctx.Flash.Success(ctx.Tr("admin.repos.update_success"))
ctx.Redirect(setting.AppSubURL + "/-/admin/repos")

View File

@ -46,8 +46,8 @@ type CreateRepoForm struct {
}
type UpdateGlobalRepoFrom struct {
GitSizeMax string
LFSSizeMax string
GitSizeMax string `form:"GitSizeMax"`
LFSSizeMax string `form:"LFSSizeMax"`
}
// Validate validates the fields

View File

@ -253,8 +253,8 @@ func BatchHandler(ctx *context.Context) {
repository.ID,
base.FileSize(repository.GitSize),
base.FileSize(repository.LFSSize),
base.FileSize(repository.GetActualSizeLimit()),
base.FileSize(repository.GetActualLFSSizeLimit()),
setting.FormatRepositorySizeLimit(repository.GetActualSizeLimit()),
setting.FormatRepositorySizeLimit(repository.GetActualLFSSizeLimit()),
)
// Check LFS size limits for upload operations
@ -280,11 +280,11 @@ func BatchHandler(ctx *context.Context) {
if predictedLFS > repository.GetActualLFSSizeLimit() && predictedLFS > repository.LFSSize {
traceBatchDecision(rc, br.Operation,
"req=%s DECISION=FORBID reason=LFS_LIMIT predictedLFS=%s limit=%s (NewObjects=%d ObjectsPresentInStore=%d MetaPresent=%d StoreExists=%d Invalid=%d)",
reqID, base.FileSize(predictedLFS), base.FileSize(repository.GetActualLFSSizeLimit()),
reqID, base.FileSize(predictedLFS), setting.FormatRepositorySizeLimit(repository.GetActualLFSSizeLimit()),
)
writeStatusMessage(ctx, http.StatusForbidden,
fmt.Sprintf("LFS size %s would exceed limit %s",
base.FileSize(predictedLFS), base.FileSize(repository.GetActualLFSSizeLimit())))
base.FileSize(predictedLFS), setting.FormatRepositorySizeLimit(repository.GetActualLFSSizeLimit())))
return
}

View File

@ -2,12 +2,22 @@
<div class="admin-setting-content">
<h4 class="ui top attached header">
{{ctx.Locale.Tr "admin.repositories"}}
<div class="ui right">
<span class="ui small label">{{ctx.Locale.Tr "repo.repo_size"}} Max: {{.GitSizeMax}}</span>
<span class="ui small label">{{ctx.Locale.Tr "repo.lfs_size"}} Max: {{.LFSSizeMax}}</span>
</div>
</h4>
<h4 class="ui attached header">
<div class="ui attached segment">
<form class="ui form" action="{{.Link}}" method="post">
{{.CsrfTokenHtml}}
<div class="field {{if .Err_Git_Size_Max}}error{{end}}">
<label>{{ctx.Locale.Tr "admin.repos.git_size_max"}}</label>
<input name="GitSizeMax" value="{{if .Err_Git_Size_Max}}{{.Err_Git_Size_Max}}{{else}}{{.GitSizeMax}}{{end}}" data-tooltip-content="{{ctx.Locale.Tr "admin.repos.git_size_max_helper"}}">
</div>
<div class="field {{if .Err_LFS_Size_Max}}error{{end}}">
<label>{{ctx.Locale.Tr "admin.repos.lfs_size_max"}}</label>
<input name="LFSSizeMax" value="{{if .Err_LFS_Size_Max}}{{.Err_LFS_Size_Max}}{{else}}{{.LFSSizeMax}}{{end}}" data-tooltip-content="{{ctx.Locale.Tr "admin.repos.lfs_size_max_helper"}}">
</div>
<button class="ui green button">{{ctx.Locale.Tr "admin.repos.update_settings"}}</button>
</form>
</div>
<h4 class="ui top attached header">
{{ctx.Locale.Tr "admin.repos.repo_manage_panel"}} ({{ctx.Locale.Tr "admin.total" .Total}})
<div class="ui right">
<a class="ui primary tiny button" href="{{AppSubUrl}}/-/admin/repos/unadopted">{{ctx.Locale.Tr "admin.repos.unadopted"}}</a>
@ -108,28 +118,6 @@
{{template "base/paginate" .}}
</div>
<div class="ui container">
<h4 class="ui top attached header">
{{ctx.Locale.Tr "admin.repos.settings"}}
</h4>
<div class="ui attached segment">
<form class="ui form" action="{{$.Link}}" method="post">
{{$.CsrfTokenHtml}}
<div class="field {{if .Err_Git_Size_Max}}error{{end}}">
<label>{{ctx.Locale.Tr "admin.repos.git_size_max"}}</label>
<input name="GitSizeMax" value="{{if .Err_Git_Size_Max}}{{.Err_Git_Size_Max}}{{else}}{{.GitSizeMax}}{{end}}">
<p class="help">{{ctx.Locale.Tr "admin.repos.git_size_max_helper"}}</p>
</div>
<div class="field {{if .Err_LFS_Size_Max}}error{{end}}">
<label>{{ctx.Locale.Tr "admin.repos.lfs_size_max"}}</label>
<input name="LFSSizeMax" value="{{if .Err_LFS_Size_Max}}{{.Err_LFS_Size_Max}}{{else}}{{.LFSSizeMax}}{{end}}">
<p class="help">{{ctx.Locale.Tr "admin.repos.lfs_size_max_helper"}}</p>
</div>
<button class="ui green button">{{ctx.Locale.Tr "settings.update_settings"}}</button>
</form>
</div>
</div>
<form class="ui small modal form-fetch-action" id="admin-repo-delete-modal" method="post">
{{.CsrfTokenHtml}}
<div class="header">{{svg "octicon-trash"}} {{ctx.Locale.Tr "repo.settings.delete"}}</div>