diff --git a/build/code-batch-process.go b/build/code-batch-process.go index 8556c27ad7379..b3ee3994207dc 100644 --- a/build/code-batch-process.go +++ b/build/code-batch-process.go @@ -25,7 +25,7 @@ import ( var optionLogVerbose bool -func logVerbose(msg string, args ...interface{}) { +func logVerbose(msg string, args ...any) { if optionLogVerbose { log.Printf(msg, args...) } diff --git a/cmd/cert.go b/cmd/cert.go index 816659023ca93..897c10c8993b2 100644 --- a/cmd/cert.go +++ b/cmd/cert.go @@ -63,7 +63,7 @@ Outputs to 'cert.pem' and 'key.pem' and will overwrite existing files.`, }, } -func publicKey(priv interface{}) interface{} { +func publicKey(priv any) any { switch k := priv.(type) { case *rsa.PrivateKey: return &k.PublicKey @@ -74,7 +74,7 @@ func publicKey(priv interface{}) interface{} { } } -func pemBlockForKey(priv interface{}) *pem.Block { +func pemBlockForKey(priv any) *pem.Block { switch k := priv.(type) { case *rsa.PrivateKey: return &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(k)} @@ -94,7 +94,7 @@ func runCert(c *cli.Context) error { return err } - var priv interface{} + var priv any var err error switch c.String("ecdsa-curve") { case "": diff --git a/cmd/dump.go b/cmd/dump.go index 0b7c1d32c5b0a..b1aed8aef46db 100644 --- a/cmd/dump.go +++ b/cmd/dump.go @@ -161,7 +161,7 @@ It can be used for backup and capture Gitea server image to send to maintainer`, }, } -func fatal(format string, args ...interface{}) { +func fatal(format string, args ...any) { fmt.Fprintf(os.Stderr, format+"\n", args...) log.Fatal(format, args...) } @@ -236,7 +236,7 @@ func runDump(ctx *cli.Context) error { return err } - var iface interface{} + var iface any if fileName == "-" { iface, err = archiver.ByExtension(fmt.Sprintf(".%s", outType)) } else { diff --git a/cmd/manager_logging.go b/cmd/manager_logging.go index dd85cc26d8087..70d1beb26d0f3 100644 --- a/cmd/manager_logging.go +++ b/cmd/manager_logging.go @@ -178,7 +178,7 @@ func runAddConnLogger(c *cli.Context) error { defer cancel() setup(ctx, c.Bool("debug")) - vals := map[string]interface{}{} + vals := map[string]any{} mode := "conn" vals["net"] = "tcp" if c.IsSet("protocol") { @@ -208,7 +208,7 @@ func runAddFileLogger(c *cli.Context) error { defer cancel() setup(ctx, c.Bool("debug")) - vals := map[string]interface{}{} + vals := map[string]any{} mode := "file" if c.IsSet("filename") { vals["filename"] = c.String("filename") @@ -236,7 +236,7 @@ func runAddFileLogger(c *cli.Context) error { return commonAddLogger(c, mode, vals) } -func commonAddLogger(c *cli.Context, mode string, vals map[string]interface{}) error { +func commonAddLogger(c *cli.Context, mode string, vals map[string]any) error { if len(c.String("level")) > 0 { vals["level"] = log.LevelFromString(c.String("level")).String() } diff --git a/cmd/serv.go b/cmd/serv.go index 79052e58a8f56..484e3bf4048a8 100644 --- a/cmd/serv.go +++ b/cmd/serv.go @@ -95,7 +95,7 @@ var ( // fail prints message to stdout, it's mainly used for git serv and git hook commands. // The output will be passed to git client and shown to user. -func fail(ctx context.Context, userMessage, logMsgFmt string, args ...interface{}) error { +func fail(ctx context.Context, userMessage, logMsgFmt string, args ...any) error { if userMessage == "" { userMessage = "Internal Server Error (no specific error)" } diff --git a/models/admin/task.go b/models/admin/task.go index fc40b13d0265a..8aa397ad351ad 100644 --- a/models/admin/task.go +++ b/models/admin/task.go @@ -44,7 +44,7 @@ func init() { // TranslatableMessage represents JSON struct that can be translated with a Locale type TranslatableMessage struct { Format string - Args []interface{} `json:"omitempty"` + Args []any `json:"omitempty"` } // LoadRepo loads repository of the task diff --git a/models/asymkey/ssh_key_authorized_keys.go b/models/asymkey/ssh_key_authorized_keys.go index e138182d6864e..77803d6709ec3 100644 --- a/models/asymkey/ssh_key_authorized_keys.go +++ b/models/asymkey/ssh_key_authorized_keys.go @@ -47,7 +47,7 @@ var sshOpLocker sync.Mutex // AuthorizedStringForKey creates the authorized keys string appropriate for the provided key func AuthorizedStringForKey(key *PublicKey) string { sb := &strings.Builder{} - _ = setting.SSH.AuthorizedKeysCommandTemplateTemplate.Execute(sb, map[string]interface{}{ + _ = setting.SSH.AuthorizedKeysCommandTemplateTemplate.Execute(sb, map[string]any{ "AppPath": util.ShellEscape(setting.AppPath), "AppWorkPath": util.ShellEscape(setting.AppWorkPath), "CustomConf": util.ShellEscape(setting.CustomConf), @@ -175,7 +175,7 @@ func RewriteAllPublicKeys() error { // RegeneratePublicKeys regenerates the authorized_keys file func RegeneratePublicKeys(ctx context.Context, t io.StringWriter) error { - if err := db.GetEngine(ctx).Where("type != ?", KeyTypePrincipal).Iterate(new(PublicKey), func(idx int, bean interface{}) (err error) { + if err := db.GetEngine(ctx).Where("type != ?", KeyTypePrincipal).Iterate(new(PublicKey), func(idx int, bean any) (err error) { _, err = t.WriteString((bean.(*PublicKey)).AuthorizedString()) return err }); err != nil { diff --git a/models/asymkey/ssh_key_authorized_principals.go b/models/asymkey/ssh_key_authorized_principals.go index 092839611f91c..592196c255ae7 100644 --- a/models/asymkey/ssh_key_authorized_principals.go +++ b/models/asymkey/ssh_key_authorized_principals.go @@ -97,7 +97,7 @@ func RewriteAllPrincipalKeys(ctx context.Context) error { } func regeneratePrincipalKeys(ctx context.Context, t io.StringWriter) error { - if err := db.GetEngine(ctx).Where("type = ?", KeyTypePrincipal).Iterate(new(PublicKey), func(idx int, bean interface{}) (err error) { + if err := db.GetEngine(ctx).Where("type = ?", KeyTypePrincipal).Iterate(new(PublicKey), func(idx int, bean any) (err error) { _, err = t.WriteString((bean.(*PublicKey)).AuthorizedString()) return err }); err != nil { diff --git a/models/db/context.go b/models/db/context.go index 59be1e138914a..351aea8faf908 100644 --- a/models/db/context.go +++ b/models/db/context.go @@ -52,7 +52,7 @@ func (ctx *Context) Engine() Engine { } // Value shadows Value for context.Context but allows us to get ourselves and an Engined object -func (ctx *Context) Value(key interface{}) interface{} { +func (ctx *Context) Value(key any) any { if key == enginedContextKey { return ctx } @@ -163,28 +163,28 @@ func txWithNoCheck(parentCtx context.Context, f func(ctx context.Context) error) } // Insert inserts records into database -func Insert(ctx context.Context, beans ...interface{}) error { +func Insert(ctx context.Context, beans ...any) error { _, err := GetEngine(ctx).Insert(beans...) return err } // Exec executes a sql with args -func Exec(ctx context.Context, sqlAndArgs ...interface{}) (sql.Result, error) { +func Exec(ctx context.Context, sqlAndArgs ...any) (sql.Result, error) { return GetEngine(ctx).Exec(sqlAndArgs...) } // GetByBean filled empty fields of the bean according non-empty fields to query in database. -func GetByBean(ctx context.Context, bean interface{}) (bool, error) { +func GetByBean(ctx context.Context, bean any) (bool, error) { return GetEngine(ctx).Get(bean) } // DeleteByBean deletes all records according non-empty fields of the bean as conditions. -func DeleteByBean(ctx context.Context, bean interface{}) (int64, error) { +func DeleteByBean(ctx context.Context, bean any) (int64, error) { return GetEngine(ctx).Delete(bean) } // DeleteByID deletes the given bean with the given ID -func DeleteByID(ctx context.Context, id int64, bean interface{}) (int64, error) { +func DeleteByID(ctx context.Context, id int64, bean any) (int64, error) { return GetEngine(ctx).ID(id).NoAutoTime().Delete(bean) } @@ -203,13 +203,13 @@ func FindIDs(ctx context.Context, tableName, idCol string, cond builder.Cond) ([ // DecrByIDs decreases the given column for entities of the "bean" type with one of the given ids by one // Timestamps of the entities won't be updated -func DecrByIDs(ctx context.Context, ids []int64, decrCol string, bean interface{}) error { +func DecrByIDs(ctx context.Context, ids []int64, decrCol string, bean any) error { _, err := GetEngine(ctx).Decr(decrCol).In("id", ids).NoAutoCondition().NoAutoTime().Update(bean) return err } // DeleteBeans deletes all given beans, beans must contain delete conditions. -func DeleteBeans(ctx context.Context, beans ...interface{}) (err error) { +func DeleteBeans(ctx context.Context, beans ...any) (err error) { e := GetEngine(ctx) for i := range beans { if _, err = e.Delete(beans[i]); err != nil { @@ -220,7 +220,7 @@ func DeleteBeans(ctx context.Context, beans ...interface{}) (err error) { } // TruncateBeans deletes all given beans, beans may contain delete conditions. -func TruncateBeans(ctx context.Context, beans ...interface{}) (err error) { +func TruncateBeans(ctx context.Context, beans ...any) (err error) { e := GetEngine(ctx) for i := range beans { if _, err = e.Truncate(beans[i]); err != nil { @@ -231,12 +231,12 @@ func TruncateBeans(ctx context.Context, beans ...interface{}) (err error) { } // CountByBean counts the number of database records according non-empty fields of the bean as conditions. -func CountByBean(ctx context.Context, bean interface{}) (int64, error) { +func CountByBean(ctx context.Context, bean any) (int64, error) { return GetEngine(ctx).Count(bean) } // TableName returns the table name according a bean object -func TableName(bean interface{}) string { +func TableName(bean any) string { return x.TableName(bean) } diff --git a/models/db/engine.go b/models/db/engine.go index 3eb16f8042ddc..07e4d00270bf2 100755 --- a/models/db/engine.go +++ b/models/db/engine.go @@ -25,7 +25,7 @@ import ( var ( x *xorm.Engine - tables []interface{} + tables []any initFuncs []func() error // HasEngine specifies if we have a xorm.Engine @@ -34,41 +34,41 @@ var ( // Engine represents a xorm engine or session. type Engine interface { - Table(tableNameOrBean interface{}) *xorm.Session - Count(...interface{}) (int64, error) - Decr(column string, arg ...interface{}) *xorm.Session - Delete(...interface{}) (int64, error) - Truncate(...interface{}) (int64, error) - Exec(...interface{}) (sql.Result, error) - Find(interface{}, ...interface{}) error - Get(beans ...interface{}) (bool, error) - ID(interface{}) *xorm.Session - In(string, ...interface{}) *xorm.Session - Incr(column string, arg ...interface{}) *xorm.Session - Insert(...interface{}) (int64, error) - Iterate(interface{}, xorm.IterFunc) error - Join(joinOperator string, tablename, condition interface{}, args ...interface{}) *xorm.Session - SQL(interface{}, ...interface{}) *xorm.Session - Where(interface{}, ...interface{}) *xorm.Session + Table(tableNameOrBean any) *xorm.Session + Count(...any) (int64, error) + Decr(column string, arg ...any) *xorm.Session + Delete(...any) (int64, error) + Truncate(...any) (int64, error) + Exec(...any) (sql.Result, error) + Find(any, ...any) error + Get(beans ...any) (bool, error) + ID(any) *xorm.Session + In(string, ...any) *xorm.Session + Incr(column string, arg ...any) *xorm.Session + Insert(...any) (int64, error) + Iterate(any, xorm.IterFunc) error + Join(joinOperator string, tablename, condition any, args ...any) *xorm.Session + SQL(any, ...any) *xorm.Session + Where(any, ...any) *xorm.Session Asc(colNames ...string) *xorm.Session Desc(colNames ...string) *xorm.Session Limit(limit int, start ...int) *xorm.Session NoAutoTime() *xorm.Session - SumInt(bean interface{}, columnName string) (res int64, err error) - Sync2(...interface{}) error + SumInt(bean any, columnName string) (res int64, err error) + Sync2(...any) error Select(string) *xorm.Session - NotIn(string, ...interface{}) *xorm.Session - OrderBy(interface{}, ...interface{}) *xorm.Session - Exist(...interface{}) (bool, error) + NotIn(string, ...any) *xorm.Session + OrderBy(any, ...any) *xorm.Session + Exist(...any) (bool, error) Distinct(...string) *xorm.Session - Query(...interface{}) ([]map[string][]byte, error) + Query(...any) ([]map[string][]byte, error) Cols(...string) *xorm.Session Context(ctx context.Context) *xorm.Session Ping() error } // TableInfo returns table's information via an object -func TableInfo(v interface{}) (*schemas.Table, error) { +func TableInfo(v any) (*schemas.Table, error) { return x.TableInfo(v) } @@ -78,7 +78,7 @@ func DumpTables(tables []*schemas.Table, w io.Writer, tp ...schemas.DBType) erro } // RegisterModel registers model, if initfunc provided, it will be invoked after data model sync -func RegisterModel(bean interface{}, initFunc ...func() error) { +func RegisterModel(bean any, initFunc ...func() error) { tables = append(tables, bean) if len(initFuncs) > 0 && initFunc[0] != nil { initFuncs = append(initFuncs, initFunc[0]) @@ -209,14 +209,14 @@ func InitEngineWithMigration(ctx context.Context, migrateFunc func(*xorm.Engine) } // NamesToBean return a list of beans or an error -func NamesToBean(names ...string) ([]interface{}, error) { - beans := []interface{}{} +func NamesToBean(names ...string) ([]any, error) { + beans := []any{} if len(names) == 0 { beans = append(beans, tables...) return beans, nil } // Need to map provided names to beans... - beanMap := make(map[string]interface{}) + beanMap := make(map[string]any) for _, bean := range tables { beanMap[strings.ToLower(reflect.Indirect(reflect.ValueOf(bean)).Type().Name())] = bean @@ -224,7 +224,7 @@ func NamesToBean(names ...string) ([]interface{}, error) { beanMap[strings.ToLower(x.TableName(bean, true))] = bean } - gotBean := make(map[interface{}]bool) + gotBean := make(map[any]bool) for _, name := range names { bean, ok := beanMap[strings.ToLower(strings.TrimSpace(name))] if !ok { @@ -266,7 +266,7 @@ func DumpDatabase(filePath, dbType string) error { } // MaxBatchInsertSize returns the table's max batch insert size -func MaxBatchInsertSize(bean interface{}) int { +func MaxBatchInsertSize(bean any) int { t, err := x.TableInfo(bean) if err != nil { return 50 @@ -286,7 +286,7 @@ func DeleteAllRecords(tableName string) error { } // GetMaxID will return max id of the table -func GetMaxID(beanOrTableName interface{}) (maxID int64, err error) { +func GetMaxID(beanOrTableName any) (maxID int64, err error) { _, err = x.Select("MAX(id)").Table(beanOrTableName).Get(&maxID) return maxID, err } diff --git a/models/db/error.go b/models/db/error.go index edc8e80a9c605..665e970e17c1e 100644 --- a/models/db/error.go +++ b/models/db/error.go @@ -25,7 +25,7 @@ func (err ErrCancelled) Error() string { } // ErrCancelledf returns an ErrCancelled for the provided format and args -func ErrCancelledf(format string, args ...interface{}) error { +func ErrCancelledf(format string, args ...any) error { return ErrCancelled{ fmt.Sprintf(format, args...), } diff --git a/models/db/log.go b/models/db/log.go index dd95f64ca80b9..307788ea2e49f 100644 --- a/models/db/log.go +++ b/models/db/log.go @@ -28,47 +28,47 @@ func NewXORMLogger(showSQL bool) xormlog.Logger { const stackLevel = 8 // Log a message with defined skip and at logging level -func (l *XORMLogBridge) Log(skip int, level log.Level, format string, v ...interface{}) { +func (l *XORMLogBridge) Log(skip int, level log.Level, format string, v ...any) { l.logger.Log(skip+1, level, format, v...) } // Debug show debug log -func (l *XORMLogBridge) Debug(v ...interface{}) { +func (l *XORMLogBridge) Debug(v ...any) { l.Log(stackLevel, log.DEBUG, "%s", fmt.Sprint(v...)) } // Debugf show debug log -func (l *XORMLogBridge) Debugf(format string, v ...interface{}) { +func (l *XORMLogBridge) Debugf(format string, v ...any) { l.Log(stackLevel, log.DEBUG, format, v...) } // Error show error log -func (l *XORMLogBridge) Error(v ...interface{}) { +func (l *XORMLogBridge) Error(v ...any) { l.Log(stackLevel, log.ERROR, "%s", fmt.Sprint(v...)) } // Errorf show error log -func (l *XORMLogBridge) Errorf(format string, v ...interface{}) { +func (l *XORMLogBridge) Errorf(format string, v ...any) { l.Log(stackLevel, log.ERROR, format, v...) } // Info show information level log -func (l *XORMLogBridge) Info(v ...interface{}) { +func (l *XORMLogBridge) Info(v ...any) { l.Log(stackLevel, log.INFO, "%s", fmt.Sprint(v...)) } // Infof show information level log -func (l *XORMLogBridge) Infof(format string, v ...interface{}) { +func (l *XORMLogBridge) Infof(format string, v ...any) { l.Log(stackLevel, log.INFO, format, v...) } // Warn show warning log -func (l *XORMLogBridge) Warn(v ...interface{}) { +func (l *XORMLogBridge) Warn(v ...any) { l.Log(stackLevel, log.WARN, "%s", fmt.Sprint(v...)) } // Warnf show warnning log -func (l *XORMLogBridge) Warnf(format string, v ...interface{}) { +func (l *XORMLogBridge) Warnf(format string, v ...any) { l.Log(stackLevel, log.WARN, format, v...) } diff --git a/models/git/branch.go b/models/git/branch.go index 88ed858b1939f..5e995449586d6 100644 --- a/models/git/branch.go +++ b/models/git/branch.go @@ -355,7 +355,7 @@ func RenameBranch(ctx context.Context, repo *repo_model.Repository, from, to str // 4. Update all not merged pull request base branch name _, err = sess.Table("pull_request").Where("base_repo_id=? AND base_branch=? AND has_merged=?", repo.ID, from, false). - Update(map[string]interface{}{"base_branch": to}) + Update(map[string]any{"base_branch": to}) if err != nil { return err } diff --git a/models/git/branch_list.go b/models/git/branch_list.go index 836d4ffc41777..131a149782e27 100644 --- a/models/git/branch_list.go +++ b/models/git/branch_list.go @@ -64,11 +64,6 @@ func (branches BranchList) LoadPusher(ctx context.Context) error { return nil } -const ( - BranchOrderByNameAsc = "name ASC" - BranchOrderByCommitTimeDesc = "commit_time DESC" -) - type FindBranchOptions struct { db.ListOptions RepoID int64 @@ -102,7 +97,8 @@ func orderByBranches(sess *xorm.Session, opts FindBranchOptions) *xorm.Session { } if opts.OrderBy == "" { - opts.OrderBy = BranchOrderByCommitTimeDesc + // the commit_time might be the same, so add the "name" to make sure the order is stable + opts.OrderBy = "commit_time DESC, name ASC" } return sess.OrderBy(opts.OrderBy) } diff --git a/models/git/commit_status.go b/models/git/commit_status.go index 49143a87e83f0..c418cd23eb63c 100644 --- a/models/git/commit_status.go +++ b/models/git/commit_status.go @@ -346,6 +346,53 @@ func GetLatestCommitStatusForPairs(ctx context.Context, repoIDsToLatestCommitSHA return repoStatuses, nil } +// GetLatestCommitStatusForRepoCommitIDs returns all statuses with a unique context for a given list of repo-sha pairs +func GetLatestCommitStatusForRepoCommitIDs(ctx context.Context, repoID int64, commitIDs []string) (map[string][]*CommitStatus, error) { + type result struct { + ID int64 + Sha string + } + + results := make([]result, 0, len(commitIDs)) + + sess := db.GetEngine(ctx).Table(&CommitStatus{}) + + // Create a disjunction of conditions for each repoID and SHA pair + conds := make([]builder.Cond, 0, len(commitIDs)) + for _, sha := range commitIDs { + conds = append(conds, builder.Eq{"sha": sha}) + } + sess = sess.Where(builder.Eq{"repo_id": repoID}.And(builder.Or(conds...))). + Select("max( id ) as id, sha"). + GroupBy("context_hash, sha").OrderBy("max( id ) desc") + + err := sess.Find(&results) + if err != nil { + return nil, err + } + + ids := make([]int64, 0, len(results)) + repoStatuses := make(map[string][]*CommitStatus) + for _, result := range results { + ids = append(ids, result.ID) + } + + statuses := make([]*CommitStatus, 0, len(ids)) + if len(ids) > 0 { + err = db.GetEngine(ctx).In("id", ids).Find(&statuses) + if err != nil { + return nil, err + } + + // Group the statuses by repo ID + for _, status := range statuses { + repoStatuses[status.SHA] = append(repoStatuses[status.SHA], status) + } + } + + return repoStatuses, nil +} + // FindRepoRecentCommitStatusContexts returns repository's recent commit status contexts func FindRepoRecentCommitStatusContexts(ctx context.Context, repoID int64, before time.Duration) ([]string, error) { start := timeutil.TimeStampNow().AddDuration(-before) diff --git a/models/git/lfs.go b/models/git/lfs.go index 0f90b2920047b..7d3da72a9410c 100644 --- a/models/git/lfs.go +++ b/models/git/lfs.go @@ -264,7 +264,7 @@ func LFSAutoAssociate(ctx context.Context, metas []*LFSMetaObject, user *user_mo sess := db.GetEngine(ctx) - oids := make([]interface{}, len(metas)) + oids := make([]any, len(metas)) oidMap := make(map[string]*LFSMetaObject, len(metas)) for i, meta := range metas { oids[i] = meta.Oid diff --git a/models/issues/comment.go b/models/issues/comment.go index dbe4434ca7542..303c23916ba2a 100644 --- a/models/issues/comment.go +++ b/models/issues/comment.go @@ -1131,7 +1131,7 @@ func DeleteComment(ctx context.Context, comment *Comment) error { } if _, err := e.Table("action"). Where("comment_id = ?", comment.ID). - Update(map[string]interface{}{ + Update(map[string]any{ "is_deleted": true, }); err != nil { return err @@ -1156,7 +1156,7 @@ func UpdateCommentsMigrationsByType(tp structs.GitServiceType, originalAuthorID }), )). And("comment.original_author_id = ?", originalAuthorID). - Update(map[string]interface{}{ + Update(map[string]any{ "poster_id": posterID, "original_author": "", "original_author_id": 0, diff --git a/models/issues/issue.go b/models/issues/issue.go index eab18f4892ce9..364d53ba318c3 100644 --- a/models/issues/issue.go +++ b/models/issues/issue.go @@ -714,7 +714,7 @@ func (issue *Issue) Pin(ctx context.Context, user *user_model.User) error { _, err = db.GetEngine(ctx).Table("issue"). Where("id = ?", issue.ID). - Update(map[string]interface{}{ + Update(map[string]any{ "pin_order": maxPin + 1, }) if err != nil { @@ -750,7 +750,7 @@ func (issue *Issue) Unpin(ctx context.Context, user *user_model.User) error { _, err = db.GetEngine(ctx).Table("issue"). Where("id = ?", issue.ID). - Update(map[string]interface{}{ + Update(map[string]any{ "pin_order": 0, }) if err != nil { @@ -822,7 +822,7 @@ func (issue *Issue) MovePin(ctx context.Context, newPosition int) error { _, err = db.GetEngine(dbctx).Table("issue"). Where("id = ?", issue.ID). - Update(map[string]interface{}{ + Update(map[string]any{ "pin_order": newPosition, }) if err != nil { diff --git a/models/issues/issue_update.go b/models/issues/issue_update.go index b6fd720fe5eb8..9453ddc085d4d 100644 --- a/models/issues/issue_update.go +++ b/models/issues/issue_update.go @@ -511,7 +511,7 @@ func UpdateIssueDeadline(issue *Issue, deadlineUnix timeutil.TimeStamp, doer *us } // DeleteInIssue delete records in beans with external key issue_id = ? -func DeleteInIssue(ctx context.Context, issueID int64, beans ...interface{}) error { +func DeleteInIssue(ctx context.Context, issueID int64, beans ...any) error { e := db.GetEngine(ctx) for _, bean := range beans { if _, err := e.In("issue_id", issueID).Delete(bean); err != nil { @@ -673,7 +673,7 @@ func UpdateIssuesMigrationsByType(gitServiceType api.GitServiceType, originalAut _, err := db.GetEngine(db.DefaultContext).Table("issue"). Where("repo_id IN (SELECT id FROM repository WHERE original_service_type = ?)", gitServiceType). And("original_author_id = ?", originalAuthorID). - Update(map[string]interface{}{ + Update(map[string]any{ "poster_id": posterID, "original_author": "", "original_author_id": 0, @@ -686,7 +686,7 @@ func UpdateReactionsMigrationsByType(gitServiceType api.GitServiceType, original _, err := db.GetEngine(db.DefaultContext).Table("reaction"). Where("original_author_id = ?", originalAuthorID). And(migratedIssueCond(gitServiceType)). - Update(map[string]interface{}{ + Update(map[string]any{ "user_id": userID, "original_author": "", "original_author_id": 0, diff --git a/models/issues/review.go b/models/issues/review.go index 3685c65ce581c..dbacfa3a8785d 100644 --- a/models/issues/review.go +++ b/models/issues/review.go @@ -1111,7 +1111,7 @@ func UpdateReviewsMigrationsByType(tp structs.GitServiceType, originalAuthorID s _, err := db.GetEngine(db.DefaultContext).Table("review"). Where("original_author_id = ?", originalAuthorID). And(migratedIssueCond(tp)). - Update(map[string]interface{}{ + Update(map[string]any{ "reviewer_id": posterID, "original_author": "", "original_author_id": 0, diff --git a/models/migrations/base/db.go b/models/migrations/base/db.go index b038ad73372e4..51351cc7d3297 100644 --- a/models/migrations/base/db.go +++ b/models/migrations/base/db.go @@ -27,7 +27,7 @@ import ( // RecreateTables will recreate the tables for the provided beans using the newly provided bean definition and move all data to that new table // WARNING: YOU MUST PROVIDE THE FULL BEAN DEFINITION -func RecreateTables(beans ...interface{}) func(*xorm.Engine) error { +func RecreateTables(beans ...any) func(*xorm.Engine) error { return func(x *xorm.Engine) error { sess := x.NewSession() defer sess.Close() @@ -48,7 +48,7 @@ func RecreateTables(beans ...interface{}) func(*xorm.Engine) error { // RecreateTable will recreate the table using the newly provided bean definition and move all data to that new table // WARNING: YOU MUST PROVIDE THE FULL BEAN DEFINITION // WARNING: YOU MUST COMMIT THE SESSION AT THE END -func RecreateTable(sess *xorm.Session, bean interface{}) error { +func RecreateTable(sess *xorm.Session, bean any) error { // TODO: This will not work if there are foreign keys tableName := sess.Engine().TableName(bean) diff --git a/models/migrations/base/tests.go b/models/migrations/base/tests.go index c3100ba665948..e7ff5241447a7 100644 --- a/models/migrations/base/tests.go +++ b/models/migrations/base/tests.go @@ -30,7 +30,7 @@ import ( // Provide models to be sync'd with the database - in particular any models you expect fixtures to be loaded from. // // fixtures in `models/migrations/fixtures/` will be loaded automatically -func PrepareTestEnv(t *testing.T, skip int, syncModels ...interface{}) (*xorm.Engine, func()) { +func PrepareTestEnv(t *testing.T, skip int, syncModels ...any) (*xorm.Engine, func()) { t.Helper() ourSkip := 2 ourSkip += skip diff --git a/models/migrations/v1_10/v100.go b/models/migrations/v1_10/v100.go index bd11790b9884c..e94024f4df43b 100644 --- a/models/migrations/v1_10/v100.go +++ b/models/migrations/v1_10/v100.go @@ -59,11 +59,11 @@ func UpdateMigrationServiceTypes(x *xorm.Engine) error { } type ExternalLoginUser struct { - ExternalID string `xorm:"pk NOT NULL"` - UserID int64 `xorm:"INDEX NOT NULL"` - LoginSourceID int64 `xorm:"pk NOT NULL"` - RawData map[string]interface{} `xorm:"TEXT JSON"` - Provider string `xorm:"index VARCHAR(25)"` + ExternalID string `xorm:"pk NOT NULL"` + UserID int64 `xorm:"INDEX NOT NULL"` + LoginSourceID int64 `xorm:"pk NOT NULL"` + RawData map[string]any `xorm:"TEXT JSON"` + Provider string `xorm:"index VARCHAR(25)"` Email string Name string FirstName string diff --git a/models/migrations/v1_16/v189.go b/models/migrations/v1_16/v189.go index 32e3899a3a1c4..79e3289ba7f51 100644 --- a/models/migrations/v1_16/v189.go +++ b/models/migrations/v1_16/v189.go @@ -14,7 +14,7 @@ import ( ) func UnwrapLDAPSourceCfg(x *xorm.Engine) error { - jsonUnmarshalHandleDoubleEncode := func(bs []byte, v interface{}) error { + jsonUnmarshalHandleDoubleEncode := func(bs []byte, v any) error { err := json.Unmarshal(bs, v) if err != nil { ok := true @@ -54,7 +54,7 @@ func UnwrapLDAPSourceCfg(x *xorm.Engine) error { const dldapType = 5 type WrappedSource struct { - Source map[string]interface{} + Source map[string]any } // change lower_email as unique @@ -77,7 +77,7 @@ func UnwrapLDAPSourceCfg(x *xorm.Engine) error { for _, source := range sources { wrapped := &WrappedSource{ - Source: map[string]interface{}{}, + Source: map[string]any{}, } err := jsonUnmarshalHandleDoubleEncode([]byte(source.Cfg), &wrapped) if err != nil { diff --git a/models/migrations/v1_16/v189_test.go b/models/migrations/v1_16/v189_test.go index 96cb97c328383..32ef821d27886 100644 --- a/models/migrations/v1_16/v189_test.go +++ b/models/migrations/v1_16/v189_test.go @@ -62,8 +62,8 @@ func Test_UnwrapLDAPSourceCfg(t *testing.T) { } for _, source := range sources { - converted := map[string]interface{}{} - expected := map[string]interface{}{} + converted := map[string]any{} + expected := map[string]any{} if err := json.Unmarshal([]byte(source.Cfg), &converted); err != nil { assert.NoError(t, err) diff --git a/models/migrations/v1_19/v233_test.go b/models/migrations/v1_19/v233_test.go index 83558da334e8d..32c10ab0f4511 100644 --- a/models/migrations/v1_19/v233_test.go +++ b/models/migrations/v1_19/v233_test.go @@ -79,7 +79,7 @@ func Test_AddHeaderAuthorizationEncryptedColWebhook(t *testing.T) { return } for _, h := range hookTasks { - var m map[string]interface{} + var m map[string]any err := json.Unmarshal([]byte(h.PayloadContent), &m) assert.NoError(t, err) assert.Nil(t, m["access_token"]) diff --git a/models/migrations/v1_6/v70.go b/models/migrations/v1_6/v70.go index fec88266ba6e8..74434a84a14f4 100644 --- a/models/migrations/v1_6/v70.go +++ b/models/migrations/v1_6/v70.go @@ -81,11 +81,11 @@ func AddIssueDependencies(x *xorm.Engine) (err error) { // RepoUnit describes all units of a repository type RepoUnit struct { ID int64 - RepoID int64 `xorm:"INDEX(s)"` - Type int `xorm:"INDEX(s)"` - Config map[string]interface{} `xorm:"JSON"` - CreatedUnix int64 `xorm:"INDEX CREATED"` - Created time.Time `xorm:"-"` + RepoID int64 `xorm:"INDEX(s)"` + Type int `xorm:"INDEX(s)"` + Config map[string]any `xorm:"JSON"` + CreatedUnix int64 `xorm:"INDEX CREATED"` + Created time.Time `xorm:"-"` } // Updating existing issue units @@ -96,7 +96,7 @@ func AddIssueDependencies(x *xorm.Engine) (err error) { } for _, unit := range units { if unit.Config == nil { - unit.Config = make(map[string]interface{}) + unit.Config = make(map[string]any) } if _, ok := unit.Config["EnableDependencies"]; !ok { unit.Config["EnableDependencies"] = setting.Service.DefaultEnableDependencies diff --git a/models/migrations/v1_8/v76.go b/models/migrations/v1_8/v76.go index f35856cc606cc..d3fbd94deb104 100644 --- a/models/migrations/v1_8/v76.go +++ b/models/migrations/v1_8/v76.go @@ -15,10 +15,10 @@ func AddPullRequestRebaseWithMerge(x *xorm.Engine) error { // RepoUnit describes all units of a repository type RepoUnit struct { ID int64 - RepoID int64 `xorm:"INDEX(s)"` - Type int `xorm:"INDEX(s)"` - Config map[string]interface{} `xorm:"JSON"` - CreatedUnix timeutil.TimeStamp `xorm:"INDEX CREATED"` + RepoID int64 `xorm:"INDEX(s)"` + Type int `xorm:"INDEX(s)"` + Config map[string]any `xorm:"JSON"` + CreatedUnix timeutil.TimeStamp `xorm:"INDEX CREATED"` } const ( @@ -46,7 +46,7 @@ func AddPullRequestRebaseWithMerge(x *xorm.Engine) error { } for _, unit := range units { if unit.Config == nil { - unit.Config = make(map[string]interface{}) + unit.Config = make(map[string]any) } // Allow the new merge style if all other merge styles are allowed allowMergeRebase := true diff --git a/models/packages/descriptor.go b/models/packages/descriptor.go index ee35ffe0f2a3a..f849ab5c0417c 100644 --- a/models/packages/descriptor.go +++ b/models/packages/descriptor.go @@ -59,7 +59,7 @@ type PackageDescriptor struct { Creator *user_model.User PackageProperties PackagePropertyList VersionProperties PackagePropertyList - Metadata interface{} + Metadata any Files []*PackageFileDescriptor } @@ -136,7 +136,7 @@ func GetPackageDescriptor(ctx context.Context, pv *PackageVersion) (*PackageDesc return nil, err } - var metadata interface{} + var metadata any switch p.Type { case TypeAlpine: metadata = &alpine.VersionMetadata{} diff --git a/models/perm/access/repo_permission.go b/models/perm/access/repo_permission.go index 64df5355bba6a..2027b87ecb43c 100644 --- a/models/perm/access/repo_permission.go +++ b/models/perm/access/repo_permission.go @@ -127,7 +127,8 @@ func (p *Permission) LogString() string { } // GetUserRepoPermission returns the user permissions to the repository -func GetUserRepoPermission(ctx context.Context, repo *repo_model.Repository, user *user_model.User) (perm Permission, err error) { +func GetUserRepoPermission(ctx context.Context, repo *repo_model.Repository, user *user_model.User) (Permission, error) { + var perm Permission if log.IsTrace() { defer func() { if user == nil { @@ -147,30 +148,31 @@ func GetUserRepoPermission(ctx context.Context, repo *repo_model.Repository, use // TODO: anonymous user visit public unit of private repo??? if user == nil && repo.IsPrivate { perm.AccessMode = perm_model.AccessModeNone - return + return perm, nil } - var is bool + var isCollaborator bool + var err error if user != nil { - is, err = repo_model.IsCollaborator(ctx, repo.ID, user.ID) + isCollaborator, err = repo_model.IsCollaborator(ctx, repo.ID, user.ID) if err != nil { return perm, err } } - if err = repo.LoadOwner(ctx); err != nil { - return + if err := repo.LoadOwner(ctx); err != nil { + return perm, err } // Prevent strangers from checking out public repo of private organization/users // Allow user if they are collaborator of a repo within a private user or a private organization but not a member of the organization itself - if !organization.HasOrgOrUserVisible(ctx, repo.Owner, user) && !is { + if !organization.HasOrgOrUserVisible(ctx, repo.Owner, user) && !isCollaborator { perm.AccessMode = perm_model.AccessModeNone - return + return perm, nil } - if err = repo.LoadUnits(ctx); err != nil { - return + if err := repo.LoadUnits(ctx); err != nil { + return perm, err } perm.Units = repo.Units @@ -178,32 +180,32 @@ func GetUserRepoPermission(ctx context.Context, repo *repo_model.Repository, use // anonymous visit public repo if user == nil { perm.AccessMode = perm_model.AccessModeRead - return + return perm, nil } // Admin or the owner has super access to the repository if user.IsAdmin || user.ID == repo.OwnerID { perm.AccessMode = perm_model.AccessModeOwner - return + return perm, nil } // plain user perm.AccessMode, err = accessLevel(ctx, user, repo) if err != nil { - return + return perm, err } - if err = repo.LoadOwner(ctx); err != nil { - return + if err := repo.LoadOwner(ctx); err != nil { + return perm, err } if !repo.Owner.IsOrganization() { - return + return perm, nil } perm.UnitsMode = make(map[unit.Type]perm_model.AccessMode) // Collaborators on organization - if is { + if isCollaborator { for _, u := range repo.Units { perm.UnitsMode[u.Type] = perm.AccessMode } @@ -212,7 +214,7 @@ func GetUserRepoPermission(ctx context.Context, repo *repo_model.Repository, use // get units mode from teams teams, err := organization.GetUserRepoTeams(ctx, repo.OwnerID, user.ID, repo.ID) if err != nil { - return + return perm, err } // if user in an owner team @@ -220,7 +222,7 @@ func GetUserRepoPermission(ctx context.Context, repo *repo_model.Repository, use if team.AccessMode >= perm_model.AccessModeAdmin { perm.AccessMode = perm_model.AccessModeOwner perm.UnitsMode = nil - return + return perm, nil } } diff --git a/models/repo.go b/models/repo.go index 933f7e56a3a04..9044fc8aedbc3 100644 --- a/models/repo.go +++ b/models/repo.go @@ -456,7 +456,7 @@ func repoStatsCorrectNumClosedPulls(ctx context.Context, id int64) error { return repo_model.UpdateRepoIssueNumbers(ctx, id, true, true) } -func statsQuery(args ...interface{}) func(context.Context) ([]map[string][]byte, error) { +func statsQuery(args ...any) func(context.Context) ([]map[string][]byte, error) { return func(ctx context.Context) ([]map[string][]byte, error) { return db.GetEngine(ctx).Query(args...) } diff --git a/models/repo/collaboration_test.go b/models/repo/collaboration_test.go index 0a6444de858ac..a29dfe99a50f1 100644 --- a/models/repo/collaboration_test.go +++ b/models/repo/collaboration_test.go @@ -33,6 +33,19 @@ func TestRepository_GetCollaborators(t *testing.T) { test(2) test(3) test(4) + + // Test db.ListOptions + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 22}) + + collaborators1, err := repo_model.GetCollaborators(db.DefaultContext, repo.ID, db.ListOptions{PageSize: 1, Page: 1}) + assert.NoError(t, err) + assert.Len(t, collaborators1, 1) + + collaborators2, err := repo_model.GetCollaborators(db.DefaultContext, repo.ID, db.ListOptions{PageSize: 1, Page: 2}) + assert.NoError(t, err) + assert.Len(t, collaborators2, 1) + + assert.NotEqualValues(t, collaborators1[0].ID, collaborators2[0].ID) } func TestRepository_IsCollaborator(t *testing.T) { @@ -66,5 +79,80 @@ func TestRepository_ChangeCollaborationAccessMode(t *testing.T) { assert.NoError(t, repo_model.ChangeCollaborationAccessMode(db.DefaultContext, repo, unittest.NonexistentID, perm.AccessModeAdmin)) + // Disvard invalid input. + assert.NoError(t, repo_model.ChangeCollaborationAccessMode(db.DefaultContext, repo, 4, perm.AccessMode(unittest.NonexistentID))) + unittest.CheckConsistencyFor(t, &repo_model.Repository{ID: repo.ID}) } + +func TestRepository_CountCollaborators(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + + repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4}) + count, err := repo_model.CountCollaborators(repo1.ID) + assert.NoError(t, err) + assert.EqualValues(t, 2, count) + + repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 22}) + count, err = repo_model.CountCollaborators(repo2.ID) + assert.NoError(t, err) + assert.EqualValues(t, 2, count) + + // Non-existent repository. + count, err = repo_model.CountCollaborators(unittest.NonexistentID) + assert.NoError(t, err) + assert.EqualValues(t, 0, count) +} + +func TestRepository_IsOwnerMemberCollaborator(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + + repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}) + + // Organisation owner. + actual, err := repo_model.IsOwnerMemberCollaborator(repo1, 2) + assert.NoError(t, err) + assert.True(t, actual) + + // Team member. + actual, err = repo_model.IsOwnerMemberCollaborator(repo1, 4) + assert.NoError(t, err) + assert.True(t, actual) + + // Normal user. + actual, err = repo_model.IsOwnerMemberCollaborator(repo1, 1) + assert.NoError(t, err) + assert.False(t, actual) + + repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4}) + + // Collaborator. + actual, err = repo_model.IsOwnerMemberCollaborator(repo2, 4) + assert.NoError(t, err) + assert.True(t, actual) + + repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 15}) + + // Repository owner. + actual, err = repo_model.IsOwnerMemberCollaborator(repo3, 2) + assert.NoError(t, err) + assert.True(t, actual) +} + +func TestRepo_GetCollaboration(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4}) + + // Existing collaboration. + collab, err := repo_model.GetCollaboration(db.DefaultContext, repo.ID, 4) + assert.NoError(t, err) + assert.NotNil(t, collab) + assert.EqualValues(t, 4, collab.UserID) + assert.EqualValues(t, 4, collab.RepoID) + + // Non-existing collaboration. + collab, err = repo_model.GetCollaboration(db.DefaultContext, repo.ID, 1) + assert.NoError(t, err) + assert.Nil(t, collab) +} diff --git a/models/repo/mirror.go b/models/repo/mirror.go index c1d24a4886375..39482037b2032 100644 --- a/models/repo/mirror.go +++ b/models/repo/mirror.go @@ -105,7 +105,7 @@ func DeleteMirrorByRepoID(repoID int64) error { } // MirrorsIterate iterates all mirror repositories. -func MirrorsIterate(limit int, f func(idx int, bean interface{}) error) error { +func MirrorsIterate(limit int, f func(idx int, bean any) error) error { sess := db.GetEngine(db.DefaultContext). Where("next_update_unix<=?", time.Now().Unix()). And("next_update_unix!=0"). diff --git a/models/repo/pushmirror.go b/models/repo/pushmirror.go index 642020bb5e6d8..f34484f638788 100644 --- a/models/repo/pushmirror.go +++ b/models/repo/pushmirror.go @@ -127,7 +127,7 @@ func GetPushMirrorsSyncedOnCommit(ctx context.Context, repoID int64) ([]*PushMir } // PushMirrorsIterate iterates all push-mirror repositories. -func PushMirrorsIterate(ctx context.Context, limit int, f func(idx int, bean interface{}) error) error { +func PushMirrorsIterate(ctx context.Context, limit int, f func(idx int, bean any) error) error { sess := db.GetEngine(ctx). Where("last_update + (`interval` / ?) <= ?", time.Second, time.Now().Unix()). And("`interval` != 0"). diff --git a/models/repo/pushmirror_test.go b/models/repo/pushmirror_test.go index 2b3c5be292c7e..9ab70235913d4 100644 --- a/models/repo/pushmirror_test.go +++ b/models/repo/pushmirror_test.go @@ -41,7 +41,7 @@ func TestPushMirrorsIterate(t *testing.T) { time.Sleep(1 * time.Millisecond) - repo_model.PushMirrorsIterate(db.DefaultContext, 1, func(idx int, bean interface{}) error { + repo_model.PushMirrorsIterate(db.DefaultContext, 1, func(idx int, bean any) error { m, ok := bean.(*repo_model.PushMirror) assert.True(t, ok) assert.Equal(t, "test-1", m.RemoteName) diff --git a/models/repo/release.go b/models/repo/release.go index b77490584f901..c63b32445767a 100644 --- a/models/repo/release.go +++ b/models/repo/release.go @@ -339,7 +339,7 @@ func (s releaseMetaSearch) Less(i, j int) bool { // GetReleaseAttachments retrieves the attachments for releases func GetReleaseAttachments(ctx context.Context, rels ...*Release) (err error) { if len(rels) == 0 { - return + return nil } // To keep this efficient as possible sort all releases by id, @@ -442,7 +442,7 @@ func UpdateReleasesMigrationsByType(gitServiceType structs.GitServiceType, origi _, err := db.GetEngine(db.DefaultContext).Table("release"). Where("repo_id IN (SELECT id FROM repository WHERE original_service_type = ?)", gitServiceType). And("original_author_id = ?", originalAuthorID). - Update(map[string]interface{}{ + Update(map[string]any{ "publisher_id": posterID, "original_author": "", "original_author_id": 0, diff --git a/models/repo/repo_list.go b/models/repo/repo_list.go index 92b9c15b4bd8d..83ba02e31653a 100644 --- a/models/repo/repo_list.go +++ b/models/repo/repo_list.go @@ -560,7 +560,7 @@ func searchRepositoryByCondition(ctx context.Context, opts *SearchRepoOptions, c opts.OrderBy = db.SearchOrderByAlphabetically } - args := make([]interface{}, 0) + args := make([]any, 0) if opts.PriorityOwnerID > 0 { opts.OrderBy = db.SearchOrderBy(fmt.Sprintf("CASE WHEN owner_id = ? THEN 0 ELSE owner_id END, %s", opts.OrderBy)) args = append(args, opts.PriorityOwnerID) diff --git a/models/system/notice.go b/models/system/notice.go index e598abe22251a..784ad74375bd9 100644 --- a/models/system/notice.go +++ b/models/system/notice.go @@ -43,7 +43,7 @@ func (n *Notice) TrStr() string { } // CreateNotice creates new system notice. -func CreateNotice(ctx context.Context, tp NoticeType, desc string, args ...interface{}) error { +func CreateNotice(ctx context.Context, tp NoticeType, desc string, args ...any) error { if len(args) > 0 { desc = fmt.Sprintf(desc, args...) } @@ -55,7 +55,7 @@ func CreateNotice(ctx context.Context, tp NoticeType, desc string, args ...inter } // CreateRepositoryNotice creates new system notice with type NoticeRepository. -func CreateRepositoryNotice(desc string, args ...interface{}) error { +func CreateRepositoryNotice(desc string, args ...any) error { // Note we use the db.DefaultContext here rather than passing in a context as the context may be cancelled return CreateNotice(db.DefaultContext, NoticeRepository, desc, args...) } diff --git a/models/unittest/consistency.go b/models/unittest/consistency.go index 41798c62536f5..faa02589aabde 100644 --- a/models/unittest/consistency.go +++ b/models/unittest/consistency.go @@ -21,10 +21,10 @@ const ( modelsCommentTypeComment = 0 ) -var consistencyCheckMap = make(map[string]func(t assert.TestingT, bean interface{})) +var consistencyCheckMap = make(map[string]func(t assert.TestingT, bean any)) // CheckConsistencyFor test that all matching database entries are consistent -func CheckConsistencyFor(t assert.TestingT, beansToCheck ...interface{}) { +func CheckConsistencyFor(t assert.TestingT, beansToCheck ...any) { for _, bean := range beansToCheck { sliceType := reflect.SliceOf(reflect.TypeOf(bean)) sliceValue := reflect.MakeSlice(sliceType, 0, 10) @@ -42,7 +42,7 @@ func CheckConsistencyFor(t assert.TestingT, beansToCheck ...interface{}) { } } -func checkForConsistency(t assert.TestingT, bean interface{}) { +func checkForConsistency(t assert.TestingT, bean any) { tb, err := db.TableInfo(bean) assert.NoError(t, err) f := consistencyCheckMap[tb.Name] @@ -63,7 +63,7 @@ func init() { return i } - checkForUserConsistency := func(t assert.TestingT, bean interface{}) { + checkForUserConsistency := func(t assert.TestingT, bean any) { user := reflectionWrap(bean) AssertCountByCond(t, "repository", builder.Eq{"owner_id": user.int("ID")}, user.int("NumRepos")) AssertCountByCond(t, "star", builder.Eq{"uid": user.int("ID")}, user.int("NumStars")) @@ -77,7 +77,7 @@ func init() { } } - checkForRepoConsistency := func(t assert.TestingT, bean interface{}) { + checkForRepoConsistency := func(t assert.TestingT, bean any) { repo := reflectionWrap(bean) assert.Equal(t, repo.str("LowerName"), strings.ToLower(repo.str("Name")), "repo: %+v", repo) AssertCountByCond(t, "star", builder.Eq{"repo_id": repo.int("ID")}, repo.int("NumStars")) @@ -113,7 +113,7 @@ func init() { "Unexpected number of closed milestones for repo id: %d", repo.int("ID")) } - checkForIssueConsistency := func(t assert.TestingT, bean interface{}) { + checkForIssueConsistency := func(t assert.TestingT, bean any) { issue := reflectionWrap(bean) typeComment := modelsCommentTypeComment actual := GetCountByCond(t, "comment", builder.Eq{"`type`": typeComment, "issue_id": issue.int("ID")}) @@ -124,14 +124,14 @@ func init() { } } - checkForPullRequestConsistency := func(t assert.TestingT, bean interface{}) { + checkForPullRequestConsistency := func(t assert.TestingT, bean any) { pr := reflectionWrap(bean) issueRow := AssertExistsAndLoadMap(t, "issue", builder.Eq{"id": pr.int("IssueID")}) assert.True(t, parseBool(issueRow["is_pull"])) assert.EqualValues(t, parseInt(issueRow["index"]), pr.int("Index"), "Unexpected index for pull request id: %d", pr.int("ID")) } - checkForMilestoneConsistency := func(t assert.TestingT, bean interface{}) { + checkForMilestoneConsistency := func(t assert.TestingT, bean any) { milestone := reflectionWrap(bean) AssertCountByCond(t, "issue", builder.Eq{"milestone_id": milestone.int("ID")}, milestone.int("NumIssues")) @@ -145,7 +145,7 @@ func init() { assert.Equal(t, completeness, milestone.int("Completeness")) } - checkForLabelConsistency := func(t assert.TestingT, bean interface{}) { + checkForLabelConsistency := func(t assert.TestingT, bean any) { label := reflectionWrap(bean) issueLabels, err := db.GetEngine(db.DefaultContext).Table("issue_label"). Where(builder.Eq{"label_id": label.int("ID")}). @@ -166,13 +166,13 @@ func init() { assert.EqualValues(t, expected, label.int("NumClosedIssues"), "Unexpected number of closed issues for label id: %d", label.int("ID")) } - checkForTeamConsistency := func(t assert.TestingT, bean interface{}) { + checkForTeamConsistency := func(t assert.TestingT, bean any) { team := reflectionWrap(bean) AssertCountByCond(t, "team_user", builder.Eq{"team_id": team.int("ID")}, team.int("NumMembers")) AssertCountByCond(t, "team_repo", builder.Eq{"team_id": team.int("ID")}, team.int("NumRepos")) } - checkForActionConsistency := func(t assert.TestingT, bean interface{}) { + checkForActionConsistency := func(t assert.TestingT, bean any) { action := reflectionWrap(bean) if action.int("RepoID") != 1700 { // dangling intentional repoRow := AssertExistsAndLoadMap(t, "repository", builder.Eq{"id": action.int("RepoID")}) diff --git a/models/unittest/reflection.go b/models/unittest/reflection.go index 1b149b19fe072..141fc66b9981a 100644 --- a/models/unittest/reflection.go +++ b/models/unittest/reflection.go @@ -23,7 +23,7 @@ type reflectionValue struct { v reflect.Value } -func reflectionWrap(v interface{}) *reflectionValue { +func reflectionWrap(v any) *reflectionValue { return &reflectionValue{v: reflect.ValueOf(v)} } diff --git a/models/unittest/testdb.go b/models/unittest/testdb.go index f926a65538efa..1ff0fdc25bda8 100644 --- a/models/unittest/testdb.go +++ b/models/unittest/testdb.go @@ -37,7 +37,7 @@ func FixturesDir() string { return fixturesDir } -func fatalTestError(fmtStr string, args ...interface{}) { +func fatalTestError(fmtStr string, args ...any) { _, _ = fmt.Fprintf(os.Stderr, fmtStr, args...) os.Exit(1) } diff --git a/models/user/external_login_user.go b/models/user/external_login_user.go index f70f3effcc520..3a56240435f87 100644 --- a/models/user/external_login_user.go +++ b/models/user/external_login_user.go @@ -57,11 +57,11 @@ func (err ErrExternalLoginUserNotExist) Unwrap() error { // ExternalLoginUser makes the connecting between some existing user and additional external login sources type ExternalLoginUser struct { - ExternalID string `xorm:"pk NOT NULL"` - UserID int64 `xorm:"INDEX NOT NULL"` - LoginSourceID int64 `xorm:"pk NOT NULL"` - RawData map[string]interface{} `xorm:"TEXT JSON"` - Provider string `xorm:"index VARCHAR(25)"` + ExternalID string `xorm:"pk NOT NULL"` + UserID int64 `xorm:"INDEX NOT NULL"` + LoginSourceID int64 `xorm:"pk NOT NULL"` + RawData map[string]any `xorm:"TEXT JSON"` + Provider string `xorm:"index VARCHAR(25)"` Email string Name string FirstName string diff --git a/models/user/redirect.go b/models/user/redirect.go index 9d8903c05994a..42e991888a69e 100644 --- a/models/user/redirect.go +++ b/models/user/redirect.go @@ -64,6 +64,10 @@ func NewUserRedirect(ctx context.Context, ID int64, oldUserName, newUserName str oldUserName = strings.ToLower(oldUserName) newUserName = strings.ToLower(newUserName) + if err := DeleteUserRedirect(ctx, oldUserName); err != nil { + return err + } + if err := DeleteUserRedirect(ctx, newUserName); err != nil { return err } diff --git a/models/webhook/hooktask.go b/models/webhook/hooktask.go index f9fc886826394..3ece5f062d921 100644 --- a/models/webhook/hooktask.go +++ b/models/webhook/hooktask.go @@ -92,7 +92,7 @@ func (t *HookTask) AfterLoad() { } } -func (t *HookTask) simpleMarshalJSON(v interface{}) string { +func (t *HookTask) simpleMarshalJSON(v any) string { p, err := json.Marshal(v) if err != nil { log.Error("Marshal [%d]: %v", t.ID, err) diff --git a/modules/actions/workflows.go b/modules/actions/workflows.go index 3786f2a274ce3..7ba82004dfa4e 100644 --- a/modules/actions/workflows.go +++ b/modules/actions/workflows.go @@ -29,7 +29,7 @@ type DetectedWorkflow struct { } func init() { - model.OnDecodeNodeError = func(node yaml.Node, out interface{}, err error) { + model.OnDecodeNodeError = func(node yaml.Node, out any, err error) { // Log the error instead of panic or fatal. // It will be a big job to refactor act/pkg/model to return decode error, // so we just log the error and return empty value, and improve it later. diff --git a/modules/avatar/hash_test.go b/modules/avatar/hash_test.go new file mode 100644 index 0000000000000..1b8249c696c3a --- /dev/null +++ b/modules/avatar/hash_test.go @@ -0,0 +1,26 @@ +// Copyright 2023 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package avatar_test + +import ( + "bytes" + "image" + "image/png" + "testing" + + "code.gitea.io/gitea/modules/avatar" + + "github.com/stretchr/testify/assert" +) + +func Test_HashAvatar(t *testing.T) { + myImage := image.NewRGBA(image.Rect(0, 0, 32, 32)) + var buff bytes.Buffer + png.Encode(&buff, myImage) + + assert.EqualValues(t, "9ddb5bac41d57e72aa876321d0c09d71090c05f94bc625303801be2f3240d2cb", avatar.HashAvatar(1, buff.Bytes())) + assert.EqualValues(t, "9a5d44e5d637b9582a976676e8f3de1dccd877c2fe3e66ca3fab1629f2f47609", avatar.HashAvatar(8, buff.Bytes())) + assert.EqualValues(t, "ed7399158672088770de6f5211ce15528ebd675e92fc4fc060c025f4b2794ccb", avatar.HashAvatar(1024, buff.Bytes())) + assert.EqualValues(t, "161178642c7d59eb25a61dddced5e6b66eae1c70880d5f148b1b497b767e72d9", avatar.HashAvatar(1024, []byte{})) +} diff --git a/modules/base/tool.go b/modules/base/tool.go index 004781835a59a..71dcb83fb4850 100644 --- a/modules/base/tool.go +++ b/modules/base/tool.go @@ -107,7 +107,7 @@ const TimeLimitCodeLength = 12 + 6 + 40 // CreateTimeLimitCode create a time limit code // code format: 12 length date time string + 6 minutes string + 40 sha1 encoded string -func CreateTimeLimitCode(data string, minutes int, startInf interface{}) string { +func CreateTimeLimitCode(data string, minutes int, startInf any) string { format := "200601021504" var start, end time.Time @@ -245,7 +245,7 @@ func SetupGiteaRoot() string { } // FormatNumberSI format a number -func FormatNumberSI(data interface{}) string { +func FormatNumberSI(data any) string { var num int64 if num1, ok := data.(int64); ok { num = num1 diff --git a/modules/cache/cache_redis.go b/modules/cache/cache_redis.go index f22482de48a2f..6c358b0a78a4d 100644 --- a/modules/cache/cache_redis.go +++ b/modules/cache/cache_redis.go @@ -24,7 +24,7 @@ type RedisCacher struct { } // toStr convert string/int/int64 interface to string. it's only used by the RedisCacher.Put internally -func toStr(v interface{}) string { +func toStr(v any) string { if v == nil { return "" } @@ -44,7 +44,7 @@ func toStr(v interface{}) string { // Put puts value (string type) into cache with key and expire time. // If expired is 0, it lives forever. -func (c *RedisCacher) Put(key string, val interface{}, expire int64) error { +func (c *RedisCacher) Put(key string, val any, expire int64) error { // this function is not well-designed, it only puts string values into cache key = c.prefix + key if expire == 0 { @@ -65,7 +65,7 @@ func (c *RedisCacher) Put(key string, val interface{}, expire int64) error { } // Get gets cached value by given key. -func (c *RedisCacher) Get(key string) interface{} { +func (c *RedisCacher) Get(key string) any { val, err := c.c.Get(graceful.GetManager().HammerContext(), c.prefix+key).Result() if err != nil { return nil diff --git a/modules/cache/cache_twoqueue.go b/modules/cache/cache_twoqueue.go index 2e2efd00f2401..184db255736f4 100644 --- a/modules/cache/cache_twoqueue.go +++ b/modules/cache/cache_twoqueue.go @@ -30,7 +30,7 @@ type TwoQueueCacheConfig struct { // MemoryItem represents a memory cache item. type MemoryItem struct { - Val interface{} + Val any Created int64 Timeout int64 } @@ -43,7 +43,7 @@ func (item *MemoryItem) hasExpired() bool { var _ mc.Cache = &TwoQueueCache{} // Put puts value into cache with key and expire time. -func (c *TwoQueueCache) Put(key string, val interface{}, timeout int64) error { +func (c *TwoQueueCache) Put(key string, val any, timeout int64) error { item := &MemoryItem{ Val: val, Created: time.Now().Unix(), @@ -56,7 +56,7 @@ func (c *TwoQueueCache) Put(key string, val interface{}, timeout int64) error { } // Get gets cached value by given key. -func (c *TwoQueueCache) Get(key string) interface{} { +func (c *TwoQueueCache) Get(key string) any { c.lock.Lock() defer c.lock.Unlock() cached, ok := c.cache.Get(key) @@ -146,7 +146,7 @@ func (c *TwoQueueCache) Flush() error { return nil } -func (c *TwoQueueCache) checkAndInvalidate(key interface{}) { +func (c *TwoQueueCache) checkAndInvalidate(key any) { c.lock.Lock() defer c.lock.Unlock() cached, ok := c.cache.Peek(key) diff --git a/modules/charset/ambiguous/generate.go b/modules/charset/ambiguous/generate.go index b0c2531008203..e3fda5be982ef 100644 --- a/modules/charset/ambiguous/generate.go +++ b/modules/charset/ambiguous/generate.go @@ -90,7 +90,7 @@ Usage: %[1]s [-v] [-o output.go] ambiguous.json sort.Slice(tables, func(i, j int) bool { return tables[i].Locale < tables[j].Locale }) - data := map[string]interface{}{ + data := map[string]any{ "Tables": tables, } @@ -99,7 +99,7 @@ Usage: %[1]s [-v] [-o output.go] ambiguous.json } } -func runTemplate(t *template.Template, filename string, data interface{}) error { +func runTemplate(t *template.Template, filename string, data any) error { buf := bytes.NewBuffer(nil) if err := t.Execute(buf, data); err != nil { return fmt.Errorf("unable to execute template: %w", err) @@ -172,17 +172,17 @@ var AmbiguousCharacters = map[string]*AmbiguousTable{ `)) -func logf(format string, args ...interface{}) { +func logf(format string, args ...any) { fmt.Fprintf(os.Stderr, format+"\n", args...) } -func verbosef(format string, args ...interface{}) { +func verbosef(format string, args ...any) { if verbose { logf(format, args...) } } -func fatalf(format string, args ...interface{}) { +func fatalf(format string, args ...any) { logf("fatal: "+format+"\n", args...) os.Exit(1) } diff --git a/modules/charset/invisible/generate.go b/modules/charset/invisible/generate.go index 9dfc253333559..bd57dd6c4dd61 100644 --- a/modules/charset/invisible/generate.go +++ b/modules/charset/invisible/generate.go @@ -52,7 +52,7 @@ Usage: %[1]s [-v] [-o output.go] } } -func runTemplate(t *template.Template, filename string, data interface{}) error { +func runTemplate(t *template.Template, filename string, data any) error { buf := bytes.NewBuffer(nil) if err := t.Execute(buf, data); err != nil { return fmt.Errorf("unable to execute template: %w", err) @@ -105,17 +105,17 @@ var InvisibleRanges = &unicode.RangeTable{ } `)) -func logf(format string, args ...interface{}) { +func logf(format string, args ...any) { fmt.Fprintf(os.Stderr, format+"\n", args...) } -func verbosef(format string, args ...interface{}) { +func verbosef(format string, args ...any) { if verbose { logf(format, args...) } } -func fatalf(format string, args ...interface{}) { +func fatalf(format string, args ...any) { logf("fatal: "+format+"\n", args...) os.Exit(1) } diff --git a/modules/context/access_log.go b/modules/context/access_log.go index 373574ba148f4..0926748ac540f 100644 --- a/modules/context/access_log.go +++ b/modules/context/access_log.go @@ -23,7 +23,7 @@ type routerLoggerOptions struct { Identity *string Start *time.Time ResponseWriter http.ResponseWriter - Ctx map[string]interface{} + Ctx map[string]any RequestID *string } @@ -84,7 +84,7 @@ func AccessLogger() func(http.Handler) http.Handler { Identity: &identity, Start: &start, ResponseWriter: rw, - Ctx: map[string]interface{}{ + Ctx: map[string]any{ "RemoteAddr": req.RemoteAddr, "RemoteHost": reqHost, "Req": req, diff --git a/modules/context/api.go b/modules/context/api.go index 3c4d02041334e..93a587d436933 100644 --- a/modules/context/api.go +++ b/modules/context/api.go @@ -108,7 +108,7 @@ func (ctx *APIContext) ServerError(title string, err error) { // Error responds with an error message to client with given obj as the message. // If status is 500, also it prints error to log. -func (ctx *APIContext) Error(status int, title string, obj interface{}) { +func (ctx *APIContext) Error(status int, title string, obj any) { var message string if err, ok := obj.(error); ok { message = err.Error() @@ -265,7 +265,7 @@ func APIContexter() func(http.Handler) http.Handler { // NotFound handles 404s for APIContext // String will replace message, errors will be added to a slice -func (ctx *APIContext) NotFound(objs ...interface{}) { +func (ctx *APIContext) NotFound(objs ...any) { message := ctx.Tr("error.not_found") var errors []string for _, obj := range objs { @@ -281,7 +281,7 @@ func (ctx *APIContext) NotFound(objs ...interface{}) { } } - ctx.JSON(http.StatusNotFound, map[string]interface{}{ + ctx.JSON(http.StatusNotFound, map[string]any{ "message": message, "url": setting.API.SwaggerURL, "errors": errors, diff --git a/modules/context/base.go b/modules/context/base.go index 839f3e10df480..8566ef7861bae 100644 --- a/modules/context/base.go +++ b/modules/context/base.go @@ -128,7 +128,7 @@ func (b *Base) Error(status int, contents ...string) { } // JSON render content as JSON -func (b *Base) JSON(status int, content interface{}) { +func (b *Base) JSON(status int, content any) { b.Resp.Header().Set("Content-Type", "application/json;charset=utf-8") b.Resp.WriteHeader(status) if err := json.NewEncoder(b.Resp).Encode(content); err != nil { diff --git a/modules/context/captcha.go b/modules/context/captcha.go index 07232e9390663..a1999900c94de 100644 --- a/modules/context/captcha.go +++ b/modules/context/captcha.go @@ -60,7 +60,7 @@ const ( // VerifyCaptcha verifies Captcha data // No-op if captchas are not enabled -func VerifyCaptcha(ctx *Context, tpl base.TplName, form interface{}) { +func VerifyCaptcha(ctx *Context, tpl base.TplName, form any) { if !setting.Service.EnableCaptcha { return } diff --git a/modules/context/context.go b/modules/context/context.go index 93d448fca5550..47a04c989c81f 100644 --- a/modules/context/context.go +++ b/modules/context/context.go @@ -32,7 +32,7 @@ import ( // Render represents a template render type Render interface { TemplateLookup(tmpl string) (templates.TemplateExecutor, error) - HTML(w io.Writer, status int, name string, data interface{}) error + HTML(w io.Writer, status int, name string, data any) error } // Context represents context of a request. @@ -69,7 +69,7 @@ func init() { // TrHTMLEscapeArgs runs ".Locale.Tr()" but pre-escapes all arguments with html.EscapeString. // This is useful if the locale message is intended to only produce HTML content. func (ctx *Context) TrHTMLEscapeArgs(msg string, args ...string) string { - trArgs := make([]interface{}, len(args)) + trArgs := make([]any, len(args)) for i, arg := range args { trArgs[i] = html.EscapeString(arg) } diff --git a/modules/context/context_response.go b/modules/context/context_response.go index 88e375986cd6b..bb3ccf69ce421 100644 --- a/modules/context/context_response.go +++ b/modules/context/context_response.go @@ -91,14 +91,14 @@ func (ctx *Context) HTML(status int, name base.TplName) { } // RenderToString renders the template content to a string -func (ctx *Context) RenderToString(name base.TplName, data map[string]interface{}) (string, error) { +func (ctx *Context) RenderToString(name base.TplName, data map[string]any) (string, error) { var buf strings.Builder err := ctx.Render.HTML(&buf, http.StatusOK, string(name), data) return buf.String(), err } // RenderWithErr used for page has form validation but need to prompt error to users. -func (ctx *Context) RenderWithErr(msg string, tpl base.TplName, form interface{}) { +func (ctx *Context) RenderWithErr(msg string, tpl base.TplName, form any) { if form != nil { middleware.AssignForm(form, ctx.Data) } diff --git a/modules/context/package.go b/modules/context/package.go index 8052032787117..8e80fa66ec43d 100644 --- a/modules/context/package.go +++ b/modules/context/package.go @@ -33,7 +33,7 @@ type packageAssignmentCtx struct { // PackageAssignment returns a middleware to handle Context.Package assignment func PackageAssignment() func(ctx *Context) { return func(ctx *Context) { - errorFn := func(status int, title string, obj interface{}) { + errorFn := func(status int, title string, obj any) { err, ok := obj.(error) if !ok { err = fmt.Errorf("%s", obj) @@ -57,7 +57,7 @@ func PackageAssignmentAPI() func(ctx *APIContext) { } } -func packageAssignment(ctx *packageAssignmentCtx, errCb func(int, string, interface{})) *Package { +func packageAssignment(ctx *packageAssignmentCtx, errCb func(int, string, any)) *Package { pkg := &Package{ Owner: ctx.ContextUser, } diff --git a/modules/context/pagination.go b/modules/context/pagination.go index 5a88c92053aa7..68237c630c0ae 100644 --- a/modules/context/pagination.go +++ b/modules/context/pagination.go @@ -32,7 +32,7 @@ func (p *Pagination) AddParam(ctx *Context, paramKey, ctxKey string) { if !exists { return } - paramData := fmt.Sprintf("%v", ctx.Data[ctxKey]) // cast interface{} to string + paramData := fmt.Sprintf("%v", ctx.Data[ctxKey]) // cast any to string urlParam := fmt.Sprintf("%s=%v", url.QueryEscape(paramKey), url.QueryEscape(paramData)) p.urlParams = append(p.urlParams, urlParam) } diff --git a/modules/context/permission.go b/modules/context/permission.go index 0f72b8e244d4c..09343b8b50bc0 100644 --- a/modules/context/permission.go +++ b/modules/context/permission.go @@ -90,7 +90,7 @@ func RequireRepoReaderOr(unitTypes ...unit.Type) func(ctx *Context) { } if log.IsTrace() { var format string - var args []interface{} + var args []any if ctx.IsSigned { format = "Permission Denied: User %-v cannot read [" args = append(args, ctx.Doer) diff --git a/modules/context/private.go b/modules/context/private.go index 2e9b31140ab56..8b41949f604e1 100644 --- a/modules/context/private.go +++ b/modules/context/private.go @@ -53,7 +53,7 @@ func (ctx *PrivateContext) Err() error { return ctx.Base.Err() } -var privateContextKey interface{} = "default_private_context" +var privateContextKey any = "default_private_context" // GetPrivateContext returns a context for Private routes func GetPrivateContext(req *http.Request) *PrivateContext { diff --git a/modules/eventsource/event.go b/modules/eventsource/event.go index d5d2f323afec1..811f97ff56263 100644 --- a/modules/eventsource/event.go +++ b/modules/eventsource/event.go @@ -51,8 +51,8 @@ func wrapNewlines(w io.Writer, prefix, value []byte) (sum int64, err error) { type Event struct { // Name represents the value of the event: tag in the stream Name string - // Data is either JSONified []byte or interface{} that can be JSONd - Data interface{} + // Data is either JSONified []byte or any that can be JSONd + Data any // ID represents the ID of an event ID string // Retry tells the receiver only to attempt to reconnect to the source after this time diff --git a/modules/git/command.go b/modules/git/command.go index ac013d4ea1c7c..c38fd04696671 100644 --- a/modules/git/command.go +++ b/modules/git/command.go @@ -301,6 +301,8 @@ func (c *Command) Run(opts *RunOpts) error { } defer finished() + startTime := time.Now() + cmd := exec.CommandContext(ctx, c.prog, c.args...) if opts.Env == nil { cmd.Env = os.Environ() @@ -327,7 +329,13 @@ func (c *Command) Run(opts *RunOpts) error { } } - if err := cmd.Wait(); err != nil && ctx.Err() != context.DeadlineExceeded { + err := cmd.Wait() + elapsed := time.Since(startTime) + if elapsed > time.Second { + log.Debug("slow git.Command.Run: %s (%s)", c, elapsed) + } + + if err != nil && ctx.Err() != context.DeadlineExceeded { return err } diff --git a/modules/git/commit_info_gogit.go b/modules/git/commit_info_gogit.go index 20db5691ebe42..c61d27993cd78 100644 --- a/modules/git/commit_info_gogit.go +++ b/modules/git/commit_info_gogit.go @@ -177,7 +177,7 @@ func GetLastCommitForPaths(ctx context.Context, cache *LastCommitCache, c cgobje refSha := c.ID().String() // We do a tree traversal with nodes sorted by commit time - heap := binaryheap.NewWith(func(a, b interface{}) int { + heap := binaryheap.NewWith(func(a, b any) int { if a.(*commitAndPaths).commit.CommitTime().Before(b.(*commitAndPaths).commit.CommitTime()) { return 1 } diff --git a/modules/git/foreachref/parser_test.go b/modules/git/foreachref/parser_test.go index 5468318ca80cf..7a37ced3565cf 100644 --- a/modules/git/foreachref/parser_test.go +++ b/modules/git/foreachref/parser_test.go @@ -217,7 +217,7 @@ func TestParser(t *testing.T) { } } -func pretty(v interface{}) string { +func pretty(v any) string { data, err := json.MarshalIndent(v, "", " ") if err != nil { // shouldn't happen diff --git a/modules/git/git.go b/modules/git/git.go index f9c0ed669f490..f78a496d534c2 100644 --- a/modules/git/git.go +++ b/modules/git/git.go @@ -114,7 +114,7 @@ func VersionInfo() string { return "(git not found)" } format := "%s" - args := []interface{}{gitVersion.Original()} + args := []any{gitVersion.Original()} // Since git wire protocol has been released from git v2.18 if setting.Git.EnableAutoGitWireProtocol && CheckGitVersionAtLeast("2.18") == nil { format += ", Wire Protocol %s Enabled" diff --git a/modules/git/last_commit_cache.go b/modules/git/last_commit_cache.go index 984561b2c6729..20bc79608557a 100644 --- a/modules/git/last_commit_cache.go +++ b/modules/git/last_commit_cache.go @@ -15,9 +15,9 @@ import ( // Cache represents a caching interface type Cache interface { // Put puts value into cache with key and expire time. - Put(key string, val interface{}, timeout int64) error + Put(key string, val any, timeout int64) error // Get gets cached value by given key. - Get(key string) interface{} + Get(key string) any } func getCacheKey(repoPath, commitID, entryPath string) string { diff --git a/modules/git/utils.go b/modules/git/utils.go index b44363820dcfb..0d67412707e5b 100644 --- a/modules/git/utils.go +++ b/modules/git/utils.go @@ -15,17 +15,17 @@ import ( // ObjectCache provides thread-safe cache operations. type ObjectCache struct { lock sync.RWMutex - cache map[string]interface{} + cache map[string]any } func newObjectCache() *ObjectCache { return &ObjectCache{ - cache: make(map[string]interface{}, 10), + cache: make(map[string]any, 10), } } // Set add obj to cache -func (oc *ObjectCache) Set(id string, obj interface{}) { +func (oc *ObjectCache) Set(id string, obj any) { oc.lock.Lock() defer oc.lock.Unlock() @@ -33,7 +33,7 @@ func (oc *ObjectCache) Set(id string, obj interface{}) { } // Get get cached obj by id -func (oc *ObjectCache) Get(id string) (interface{}, bool) { +func (oc *ObjectCache) Get(id string) (any, bool) { oc.lock.RLock() defer oc.lock.RUnlock() diff --git a/modules/graceful/manager.go b/modules/graceful/manager.go index 3604c0a3f5804..068de21076fc7 100644 --- a/modules/graceful/manager.go +++ b/modules/graceful/manager.go @@ -283,7 +283,7 @@ func (g *Manager) Err() error { } // Value allows the manager to be viewed as a context.Context done at Terminate -func (g *Manager) Value(key interface{}) interface{} { +func (g *Manager) Value(key any) any { return g.managerCtx.Value(key) } diff --git a/modules/html/html.go b/modules/html/html.go index 3219b939f40a8..6cb6b847ef19c 100644 --- a/modules/html/html.go +++ b/modules/html/html.go @@ -5,7 +5,7 @@ package html // ParseSizeAndClass get size and class from string with default values // If present, "others" expects the new size first and then the classes to use -func ParseSizeAndClass(defaultSize int, defaultClass string, others ...interface{}) (int, string) { +func ParseSizeAndClass(defaultSize int, defaultClass string, others ...any) (int, string) { if len(others) == 0 { return defaultSize, defaultClass } diff --git a/modules/httplib/request.go b/modules/httplib/request.go index e904d77e14977..880d7ad3cbe36 100644 --- a/modules/httplib/request.go +++ b/modules/httplib/request.go @@ -101,7 +101,7 @@ func (r *Request) Param(key, value string) *Request { // Body adds request raw body. // it supports string and []byte. -func (r *Request) Body(data interface{}) *Request { +func (r *Request) Body(data any) *Request { switch t := data.(type) { case string: bf := bytes.NewBufferString(t) diff --git a/modules/indexer/code/bleve/bleve.go b/modules/indexer/code/bleve/bleve.go index 33cc4e02b5149..1e34226e8df14 100644 --- a/modules/indexer/code/bleve/bleve.go +++ b/modules/indexer/code/bleve/bleve.go @@ -51,7 +51,7 @@ func numericEqualityQuery(value int64, field string) *query.NumericRangeQuery { } func addUnicodeNormalizeTokenFilter(m *mapping.IndexMappingImpl) error { - return m.AddCustomTokenFilter(unicodeNormalizeName, map[string]interface{}{ + return m.AddCustomTokenFilter(unicodeNormalizeName, map[string]any{ "type": unicodenorm.Name, "form": unicodenorm.NFC, }) @@ -101,7 +101,7 @@ func generateBleveIndexMapping() (mapping.IndexMapping, error) { mapping := bleve.NewIndexMapping() if err := addUnicodeNormalizeTokenFilter(mapping); err != nil { return nil, err - } else if err := mapping.AddCustomAnalyzer(repoIndexerAnalyzer, map[string]interface{}{ + } else if err := mapping.AddCustomAnalyzer(repoIndexerAnalyzer, map[string]any{ "type": analyzer_custom.Name, "char_filters": []string{}, "tokenizer": unicode.Name, diff --git a/modules/indexer/code/elasticsearch/elasticsearch.go b/modules/indexer/code/elasticsearch/elasticsearch.go index 88054585cd28f..e7e3429a39af6 100644 --- a/modules/indexer/code/elasticsearch/elasticsearch.go +++ b/modules/indexer/code/elasticsearch/elasticsearch.go @@ -133,7 +133,7 @@ func (b *Indexer) addUpdate(ctx context.Context, batchWriter git.WriteCloserErro elastic.NewBulkIndexRequest(). Index(b.inner.VersionedIndexName()). Id(id). - Doc(map[string]interface{}{ + Doc(map[string]any{ "repo_id": repo.ID, "content": string(charset.ToUTF8DropErrors(fileContents)), "commit_id": sha, @@ -234,7 +234,7 @@ func convertResult(searchResult *elastic.SearchResult, kw string, pageSize int) } repoID, fileName := internal.ParseIndexerID(hit.Id) - res := make(map[string]interface{}) + res := make(map[string]any) if err := json.Unmarshal(hit.Source, &res); err != nil { return 0, nil, nil, err } @@ -285,7 +285,7 @@ func (b *Indexer) Search(ctx context.Context, repoIDs []int64, language, keyword query := elastic.NewBoolQuery() query = query.Must(kwQuery) if len(repoIDs) > 0 { - repoStrs := make([]interface{}, 0, len(repoIDs)) + repoStrs := make([]any, 0, len(repoIDs)) for _, repoID := range repoIDs { repoStrs = append(repoStrs, repoID) } diff --git a/modules/indexer/internal/bleve/batch.go b/modules/indexer/internal/bleve/batch.go index 77675147b2cda..ed5ef0773c8cf 100644 --- a/modules/indexer/internal/bleve/batch.go +++ b/modules/indexer/internal/bleve/batch.go @@ -27,7 +27,7 @@ func NewFlushingBatch(index bleve.Index, maxBatchSize int) *FlushingBatch { } // Index add a new index to batch -func (b *FlushingBatch) Index(id string, data interface{}) error { +func (b *FlushingBatch) Index(id string, data any) error { if err := b.batch.Index(id, data); err != nil { return err } diff --git a/modules/indexer/issues/bleve/bleve.go b/modules/indexer/issues/bleve/bleve.go index bb0bc4b04a414..4cc58acac7846 100644 --- a/modules/indexer/issues/bleve/bleve.go +++ b/modules/indexer/issues/bleve/bleve.go @@ -23,7 +23,7 @@ import ( const ( issueIndexerAnalyzer = "issueIndexer" issueIndexerDocType = "issueIndexerDocType" - issueIndexerLatestVersion = 2 + issueIndexerLatestVersion = 3 ) // numericEqualityQuery a numeric equality query for the given value and field @@ -45,7 +45,7 @@ func newMatchPhraseQuery(matchPhrase, field, analyzer string) *query.MatchPhrase const unicodeNormalizeName = "unicodeNormalize" func addUnicodeNormalizeTokenFilter(m *mapping.IndexMappingImpl) error { - return m.AddCustomTokenFilter(unicodeNormalizeName, map[string]interface{}{ + return m.AddCustomTokenFilter(unicodeNormalizeName, map[string]any{ "type": unicodenorm.Name, "form": unicodenorm.NFC, }) @@ -67,19 +67,20 @@ func generateIssueIndexMapping() (mapping.IndexMapping, error) { docMapping := bleve.NewDocumentMapping() numericFieldMapping := bleve.NewNumericFieldMapping() + numericFieldMapping.Store = false numericFieldMapping.IncludeInAll = false - docMapping.AddFieldMappingsAt("RepoID", numericFieldMapping) + docMapping.AddFieldMappingsAt("repo_id", numericFieldMapping) textFieldMapping := bleve.NewTextFieldMapping() textFieldMapping.Store = false textFieldMapping.IncludeInAll = false - docMapping.AddFieldMappingsAt("Title", textFieldMapping) - docMapping.AddFieldMappingsAt("Content", textFieldMapping) - docMapping.AddFieldMappingsAt("Comments", textFieldMapping) + docMapping.AddFieldMappingsAt("title", textFieldMapping) + docMapping.AddFieldMappingsAt("content", textFieldMapping) + docMapping.AddFieldMappingsAt("comments", textFieldMapping) if err := addUnicodeNormalizeTokenFilter(mapping); err != nil { return nil, err - } else if err = mapping.AddCustomAnalyzer(issueIndexerAnalyzer, map[string]interface{}{ + } else if err = mapping.AddCustomAnalyzer(issueIndexerAnalyzer, map[string]any{ "type": custom.Name, "char_filters": []string{}, "tokenizer": unicode.Name, @@ -91,6 +92,7 @@ func generateIssueIndexMapping() (mapping.IndexMapping, error) { mapping.DefaultAnalyzer = issueIndexerAnalyzer mapping.AddDocumentMapping(issueIndexerDocType, docMapping) mapping.AddDocumentMapping("_all", bleve.NewDocumentDisabledMapping()) + mapping.DefaultMapping = bleve.NewDocumentDisabledMapping() // disable default mapping, avoid indexing unexpected structs return mapping, nil } @@ -116,17 +118,7 @@ func NewIndexer(indexDir string) *Indexer { func (b *Indexer) Index(_ context.Context, issues []*internal.IndexerData) error { batch := inner_bleve.NewFlushingBatch(b.inner.Indexer, maxBatchSize) for _, issue := range issues { - if err := batch.Index(indexer_internal.Base36(issue.ID), struct { - RepoID int64 - Title string - Content string - Comments []string - }{ - RepoID: issue.RepoID, - Title: issue.Title, - Content: issue.Content, - Comments: issue.Comments, - }); err != nil { + if err := batch.Index(indexer_internal.Base36(issue.ID), (*IndexerData)(issue)); err != nil { return err } } @@ -149,7 +141,7 @@ func (b *Indexer) Delete(_ context.Context, ids ...int64) error { func (b *Indexer) Search(ctx context.Context, keyword string, repoIDs []int64, limit, start int) (*internal.SearchResult, error) { var repoQueriesP []*query.NumericRangeQuery for _, repoID := range repoIDs { - repoQueriesP = append(repoQueriesP, numericEqualityQuery(repoID, "RepoID")) + repoQueriesP = append(repoQueriesP, numericEqualityQuery(repoID, "repo_id")) } repoQueries := make([]query.Query, len(repoQueriesP)) for i, v := range repoQueriesP { @@ -159,9 +151,9 @@ func (b *Indexer) Search(ctx context.Context, keyword string, repoIDs []int64, l indexerQuery := bleve.NewConjunctionQuery( bleve.NewDisjunctionQuery(repoQueries...), bleve.NewDisjunctionQuery( - newMatchPhraseQuery(keyword, "Title", issueIndexerAnalyzer), - newMatchPhraseQuery(keyword, "Content", issueIndexerAnalyzer), - newMatchPhraseQuery(keyword, "Comments", issueIndexerAnalyzer), + newMatchPhraseQuery(keyword, "title", issueIndexerAnalyzer), + newMatchPhraseQuery(keyword, "content", issueIndexerAnalyzer), + newMatchPhraseQuery(keyword, "comments", issueIndexerAnalyzer), )) search := bleve.NewSearchRequestOptions(indexerQuery, limit, start, false) search.SortBy([]string{"-_score"}) diff --git a/modules/indexer/issues/elasticsearch/elasticsearch.go b/modules/indexer/issues/elasticsearch/elasticsearch.go index 33a7dfc21e0c7..62889ea578f67 100644 --- a/modules/indexer/issues/elasticsearch/elasticsearch.go +++ b/modules/indexer/issues/elasticsearch/elasticsearch.go @@ -76,7 +76,7 @@ func (b *Indexer) Index(ctx context.Context, issues []*internal.IndexerData) err _, err := b.inner.Client.Index(). Index(b.inner.VersionedIndexName()). Id(fmt.Sprintf("%d", issue.ID)). - BodyJson(map[string]interface{}{ + BodyJson(map[string]any{ "id": issue.ID, "repo_id": issue.RepoID, "title": issue.Title, @@ -93,7 +93,7 @@ func (b *Indexer) Index(ctx context.Context, issues []*internal.IndexerData) err elastic.NewBulkIndexRequest(). Index(b.inner.VersionedIndexName()). Id(fmt.Sprintf("%d", issue.ID)). - Doc(map[string]interface{}{ + Doc(map[string]any{ "id": issue.ID, "repo_id": issue.RepoID, "title": issue.Title, @@ -145,7 +145,7 @@ func (b *Indexer) Search(ctx context.Context, keyword string, repoIDs []int64, l query := elastic.NewBoolQuery() query = query.Must(kwQuery) if len(repoIDs) > 0 { - repoStrs := make([]interface{}, 0, len(repoIDs)) + repoStrs := make([]any, 0, len(repoIDs)) for _, repoID := range repoIDs { repoStrs = append(repoStrs, repoID) } diff --git a/modules/indexer/issues/meilisearch/meilisearch.go b/modules/indexer/issues/meilisearch/meilisearch.go index 877c04f1dcb2d..2a46b1ab15cfd 100644 --- a/modules/indexer/issues/meilisearch/meilisearch.go +++ b/modules/indexer/issues/meilisearch/meilisearch.go @@ -88,7 +88,7 @@ func (b *Indexer) Search(ctx context.Context, keyword string, repoIDs []int64, l hits := make([]internal.Match, 0, len(searchRes.Hits)) for _, hit := range searchRes.Hits { hits = append(hits, internal.Match{ - ID: int64(hit.(map[string]interface{})["id"].(float64)), + ID: int64(hit.(map[string]any)["id"].(float64)), }) } return &internal.SearchResult{ diff --git a/modules/issue/template/template.go b/modules/issue/template/template.go index 0f19d87e8d5dc..4e813fc91f786 100644 --- a/modules/issue/template/template.go +++ b/modules/issue/template/template.go @@ -151,7 +151,7 @@ func validateOptions(field *api.IssueFormField, idx int) error { } position := newErrorPosition(idx, field.Type) - options, ok := field.Attributes["options"].([]interface{}) + options, ok := field.Attributes["options"].([]any) if !ok || len(options) == 0 { return position.Errorf("'options' is required and should be a array") } @@ -164,7 +164,7 @@ func validateOptions(field *api.IssueFormField, idx int) error { return position.Errorf("should be a string") } case api.IssueFormFieldTypeCheckboxes: - opt, ok := option.(map[string]interface{}) + opt, ok := option.(map[string]any) if !ok { return position.Errorf("should be a dictionary") } @@ -182,7 +182,7 @@ func validateOptions(field *api.IssueFormField, idx int) error { return nil } -func validateStringItem(position errorPosition, m map[string]interface{}, required bool, names ...string) error { +func validateStringItem(position errorPosition, m map[string]any, required bool, names ...string) error { for _, name := range names { v, ok := m[name] if !ok { @@ -202,7 +202,7 @@ func validateStringItem(position errorPosition, m map[string]interface{}, requir return nil } -func validateBoolItem(position errorPosition, m map[string]interface{}, names ...string) error { +func validateBoolItem(position errorPosition, m map[string]any, names ...string) error { for _, name := range names { v, ok := m[name] if !ok { @@ -217,7 +217,7 @@ func validateBoolItem(position errorPosition, m map[string]interface{}, names .. type errorPosition string -func (p errorPosition) Errorf(format string, a ...interface{}) error { +func (p errorPosition) Errorf(format string, a ...any) error { return fmt.Errorf(string(p)+": "+format, a...) } @@ -332,7 +332,7 @@ func (f *valuedField) Value() string { } func (f *valuedField) Options() []*valuedOption { - if options, ok := f.Attributes["options"].([]interface{}); ok { + if options, ok := f.Attributes["options"].([]any); ok { ret := make([]*valuedOption, 0, len(options)) for i, option := range options { ret = append(ret, &valuedOption{ @@ -348,7 +348,7 @@ func (f *valuedField) Options() []*valuedOption { type valuedOption struct { index int - data interface{} + data any field *valuedField } @@ -359,7 +359,7 @@ func (o *valuedOption) Label() string { return label } case api.IssueFormFieldTypeCheckboxes: - if vs, ok := o.data.(map[string]interface{}); ok { + if vs, ok := o.data.(map[string]any); ok { if v, ok := vs["label"].(string); ok { return v } diff --git a/modules/issue/template/template_test.go b/modules/issue/template/template_test.go index 0cdddd0c85f9d..06e6b70d35f64 100644 --- a/modules/issue/template/template_test.go +++ b/modules/issue/template/template_test.go @@ -387,34 +387,34 @@ body: { Type: "markdown", ID: "id1", - Attributes: map[string]interface{}{ + Attributes: map[string]any{ "value": "Value of the markdown", }, }, { Type: "textarea", ID: "id2", - Attributes: map[string]interface{}{ + Attributes: map[string]any{ "label": "Label of textarea", "description": "Description of textarea", "placeholder": "Placeholder of textarea", "value": "Value of textarea", "render": "bash", }, - Validations: map[string]interface{}{ + Validations: map[string]any{ "required": true, }, }, { Type: "input", ID: "id3", - Attributes: map[string]interface{}{ + Attributes: map[string]any{ "label": "Label of input", "description": "Description of input", "placeholder": "Placeholder of input", "value": "Value of input", }, - Validations: map[string]interface{}{ + Validations: map[string]any{ "required": true, "is_number": true, "regex": "[a-zA-Z0-9]+", @@ -423,30 +423,30 @@ body: { Type: "dropdown", ID: "id4", - Attributes: map[string]interface{}{ + Attributes: map[string]any{ "label": "Label of dropdown", "description": "Description of dropdown", "multiple": true, - "options": []interface{}{ + "options": []any{ "Option 1 of dropdown", "Option 2 of dropdown", "Option 3 of dropdown", }, }, - Validations: map[string]interface{}{ + Validations: map[string]any{ "required": true, }, }, { Type: "checkboxes", ID: "id5", - Attributes: map[string]interface{}{ + Attributes: map[string]any{ "label": "Label of checkboxes", "description": "Description of checkboxes", - "options": []interface{}{ - map[string]interface{}{"label": "Option 1 of checkboxes", "required": true}, - map[string]interface{}{"label": "Option 2 of checkboxes", "required": false}, - map[string]interface{}{"label": "Option 3 of checkboxes", "required": true}, + "options": []any{ + map[string]any{"label": "Option 1 of checkboxes", "required": true}, + map[string]any{"label": "Option 2 of checkboxes", "required": false}, + map[string]any{"label": "Option 3 of checkboxes", "required": true}, }, }, }, @@ -479,7 +479,7 @@ body: { Type: "markdown", ID: "id1", - Attributes: map[string]interface{}{ + Attributes: map[string]any{ "value": "Value of the markdown", }, }, @@ -512,7 +512,7 @@ body: { Type: "markdown", ID: "id1", - Attributes: map[string]interface{}{ + Attributes: map[string]any{ "value": "Value of the markdown", }, }, @@ -545,7 +545,7 @@ body: { Type: "markdown", ID: "id1", - Attributes: map[string]interface{}{ + Attributes: map[string]any{ "value": "Value of the markdown", }, }, diff --git a/modules/json/json.go b/modules/json/json.go index 5f8c474e05264..34568c75c6e4b 100644 --- a/modules/json/json.go +++ b/modules/json/json.go @@ -15,18 +15,18 @@ import ( // Encoder represents an encoder for json type Encoder interface { - Encode(v interface{}) error + Encode(v any) error } // Decoder represents a decoder for json type Decoder interface { - Decode(v interface{}) error + Decode(v any) error } // Interface represents an interface to handle json data type Interface interface { - Marshal(v interface{}) ([]byte, error) - Unmarshal(data []byte, v interface{}) error + Marshal(v any) ([]byte, error) + Unmarshal(data []byte, v any) error NewEncoder(writer io.Writer) Encoder NewDecoder(reader io.Reader) Decoder Indent(dst *bytes.Buffer, src []byte, prefix, indent string) error @@ -44,12 +44,12 @@ var ( type StdJSON struct{} // Marshal implements Interface -func (StdJSON) Marshal(v interface{}) ([]byte, error) { +func (StdJSON) Marshal(v any) ([]byte, error) { return json.Marshal(v) } // Unmarshal implements Interface -func (StdJSON) Unmarshal(data []byte, v interface{}) error { +func (StdJSON) Unmarshal(data []byte, v any) error { return json.Unmarshal(data, v) } @@ -74,12 +74,12 @@ type JSONiter struct { } // Marshal implements Interface -func (j JSONiter) Marshal(v interface{}) ([]byte, error) { +func (j JSONiter) Marshal(v any) ([]byte, error) { return j.API.Marshal(v) } // Unmarshal implements Interface -func (j JSONiter) Unmarshal(data []byte, v interface{}) error { +func (j JSONiter) Unmarshal(data []byte, v any) error { return j.API.Unmarshal(data, v) } @@ -99,12 +99,12 @@ func (j JSONiter) Indent(dst *bytes.Buffer, src []byte, prefix, indent string) e } // Marshal converts object as bytes -func Marshal(v interface{}) ([]byte, error) { +func Marshal(v any) ([]byte, error) { return DefaultJSONHandler.Marshal(v) } // Unmarshal decodes object from bytes -func Unmarshal(data []byte, v interface{}) error { +func Unmarshal(data []byte, v any) error { return DefaultJSONHandler.Unmarshal(data, v) } @@ -124,7 +124,7 @@ func Indent(dst *bytes.Buffer, src []byte, prefix, indent string) error { } // MarshalIndent copied from encoding/json -func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) { +func MarshalIndent(v any, prefix, indent string) ([]byte, error) { b, err := Marshal(v) if err != nil { return nil, err @@ -144,7 +144,7 @@ func Valid(data []byte) bool { // UnmarshalHandleDoubleEncode - due to a bug in xorm (see https://gitea.com/xorm/xorm/pulls/1957) - it's // possible that a Blob may be double encoded or gain an unwanted prefix of 0xff 0xfe. -func UnmarshalHandleDoubleEncode(bs []byte, v interface{}) error { +func UnmarshalHandleDoubleEncode(bs []byte, v any) error { err := json.Unmarshal(bs, v) if err != nil { ok := true diff --git a/modules/markup/html_internal_test.go b/modules/markup/html_internal_test.go index 7e04b03531d87..00ffe45c285b3 100644 --- a/modules/markup/html_internal_test.go +++ b/modules/markup/html_internal_test.go @@ -120,7 +120,7 @@ func TestRender_IssueIndexPattern2(t *testing.T) { isExternal = true } - links := make([]interface{}, len(indices)) + links := make([]any, len(indices)) for i, index := range indices { links[i] = numericIssueLink(util.URLJoin(TestRepoURL, path), "ref-issue", index, marker) } @@ -204,7 +204,7 @@ func TestRender_IssueIndexPattern4(t *testing.T) { // alphanumeric: render inputs with valid mentions test := func(s, expectedFmt string, names ...string) { - links := make([]interface{}, len(names)) + links := make([]any, len(names)) for i, name := range names { links[i] = externalIssueLink("https://someurl.com/someUser/someRepo/", "ref-issue ref-external-issue", name) } @@ -226,7 +226,7 @@ func TestRender_IssueIndexPattern5(t *testing.T) { test := func(s, expectedFmt, pattern string, ids, names []string) { metas := regexpMetas metas["regexp"] = pattern - links := make([]interface{}, len(ids)) + links := make([]any, len(ids)) for i, id := range ids { links[i] = link(util.URLJoin("https://someurl.com/someUser/someRepo/", id), "ref-issue ref-external-issue", names[i]) } diff --git a/modules/markup/markdown/meta.go b/modules/markup/markdown/meta.go index bbefbd380c255..e76b253ecd263 100644 --- a/modules/markup/markdown/meta.go +++ b/modules/markup/markdown/meta.go @@ -55,14 +55,14 @@ func isYAMLSeparator(line []byte) bool { // ExtractMetadata consumes a markdown file, parses YAML frontmatter, // and returns the frontmatter metadata separated from the markdown content -func ExtractMetadata(contents string, out interface{}) (string, error) { +func ExtractMetadata(contents string, out any) (string, error) { body, err := ExtractMetadataBytes([]byte(contents), out) return string(body), err } // ExtractMetadata consumes a markdown file, parses YAML frontmatter, // and returns the frontmatter metadata separated from the markdown content -func ExtractMetadataBytes(contents []byte, out interface{}) ([]byte, error) { +func ExtractMetadataBytes(contents []byte, out any) ([]byte, error) { var front, body []byte start, end := 0, len(contents) diff --git a/modules/migration/comment.go b/modules/migration/comment.go index 92ce30e302023..e041758467d46 100644 --- a/modules/migration/comment.go +++ b/modules/migration/comment.go @@ -24,7 +24,7 @@ type Comment struct { Updated time.Time Content string Reactions []*Reaction - Meta map[string]interface{} `yaml:"meta,omitempty"` // see models/issues/comment.go for fields in Comment struct + Meta map[string]any `yaml:"meta,omitempty"` // see models/issues/comment.go for fields in Comment struct } // GetExternalName ExternalUserMigrated interface diff --git a/modules/migration/downloader.go b/modules/migration/downloader.go index ebd3672d63699..08dbbc29a9958 100644 --- a/modules/migration/downloader.go +++ b/modules/migration/downloader.go @@ -34,4 +34,4 @@ type DownloaderFactory interface { } // DownloaderContext has opaque information only relevant to a given downloader -type DownloaderContext interface{} +type DownloaderContext any diff --git a/modules/migration/file_format.go b/modules/migration/file_format.go index 04e5d76981336..e8b6891ca118f 100644 --- a/modules/migration/file_format.go +++ b/modules/migration/file_format.go @@ -17,7 +17,7 @@ import ( ) // Load project data from file, with optional validation -func Load(filename string, data interface{}, validation bool) error { +func Load(filename string, data any, validation bool) error { isJSON := strings.HasSuffix(filename, ".json") bs, err := os.ReadFile(filename) @@ -34,7 +34,7 @@ func Load(filename string, data interface{}, validation bool) error { return unmarshal(bs, data, isJSON) } -func unmarshal(bs []byte, data interface{}, isJSON bool) error { +func unmarshal(bs []byte, data any, isJSON bool) error { if isJSON { return json.Unmarshal(bs, data) } @@ -47,8 +47,8 @@ func getSchema(filename string) (*jsonschema.Schema, error) { return c.Compile(filename) } -func validate(bs []byte, datatype interface{}, isJSON bool) error { - var v interface{} +func validate(bs []byte, datatype any, isJSON bool) error { + var v any err := unmarshal(bs, &v, isJSON) if err != nil { return err @@ -81,11 +81,11 @@ func validate(bs []byte, datatype interface{}, isJSON bool) error { return err } -func toStringKeys(val interface{}) (interface{}, error) { +func toStringKeys(val any) (any, error) { var err error switch val := val.(type) { - case map[string]interface{}: - m := make(map[string]interface{}) + case map[string]any: + m := make(map[string]any) for k, v := range val { m[k], err = toStringKeys(v) if err != nil { @@ -93,8 +93,8 @@ func toStringKeys(val interface{}) (interface{}, error) { } } return m, nil - case []interface{}: - l := make([]interface{}, len(val)) + case []any: + l := make([]any, len(val)) for i, v := range val { l[i], err = toStringKeys(v) if err != nil { diff --git a/modules/migration/messenger.go b/modules/migration/messenger.go index 1fd5456259ea4..924aac976943c 100644 --- a/modules/migration/messenger.go +++ b/modules/migration/messenger.go @@ -4,7 +4,7 @@ package migration // Messenger is a formatting function similar to i18n.Tr -type Messenger func(key string, args ...interface{}) +type Messenger func(key string, args ...any) // NilMessenger represents an empty formatting function -func NilMessenger(string, ...interface{}) {} +func NilMessenger(string, ...any) {} diff --git a/modules/nosql/manager_leveldb.go b/modules/nosql/manager_leveldb.go index 078a8028116f8..4d2c90debc66b 100644 --- a/modules/nosql/manager_leveldb.go +++ b/modules/nosql/manager_leveldb.go @@ -54,7 +54,7 @@ func (m *Manager) GetLevelDB(connection string) (db *leveldb.DB, err error) { // Because we want associate any goroutines created by this call to the main nosqldb context we need to // wrap this in a goroutine labelled with the nosqldb context done := make(chan struct{}) - var recovered interface{} + var recovered any go func() { defer func() { recovered = recover() diff --git a/modules/nosql/manager_redis.go b/modules/nosql/manager_redis.go index 7066863b89f8f..3c82651541f2c 100644 --- a/modules/nosql/manager_redis.go +++ b/modules/nosql/manager_redis.go @@ -47,7 +47,7 @@ func (m *Manager) GetRedisClient(connection string) (client redis.UniversalClien // Because we want associate any goroutines created by this call to the main nosqldb context we need to // wrap this in a goroutine labelled with the nosqldb context done := make(chan struct{}) - var recovered interface{} + var recovered any go func() { defer func() { recovered = recover() diff --git a/modules/packages/composer/metadata.go b/modules/packages/composer/metadata.go index 36b0b8e421974..1d0f025648896 100644 --- a/modules/packages/composer/metadata.go +++ b/modules/packages/composer/metadata.go @@ -38,18 +38,18 @@ type Package struct { // Metadata represents the metadata of a Composer package type Metadata struct { - Description string `json:"description,omitempty"` - Keywords []string `json:"keywords,omitempty"` - Homepage string `json:"homepage,omitempty"` - License Licenses `json:"license,omitempty"` - Authors []Author `json:"authors,omitempty"` - Autoload map[string]interface{} `json:"autoload,omitempty"` - AutoloadDev map[string]interface{} `json:"autoload-dev,omitempty"` - Extra map[string]interface{} `json:"extra,omitempty"` - Require map[string]string `json:"require,omitempty"` - RequireDev map[string]string `json:"require-dev,omitempty"` - Suggest map[string]string `json:"suggest,omitempty"` - Provide map[string]string `json:"provide,omitempty"` + Description string `json:"description,omitempty"` + Keywords []string `json:"keywords,omitempty"` + Homepage string `json:"homepage,omitempty"` + License Licenses `json:"license,omitempty"` + Authors []Author `json:"authors,omitempty"` + Autoload map[string]any `json:"autoload,omitempty"` + AutoloadDev map[string]any `json:"autoload-dev,omitempty"` + Extra map[string]any `json:"extra,omitempty"` + Require map[string]string `json:"require,omitempty"` + RequireDev map[string]string `json:"require-dev,omitempty"` + Suggest map[string]string `json:"suggest,omitempty"` + Provide map[string]string `json:"provide,omitempty"` } // Licenses represents the licenses of a Composer package diff --git a/modules/packages/content_store.go b/modules/packages/content_store.go index 1181fa4d528be..da93e6cf6bcbb 100644 --- a/modules/packages/content_store.go +++ b/modules/packages/content_store.go @@ -5,9 +5,11 @@ package packages import ( "io" + "net/url" "path" "strings" + "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/storage" "code.gitea.io/gitea/modules/util" ) @@ -31,6 +33,14 @@ func (s *ContentStore) Get(key BlobHash256Key) (storage.Object, error) { return s.store.Open(KeyToRelativePath(key)) } +func (s *ContentStore) ShouldServeDirect() bool { + return setting.Packages.Storage.MinioConfig.ServeDirect +} + +func (s *ContentStore) GetServeDirectURL(key BlobHash256Key, filename string) (*url.URL, error) { + return s.store.URL(KeyToRelativePath(key), filename) +} + // FIXME: Workaround to be removed in v1.20 // https://github.com/go-gitea/gitea/issues/19586 func (s *ContentStore) Has(key BlobHash256Key) error { diff --git a/modules/packages/helm/metadata.go b/modules/packages/helm/metadata.go index fdbd9003b84c2..421fc5e7259ca 100644 --- a/modules/packages/helm/metadata.go +++ b/modules/packages/helm/metadata.go @@ -55,14 +55,14 @@ type Maintainer struct { } type Dependency struct { - Name string `json:"name" yaml:"name"` - Version string `json:"version,omitempty" yaml:"version,omitempty"` - Repository string `json:"repository" yaml:"repository"` - Condition string `json:"condition,omitempty" yaml:"condition,omitempty"` - Tags []string `json:"tags,omitempty" yaml:"tags,omitempty"` - Enabled bool `json:"enabled,omitempty" yaml:"enabled,omitempty"` - ImportValues []interface{} `json:"import_values,omitempty" yaml:"import-values,omitempty"` - Alias string `json:"alias,omitempty" yaml:"alias,omitempty"` + Name string `json:"name" yaml:"name"` + Version string `json:"version,omitempty" yaml:"version,omitempty"` + Repository string `json:"repository" yaml:"repository"` + Condition string `json:"condition,omitempty" yaml:"condition,omitempty"` + Tags []string `json:"tags,omitempty" yaml:"tags,omitempty"` + Enabled bool `json:"enabled,omitempty" yaml:"enabled,omitempty"` + ImportValues []any `json:"import_values,omitempty" yaml:"import-values,omitempty"` + Alias string `json:"alias,omitempty" yaml:"alias,omitempty"` } // ParseChartArchive parses the metadata of a Helm archive diff --git a/modules/packages/pub/metadata.go b/modules/packages/pub/metadata.go index 13a066afacc9d..afb464e462057 100644 --- a/modules/packages/pub/metadata.go +++ b/modules/packages/pub/metadata.go @@ -38,12 +38,12 @@ type Package struct { // Metadata represents the metadata of a Pub package type Metadata struct { - Description string `json:"description,omitempty"` - ProjectURL string `json:"project_url,omitempty"` - RepositoryURL string `json:"repository_url,omitempty"` - DocumentationURL string `json:"documentation_url,omitempty"` - Readme string `json:"readme,omitempty"` - Pubspec interface{} `json:"pubspec"` + Description string `json:"description,omitempty"` + ProjectURL string `json:"project_url,omitempty"` + RepositoryURL string `json:"repository_url,omitempty"` + DocumentationURL string `json:"documentation_url,omitempty"` + Readme string `json:"readme,omitempty"` + Pubspec any `json:"pubspec"` } type pubspecPackage struct { @@ -134,7 +134,7 @@ func ParsePubspecMetadata(r io.Reader) (*Package, error) { p.Repository = "" } - var pubspec interface{} + var pubspec any if err := yaml.Unmarshal(buf, &pubspec); err != nil { return nil, err } diff --git a/modules/packages/rubygems/marshal.go b/modules/packages/rubygems/marshal.go index efb2ba34a4921..8878dcf9732f5 100644 --- a/modules/packages/rubygems/marshal.go +++ b/modules/packages/rubygems/marshal.go @@ -40,19 +40,19 @@ var ( // RubyUserMarshal is a Ruby object that has a marshal_load function. type RubyUserMarshal struct { Name string - Value interface{} + Value any } // RubyUserDef is a Ruby object that has a _load function. type RubyUserDef struct { Name string - Value interface{} + Value any } // RubyObject is a default Ruby object. type RubyObject struct { Name string - Member map[string]interface{} + Member map[string]any } // MarshalEncoder mimics Rubys Marshal class. @@ -71,7 +71,7 @@ func NewMarshalEncoder(w io.Writer) *MarshalEncoder { } // Encode encodes the given type -func (e *MarshalEncoder) Encode(v interface{}) error { +func (e *MarshalEncoder) Encode(v any) error { if _, err := e.w.Write([]byte{majorVersion, minorVersion}); err != nil { return err } @@ -83,7 +83,7 @@ func (e *MarshalEncoder) Encode(v interface{}) error { return e.w.Flush() } -func (e *MarshalEncoder) marshal(v interface{}) error { +func (e *MarshalEncoder) marshal(v any) error { if v == nil { return e.marshalNil() } diff --git a/modules/packages/rubygems/marshal_test.go b/modules/packages/rubygems/marshal_test.go index 501757bfeda67..6d2354cd876ca 100644 --- a/modules/packages/rubygems/marshal_test.go +++ b/modules/packages/rubygems/marshal_test.go @@ -12,7 +12,7 @@ import ( func TestMinimalEncoder(t *testing.T) { cases := []struct { - Value interface{} + Value any Expected []byte Error error }{ @@ -73,7 +73,7 @@ func TestMinimalEncoder(t *testing.T) { { Value: &RubyObject{ Name: "Test", - Member: map[string]interface{}{ + Member: map[string]any{ "test": 4, }, }, diff --git a/modules/packages/rubygems/metadata.go b/modules/packages/rubygems/metadata.go index adc1c05808740..8a9794860ebfb 100644 --- a/modules/packages/rubygems/metadata.go +++ b/modules/packages/rubygems/metadata.go @@ -65,12 +65,12 @@ type gemspec struct { Version struct { Version string `yaml:"version"` } `yaml:"version"` - Platform string `yaml:"platform"` - Authors []string `yaml:"authors"` - Autorequire interface{} `yaml:"autorequire"` - Bindir string `yaml:"bindir"` - CertChain []interface{} `yaml:"cert_chain"` - Date string `yaml:"date"` + Platform string `yaml:"platform"` + Authors []string `yaml:"authors"` + Autorequire any `yaml:"autorequire"` + Bindir string `yaml:"bindir"` + CertChain []any `yaml:"cert_chain"` + Date string `yaml:"date"` Dependencies []struct { Name string `yaml:"name"` Requirement requirement `yaml:"requirement"` @@ -78,34 +78,34 @@ type gemspec struct { Prerelease bool `yaml:"prerelease"` VersionRequirements requirement `yaml:"version_requirements"` } `yaml:"dependencies"` - Description string `yaml:"description"` - Executables []string `yaml:"executables"` - Extensions []interface{} `yaml:"extensions"` - ExtraRdocFiles []string `yaml:"extra_rdoc_files"` - Files []string `yaml:"files"` - Homepage string `yaml:"homepage"` - Licenses []string `yaml:"licenses"` + Description string `yaml:"description"` + Executables []string `yaml:"executables"` + Extensions []any `yaml:"extensions"` + ExtraRdocFiles []string `yaml:"extra_rdoc_files"` + Files []string `yaml:"files"` + Homepage string `yaml:"homepage"` + Licenses []string `yaml:"licenses"` Metadata struct { BugTrackerURI string `yaml:"bug_tracker_uri"` ChangelogURI string `yaml:"changelog_uri"` DocumentationURI string `yaml:"documentation_uri"` SourceCodeURI string `yaml:"source_code_uri"` } `yaml:"metadata"` - PostInstallMessage interface{} `yaml:"post_install_message"` - RdocOptions []interface{} `yaml:"rdoc_options"` - RequirePaths []string `yaml:"require_paths"` - RequiredRubyVersion requirement `yaml:"required_ruby_version"` - RequiredRubygemsVersion requirement `yaml:"required_rubygems_version"` - Requirements []interface{} `yaml:"requirements"` - RubygemsVersion string `yaml:"rubygems_version"` - SigningKey interface{} `yaml:"signing_key"` - SpecificationVersion int `yaml:"specification_version"` - Summary string `yaml:"summary"` - TestFiles []interface{} `yaml:"test_files"` + PostInstallMessage any `yaml:"post_install_message"` + RdocOptions []any `yaml:"rdoc_options"` + RequirePaths []string `yaml:"require_paths"` + RequiredRubyVersion requirement `yaml:"required_ruby_version"` + RequiredRubygemsVersion requirement `yaml:"required_rubygems_version"` + Requirements []any `yaml:"requirements"` + RubygemsVersion string `yaml:"rubygems_version"` + SigningKey any `yaml:"signing_key"` + SpecificationVersion int `yaml:"specification_version"` + Summary string `yaml:"summary"` + TestFiles []any `yaml:"test_files"` } type requirement struct { - Requirements [][]interface{} `yaml:"requirements"` + Requirements [][]any `yaml:"requirements"` } // AsVersionRequirement converts into []VersionRequirement @@ -119,7 +119,7 @@ func (r requirement) AsVersionRequirement() []VersionRequirement { if !ok { continue } - vm, ok := req[1].(map[string]interface{}) + vm, ok := req[1].(map[string]any) if !ok { continue } diff --git a/modules/private/manager.go b/modules/private/manager.go index 382986bf1db11..6055e553bd0f0 100644 --- a/modules/private/manager.go +++ b/modules/private/manager.go @@ -85,11 +85,11 @@ type LoggerOptions struct { Logger string Writer string Mode string - Config map[string]interface{} + Config map[string]any } // AddLogger adds a logger -func AddLogger(ctx context.Context, logger, writer, mode string, config map[string]interface{}) ResponseExtra { +func AddLogger(ctx context.Context, logger, writer, mode string, config map[string]any) ResponseExtra { reqURL := setting.LocalURL + "api/internal/manager/add-logger" req := newInternalRequest(ctx, reqURL, "POST", LoggerOptions{ Logger: logger, diff --git a/modules/process/context.go b/modules/process/context.go index f1bc582ff069c..26a80ebd6207c 100644 --- a/modules/process/context.go +++ b/modules/process/context.go @@ -24,7 +24,7 @@ func (c *Context) GetParent() *Context { } // Value is part of the interface for context.Context. We mostly defer to the internal context - but we return this in response to the ProcessContextKey -func (c *Context) Value(key interface{}) interface{} { +func (c *Context) Value(key any) any { if key == ProcessContextKey { return c } @@ -32,7 +32,7 @@ func (c *Context) Value(key interface{}) interface{} { } // ProcessContextKey is the key under which process contexts are stored -var ProcessContextKey interface{} = "process-context" +var ProcessContextKey any = "process-context" // GetContext will return a process context if one exists func GetContext(ctx context.Context) *Context { diff --git a/modules/session/db.go b/modules/session/db.go index 6fdfb81e03189..f86f7d1e9cf9e 100644 --- a/modules/session/db.go +++ b/modules/session/db.go @@ -17,11 +17,11 @@ import ( type DBStore struct { sid string lock sync.RWMutex - data map[interface{}]interface{} + data map[any]any } // NewDBStore creates and returns a DB session store. -func NewDBStore(sid string, kv map[interface{}]interface{}) *DBStore { +func NewDBStore(sid string, kv map[any]any) *DBStore { return &DBStore{ sid: sid, data: kv, @@ -29,7 +29,7 @@ func NewDBStore(sid string, kv map[interface{}]interface{}) *DBStore { } // Set sets value to given key in session. -func (s *DBStore) Set(key, val interface{}) error { +func (s *DBStore) Set(key, val any) error { s.lock.Lock() defer s.lock.Unlock() @@ -38,7 +38,7 @@ func (s *DBStore) Set(key, val interface{}) error { } // Get gets value by given key in session. -func (s *DBStore) Get(key interface{}) interface{} { +func (s *DBStore) Get(key any) any { s.lock.RLock() defer s.lock.RUnlock() @@ -46,7 +46,7 @@ func (s *DBStore) Get(key interface{}) interface{} { } // Delete delete a key from session. -func (s *DBStore) Delete(key interface{}) error { +func (s *DBStore) Delete(key any) error { s.lock.Lock() defer s.lock.Unlock() @@ -79,7 +79,7 @@ func (s *DBStore) Flush() error { s.lock.Lock() defer s.lock.Unlock() - s.data = make(map[interface{}]interface{}) + s.data = make(map[any]any) return nil } @@ -102,9 +102,9 @@ func (p *DBProvider) Read(sid string) (session.RawStore, error) { return nil, err } - var kv map[interface{}]interface{} + var kv map[any]any if len(s.Data) == 0 || s.Expiry.Add(p.maxLifetime) <= timeutil.TimeStampNow() { - kv = make(map[interface{}]interface{}) + kv = make(map[any]any) } else { kv, err = session.DecodeGob(s.Data) if err != nil { @@ -136,9 +136,9 @@ func (p *DBProvider) Regenerate(oldsid, sid string) (_ session.RawStore, err err return nil, err } - var kv map[interface{}]interface{} + var kv map[any]any if len(s.Data) == 0 || s.Expiry.Add(p.maxLifetime) <= timeutil.TimeStampNow() { - kv = make(map[interface{}]interface{}) + kv = make(map[any]any) } else { kv, err = session.DecodeGob(s.Data) if err != nil { diff --git a/modules/session/redis.go b/modules/session/redis.go index 322470743a510..d89d8bc6e2100 100644 --- a/modules/session/redis.go +++ b/modules/session/redis.go @@ -35,11 +35,11 @@ type RedisStore struct { prefix, sid string duration time.Duration lock sync.RWMutex - data map[interface{}]interface{} + data map[any]any } // NewRedisStore creates and returns a redis session store. -func NewRedisStore(c redis.UniversalClient, prefix, sid string, dur time.Duration, kv map[interface{}]interface{}) *RedisStore { +func NewRedisStore(c redis.UniversalClient, prefix, sid string, dur time.Duration, kv map[any]any) *RedisStore { return &RedisStore{ c: c, prefix: prefix, @@ -50,7 +50,7 @@ func NewRedisStore(c redis.UniversalClient, prefix, sid string, dur time.Duratio } // Set sets value to given key in session. -func (s *RedisStore) Set(key, val interface{}) error { +func (s *RedisStore) Set(key, val any) error { s.lock.Lock() defer s.lock.Unlock() @@ -59,7 +59,7 @@ func (s *RedisStore) Set(key, val interface{}) error { } // Get gets value by given key in session. -func (s *RedisStore) Get(key interface{}) interface{} { +func (s *RedisStore) Get(key any) any { s.lock.RLock() defer s.lock.RUnlock() @@ -67,7 +67,7 @@ func (s *RedisStore) Get(key interface{}) interface{} { } // Delete delete a key from session. -func (s *RedisStore) Delete(key interface{}) error { +func (s *RedisStore) Delete(key any) error { s.lock.Lock() defer s.lock.Unlock() @@ -100,7 +100,7 @@ func (s *RedisStore) Flush() error { s.lock.Lock() defer s.lock.Unlock() - s.data = make(map[interface{}]interface{}) + s.data = make(map[any]any) return nil } @@ -141,13 +141,13 @@ func (p *RedisProvider) Read(sid string) (session.RawStore, error) { } } - var kv map[interface{}]interface{} + var kv map[any]any kvs, err := p.c.Get(graceful.GetManager().HammerContext(), psid).Result() if err != nil { return nil, err } if len(kvs) == 0 { - kv = make(map[interface{}]interface{}) + kv = make(map[any]any) } else { kv, err = session.DecodeGob([]byte(kvs)) if err != nil { @@ -197,9 +197,9 @@ func (p *RedisProvider) Regenerate(oldsid, sid string) (_ session.RawStore, err return nil, err } - var kv map[interface{}]interface{} + var kv map[any]any if len(kvs) == 0 { - kv = make(map[interface{}]interface{}) + kv = make(map[any]any) } else { kv, err = session.DecodeGob([]byte(kvs)) if err != nil { diff --git a/modules/session/store.go b/modules/session/store.go index 7b0c550ace397..4fa4d2848f1b8 100644 --- a/modules/session/store.go +++ b/modules/session/store.go @@ -11,9 +11,9 @@ import ( // Store represents a session store type Store interface { - Get(interface{}) interface{} - Set(interface{}, interface{}) error - Delete(interface{}) error + Get(any) any + Set(any, any) error + Delete(any) error } // RegenerateSession regenerates the underlying session and returns the new store diff --git a/modules/session/virtual.go b/modules/session/virtual.go index fcbc44249dc78..80352b6e721de 100644 --- a/modules/session/virtual.go +++ b/modules/session/virtual.go @@ -62,7 +62,7 @@ func (o *VirtualSessionProvider) Read(sid string) (session.RawStore, error) { if o.provider.Exist(sid) { return o.provider.Read(sid) } - kv := make(map[interface{}]interface{}) + kv := make(map[any]any) kv["_old_uid"] = "0" return NewVirtualStore(o, sid, kv), nil } @@ -107,12 +107,12 @@ type VirtualStore struct { p *VirtualSessionProvider sid string lock sync.RWMutex - data map[interface{}]interface{} + data map[any]any released bool } // NewVirtualStore creates and returns a virtual session store. -func NewVirtualStore(p *VirtualSessionProvider, sid string, kv map[interface{}]interface{}) *VirtualStore { +func NewVirtualStore(p *VirtualSessionProvider, sid string, kv map[any]any) *VirtualStore { return &VirtualStore{ p: p, sid: sid, @@ -121,7 +121,7 @@ func NewVirtualStore(p *VirtualSessionProvider, sid string, kv map[interface{}]i } // Set sets value to given key in session. -func (s *VirtualStore) Set(key, val interface{}) error { +func (s *VirtualStore) Set(key, val any) error { s.lock.Lock() defer s.lock.Unlock() @@ -130,7 +130,7 @@ func (s *VirtualStore) Set(key, val interface{}) error { } // Get gets value by given key in session. -func (s *VirtualStore) Get(key interface{}) interface{} { +func (s *VirtualStore) Get(key any) any { s.lock.RLock() defer s.lock.RUnlock() @@ -138,7 +138,7 @@ func (s *VirtualStore) Get(key interface{}) interface{} { } // Delete delete a key from session. -func (s *VirtualStore) Delete(key interface{}) error { +func (s *VirtualStore) Delete(key any) error { s.lock.Lock() defer s.lock.Unlock() @@ -192,6 +192,6 @@ func (s *VirtualStore) Flush() error { s.lock.Lock() defer s.lock.Unlock() - s.data = make(map[interface{}]interface{}) + s.data = make(map[any]any) return nil } diff --git a/modules/setting/cron.go b/modules/setting/cron.go index 45bae4dde37a9..7c4cc44288597 100644 --- a/modules/setting/cron.go +++ b/modules/setting/cron.go @@ -6,11 +6,11 @@ package setting import "reflect" // GetCronSettings maps the cron subsection to the provided config -func GetCronSettings(name string, config interface{}) (interface{}, error) { +func GetCronSettings(name string, config any) (any, error) { return getCronSettings(CfgProvider, name, config) } -func getCronSettings(rootCfg ConfigProvider, name string, config interface{}) (interface{}, error) { +func getCronSettings(rootCfg ConfigProvider, name string, config any) (any, error) { if err := rootCfg.Section("cron." + name).MapTo(config); err != nil { return config, err } diff --git a/modules/setting/log_test.go b/modules/setting/log_test.go index c07651f5488fa..87b14f0b1d8d7 100644 --- a/modules/setting/log_test.go +++ b/modules/setting/log_test.go @@ -30,7 +30,7 @@ func initLoggersByConfig(t *testing.T, config string) (*log.LoggerManager, func( return manager, manager.Close } -func toJSON(v interface{}) string { +func toJSON(v any) string { b, _ := json.MarshalIndent(v, "", "\t") return string(b) } diff --git a/modules/storage/minio.go b/modules/storage/minio.go index 81774fb9cfada..e2ce09d07a516 100644 --- a/modules/storage/minio.go +++ b/modules/storage/minio.go @@ -173,7 +173,7 @@ func (m minioFileInfo) Mode() os.FileMode { return os.ModePerm } -func (m minioFileInfo) Sys() interface{} { +func (m minioFileInfo) Sys() any { return nil } diff --git a/modules/storage/storage.go b/modules/storage/storage.go index c3396f0c7fbd3..8f970b5dfccc9 100644 --- a/modules/storage/storage.go +++ b/modules/storage/storage.go @@ -20,7 +20,7 @@ var ErrURLNotSupported = errors.New("url method not supported") // ErrInvalidConfiguration is called when there is invalid configuration for a storage type ErrInvalidConfiguration struct { - cfg interface{} + cfg any err error } diff --git a/modules/structs/issue.go b/modules/structs/issue.go index a9fb6c6e797b2..1aec5cc6b86c8 100644 --- a/modules/structs/issue.go +++ b/modules/structs/issue.go @@ -140,10 +140,10 @@ const ( // IssueFormField represents a form field // swagger:model type IssueFormField struct { - Type IssueFormFieldType `json:"type" yaml:"type"` - ID string `json:"id" yaml:"id"` - Attributes map[string]interface{} `json:"attributes" yaml:"attributes"` - Validations map[string]interface{} `json:"validations" yaml:"validations"` + Type IssueFormFieldType `json:"type" yaml:"type"` + ID string `json:"id" yaml:"id"` + Attributes map[string]any `json:"attributes" yaml:"attributes"` + Validations map[string]any `json:"validations" yaml:"validations"` } // IssueTemplate represents an issue template for a repository diff --git a/modules/structs/repo_file.go b/modules/structs/repo_file.go index 48fcebe6f877d..eb4f1c7dca57e 100644 --- a/modules/structs/repo_file.go +++ b/modules/structs/repo_file.go @@ -166,7 +166,7 @@ type FilesResponse struct { // FileDeleteResponse contains information about a repo's file that was deleted type FileDeleteResponse struct { - Content interface{} `json:"content"` // to be set to nil + Content any `json:"content"` // to be set to nil Commit *FileCommitResponse `json:"commit"` Verification *PayloadCommitVerification `json:"verification"` } diff --git a/modules/structs/repo_watch.go b/modules/structs/repo_watch.go index 2e89a9eefcf59..0d0b7c4ae0483 100644 --- a/modules/structs/repo_watch.go +++ b/modules/structs/repo_watch.go @@ -9,10 +9,10 @@ import ( // WatchInfo represents an API watch status of one repository type WatchInfo struct { - Subscribed bool `json:"subscribed"` - Ignored bool `json:"ignored"` - Reason interface{} `json:"reason"` - CreatedAt time.Time `json:"created_at"` - URL string `json:"url"` - RepositoryURL string `json:"repository_url"` + Subscribed bool `json:"subscribed"` + Ignored bool `json:"ignored"` + Reason any `json:"reason"` + CreatedAt time.Time `json:"created_at"` + URL string `json:"url"` + RepositoryURL string `json:"repository_url"` } diff --git a/modules/svg/svg.go b/modules/svg/svg.go index 6db5c7109b2f8..0e2f6a00346aa 100644 --- a/modules/svg/svg.go +++ b/modules/svg/svg.go @@ -49,7 +49,7 @@ func Init() error { } // RenderHTML renders icons - arguments icon name (string), size (int), class (string) -func RenderHTML(icon string, others ...interface{}) template.HTML { +func RenderHTML(icon string, others ...any) template.HTML { size, class := html.ParseSizeAndClass(defaultSize, "", others...) if svgStr, ok := SVGs[icon]; ok { diff --git a/modules/templates/helper.go b/modules/templates/helper.go index 2f2ef44049794..2b918f42c099e 100644 --- a/modules/templates/helper.go +++ b/modules/templates/helper.go @@ -27,7 +27,7 @@ import ( // NewFuncMap returns functions for injecting to templates func NewFuncMap() template.FuncMap { - return map[string]interface{}{ + return map[string]any{ "DumpVar": dumpVar, // ----------------------------------------------------------------- @@ -142,8 +142,8 @@ func NewFuncMap() template.FuncMap { "DefaultTheme": func() string { return setting.UI.DefaultTheme }, - "NotificationSettings": func() map[string]interface{} { - return map[string]interface{}{ + "NotificationSettings": func() map[string]any { + return map[string]any{ "MinTimeout": int(setting.UI.Notification.MinTimeout / time.Millisecond), "TimeoutStep": int(setting.UI.Notification.TimeoutStep / time.Millisecond), "MaxTimeout": int(setting.UI.Notification.MaxTimeout / time.Millisecond), diff --git a/modules/templates/htmlrenderer.go b/modules/templates/htmlrenderer.go index e0cbc49ff4401..d470435b63d56 100644 --- a/modules/templates/htmlrenderer.go +++ b/modules/templates/htmlrenderer.go @@ -39,7 +39,7 @@ var ( var ErrTemplateNotInitialized = errors.New("template system is not initialized, check your log for errors") -func (h *HTMLRender) HTML(w io.Writer, status int, name string, data interface{}) error { +func (h *HTMLRender) HTML(w io.Writer, status int, name string, data any) error { if respWriter, ok := w.(http.ResponseWriter); ok { if respWriter.Header().Get("Content-Type") == "" { respWriter.Header().Set("Content-Type", "text/html; charset=utf-8") diff --git a/modules/templates/scopedtmpl/scopedtmpl.go b/modules/templates/scopedtmpl/scopedtmpl.go index a8b67ad0f908c..2722ba97a28ac 100644 --- a/modules/templates/scopedtmpl/scopedtmpl.go +++ b/modules/templates/scopedtmpl/scopedtmpl.go @@ -15,7 +15,7 @@ import ( ) type TemplateExecutor interface { - Execute(wr io.Writer, data interface{}) error + Execute(wr io.Writer, data any) error } type ScopedTemplate struct { diff --git a/modules/templates/util_avatar.go b/modules/templates/util_avatar.go index 3badc97cb9fa2..9f8f8f87a9d6b 100644 --- a/modules/templates/util_avatar.go +++ b/modules/templates/util_avatar.go @@ -30,7 +30,7 @@ func AvatarHTML(src string, size int, class, name string) template.HTML { } // Avatar renders user avatars. args: user, size (int), class (string) -func Avatar(ctx context.Context, item interface{}, others ...interface{}) template.HTML { +func Avatar(ctx context.Context, item any, others ...any) template.HTML { size, class := gitea_html.ParseSizeAndClass(avatars.DefaultAvatarPixelSize, avatars.DefaultAvatarClass, others...) switch t := item.(type) { @@ -55,13 +55,13 @@ func Avatar(ctx context.Context, item interface{}, others ...interface{}) templa } // AvatarByAction renders user avatars from action. args: action, size (int), class (string) -func AvatarByAction(ctx context.Context, action *activities_model.Action, others ...interface{}) template.HTML { +func AvatarByAction(ctx context.Context, action *activities_model.Action, others ...any) template.HTML { action.LoadActUser(ctx) return Avatar(ctx, action.ActUser, others...) } // RepoAvatar renders repo avatars. args: repo, size(int), class (string) -func RepoAvatar(repo *repo_model.Repository, others ...interface{}) template.HTML { +func RepoAvatar(repo *repo_model.Repository, others ...any) template.HTML { size, class := gitea_html.ParseSizeAndClass(avatars.DefaultAvatarPixelSize, avatars.DefaultAvatarClass, others...) src := repo.RelAvatarLink() @@ -72,7 +72,7 @@ func RepoAvatar(repo *repo_model.Repository, others ...interface{}) template.HTM } // AvatarByEmail renders avatars by email address. args: email, name, size (int), class (string) -func AvatarByEmail(ctx context.Context, email, name string, others ...interface{}) template.HTML { +func AvatarByEmail(ctx context.Context, email, name string, others ...any) template.HTML { size, class := gitea_html.ParseSizeAndClass(avatars.DefaultAvatarPixelSize, avatars.DefaultAvatarClass, others...) src := avatars.GenerateEmailAvatarFastLink(ctx, email, size*setting.Avatar.RenderedSizeFactor) diff --git a/modules/templates/util_misc.go b/modules/templates/util_misc.go index d11251fcdf653..9cdabeb3aceed 100644 --- a/modules/templates/util_misc.go +++ b/modules/templates/util_misc.go @@ -174,7 +174,7 @@ func FilenameIsImage(filename string) bool { return strings.HasPrefix(mimeType, "image/") } -func TabSizeClass(ec interface{}, filename string) string { +func TabSizeClass(ec any, filename string) string { var ( value *editorconfig.Editorconfig ok bool diff --git a/modules/test/context_tests.go b/modules/test/context_tests.go index cf8af32fc69ef..9e7095e116c8a 100644 --- a/modules/test/context_tests.go +++ b/modules/test/context_tests.go @@ -154,7 +154,7 @@ func (tr *mockRender) TemplateLookup(tmpl string) (templates.TemplateExecutor, e return nil, nil } -func (tr *mockRender) HTML(w io.Writer, status int, _ string, _ interface{}) error { +func (tr *mockRender) HTML(w io.Writer, status int, _ string, _ any) error { if resp, ok := w.(http.ResponseWriter); ok { resp.WriteHeader(status) } diff --git a/modules/testlogger/testlogger.go b/modules/testlogger/testlogger.go index 6a0cee4a2998b..4215567c00488 100644 --- a/modules/testlogger/testlogger.go +++ b/modules/testlogger/testlogger.go @@ -137,7 +137,7 @@ func PrintCurrentTest(t testing.TB, skip ...int) func() { } // Printf takes a format and args and prints the string to os.Stdout -func Printf(format string, args ...interface{}) { +func Printf(format string, args ...any) { if log.CanColorStdout { for i := 0; i < len(args); i++ { args[i] = log.NewColoredValue(args[i]) diff --git a/modules/translation/i18n/format.go b/modules/translation/i18n/format.go index 637209ad807e6..e5e221831f5ec 100644 --- a/modules/translation/i18n/format.go +++ b/modules/translation/i18n/format.go @@ -9,12 +9,12 @@ import ( ) // Format formats provided arguments for a given translated message -func Format(format string, args ...interface{}) (msg string, err error) { +func Format(format string, args ...any) (msg string, err error) { if len(args) == 0 { return format, nil } - fmtArgs := make([]interface{}, 0, len(args)) + fmtArgs := make([]any, 0, len(args)) for _, arg := range args { val := reflect.ValueOf(arg) if val.Kind() == reflect.Slice { diff --git a/modules/translation/i18n/i18n.go b/modules/translation/i18n/i18n.go index 4048c9acd2d22..42475545b34a9 100644 --- a/modules/translation/i18n/i18n.go +++ b/modules/translation/i18n/i18n.go @@ -11,7 +11,7 @@ var DefaultLocales = NewLocaleStore() type Locale interface { // Tr translates a given key and arguments for a language - Tr(trKey string, trArgs ...interface{}) string + Tr(trKey string, trArgs ...any) string // Has reports if a locale has a translation for a given key Has(trKey string) bool } @@ -21,7 +21,7 @@ type LocaleStore interface { io.Closer // Tr translates a given key and arguments for a language - Tr(lang, trKey string, trArgs ...interface{}) string + Tr(lang, trKey string, trArgs ...any) string // Has reports if a locale has a translation for a given key Has(lang, trKey string) bool // SetDefaultLang sets the default language to fall back to diff --git a/modules/translation/i18n/localestore.go b/modules/translation/i18n/localestore.go index aa784e866fce4..f5a951a79f15c 100644 --- a/modules/translation/i18n/localestore.go +++ b/modules/translation/i18n/localestore.go @@ -86,7 +86,7 @@ func (store *localeStore) SetDefaultLang(lang string) { } // Tr translates content to target language. fall back to default language. -func (store *localeStore) Tr(lang, trKey string, trArgs ...interface{}) string { +func (store *localeStore) Tr(lang, trKey string, trArgs ...any) string { l, _ := store.Locale(lang) return l.Tr(trKey, trArgs...) @@ -119,7 +119,7 @@ func (store *localeStore) Close() error { } // Tr translates content to locale language. fall back to default language. -func (l *locale) Tr(trKey string, trArgs ...interface{}) string { +func (l *locale) Tr(trKey string, trArgs ...any) string { format := trKey idx, ok := l.store.trKeyToIdxMap[trKey] diff --git a/modules/translation/mock.go b/modules/translation/mock.go index 6ce66166aa13d..2d0cb173246ba 100644 --- a/modules/translation/mock.go +++ b/modules/translation/mock.go @@ -14,11 +14,11 @@ func (l MockLocale) Language() string { return "en" } -func (l MockLocale) Tr(s string, _ ...interface{}) string { +func (l MockLocale) Tr(s string, _ ...any) string { return s } -func (l MockLocale) TrN(_cnt interface{}, key1, _keyN string, _args ...interface{}) string { +func (l MockLocale) TrN(_cnt any, key1, _keyN string, _args ...any) string { return key1 } diff --git a/modules/util/error.go b/modules/util/error.go index e67b9977f080c..0f3597147ceaa 100644 --- a/modules/util/error.go +++ b/modules/util/error.go @@ -37,7 +37,7 @@ func (w SilentWrap) Unwrap() error { } // NewSilentWrapErrorf returns an error that formats as the given text but unwraps as the provided error -func NewSilentWrapErrorf(unwrap error, message string, args ...interface{}) error { +func NewSilentWrapErrorf(unwrap error, message string, args ...any) error { if len(args) == 0 { return SilentWrap{Message: message, Err: unwrap} } @@ -45,21 +45,21 @@ func NewSilentWrapErrorf(unwrap error, message string, args ...interface{}) erro } // NewInvalidArgumentErrorf returns an error that formats as the given text but unwraps as an ErrInvalidArgument -func NewInvalidArgumentErrorf(message string, args ...interface{}) error { +func NewInvalidArgumentErrorf(message string, args ...any) error { return NewSilentWrapErrorf(ErrInvalidArgument, message, args...) } // NewPermissionDeniedErrorf returns an error that formats as the given text but unwraps as an ErrPermissionDenied -func NewPermissionDeniedErrorf(message string, args ...interface{}) error { +func NewPermissionDeniedErrorf(message string, args ...any) error { return NewSilentWrapErrorf(ErrPermissionDenied, message, args...) } // NewAlreadyExistErrorf returns an error that formats as the given text but unwraps as an ErrAlreadyExist -func NewAlreadyExistErrorf(message string, args ...interface{}) error { +func NewAlreadyExistErrorf(message string, args ...any) error { return NewSilentWrapErrorf(ErrAlreadyExist, message, args...) } // NewNotExistErrorf returns an error that formats as the given text but unwraps as an ErrNotExist -func NewNotExistErrorf(message string, args ...interface{}) error { +func NewNotExistErrorf(message string, args ...any) error { return NewSilentWrapErrorf(ErrNotExist, message, args...) } diff --git a/modules/util/pack.go b/modules/util/pack.go index 315d9f5066ff9..7fc074a2b037f 100644 --- a/modules/util/pack.go +++ b/modules/util/pack.go @@ -9,7 +9,7 @@ import ( ) // PackData uses gob to encode the given data in sequence -func PackData(data ...interface{}) ([]byte, error) { +func PackData(data ...any) ([]byte, error) { var buf bytes.Buffer enc := gob.NewEncoder(&buf) for _, datum := range data { @@ -21,7 +21,7 @@ func PackData(data ...interface{}) ([]byte, error) { } // UnpackData uses gob to decode the given data in sequence -func UnpackData(buf []byte, data ...interface{}) error { +func UnpackData(buf []byte, data ...any) error { r := bytes.NewReader(buf) enc := gob.NewDecoder(r) for _, datum := range data { diff --git a/modules/util/paginate.go b/modules/util/paginate.go index f2721df1adba4..87f31b76ed268 100644 --- a/modules/util/paginate.go +++ b/modules/util/paginate.go @@ -7,7 +7,7 @@ import "reflect" // PaginateSlice cut a slice as per pagination options // if page = 0 it do not paginate -func PaginateSlice(list interface{}, page, pageSize int) interface{} { +func PaginateSlice(list any, page, pageSize int) any { if page <= 0 || pageSize <= 0 { return list } diff --git a/modules/util/rotatingfilewriter/writer.go b/modules/util/rotatingfilewriter/writer.go index 5243bfe353861..c595f49c49b5e 100644 --- a/modules/util/rotatingfilewriter/writer.go +++ b/modules/util/rotatingfilewriter/writer.go @@ -39,10 +39,10 @@ type RotatingFileWriter struct { cancelReleaseReopen func() } -var ErrorPrintf func(format string, args ...interface{}) +var ErrorPrintf func(format string, args ...any) // errorf tries to print error messages. Since this writer could be used by a logger system, this is the last chance to show the error in some cases -func errorf(format string, args ...interface{}) { +func errorf(format string, args ...any) { if ErrorPrintf != nil { ErrorPrintf("rotatingfilewriter: "+format+"\n", args...) } diff --git a/modules/util/util.go b/modules/util/util.go index 148817bd47047..3051449544d00 100644 --- a/modules/util/util.go +++ b/modules/util/util.go @@ -174,7 +174,7 @@ func ToTitleCaseNoLower(s string) string { } // ToInt64 transform a given int into int64. -func ToInt64(number interface{}) (int64, error) { +func ToInt64(number any) (int64, error) { var value int64 switch v := number.(type) { case int: @@ -216,7 +216,7 @@ func ToInt64(number interface{}) (int64, error) { } // ToFloat64 transform a given int into float64. -func ToFloat64(number interface{}) (float64, error) { +func ToFloat64(number any) (float64, error) { var value float64 switch v := number.(type) { case int: diff --git a/modules/validation/binding.go b/modules/validation/binding.go index 1f904979ffd9c..cb0a5063e509b 100644 --- a/modules/validation/binding.go +++ b/modules/validation/binding.go @@ -46,7 +46,7 @@ func addGitRefNameBindingRule() { IsMatch: func(rule string) bool { return strings.HasPrefix(rule, "GitRefName") }, - IsValid: func(errs binding.Errors, name string, val interface{}) (bool, binding.Errors) { + IsValid: func(errs binding.Errors, name string, val any) (bool, binding.Errors) { str := fmt.Sprintf("%v", val) if !git.IsValidRefPattern(str) { @@ -64,7 +64,7 @@ func addValidURLBindingRule() { IsMatch: func(rule string) bool { return strings.HasPrefix(rule, "ValidUrl") }, - IsValid: func(errs binding.Errors, name string, val interface{}) (bool, binding.Errors) { + IsValid: func(errs binding.Errors, name string, val any) (bool, binding.Errors) { str := fmt.Sprintf("%v", val) if len(str) != 0 && !IsValidURL(str) { errs.Add([]string{name}, binding.ERR_URL, "Url") @@ -82,7 +82,7 @@ func addValidSiteURLBindingRule() { IsMatch: func(rule string) bool { return strings.HasPrefix(rule, "ValidSiteUrl") }, - IsValid: func(errs binding.Errors, name string, val interface{}) (bool, binding.Errors) { + IsValid: func(errs binding.Errors, name string, val any) (bool, binding.Errors) { str := fmt.Sprintf("%v", val) if len(str) != 0 && !IsValidSiteURL(str) { errs.Add([]string{name}, binding.ERR_URL, "Url") @@ -103,7 +103,7 @@ func addGlobPatternRule() { }) } -func globPatternValidator(errs binding.Errors, name string, val interface{}) (bool, binding.Errors) { +func globPatternValidator(errs binding.Errors, name string, val any) (bool, binding.Errors) { str := fmt.Sprintf("%v", val) if len(str) != 0 { @@ -125,7 +125,7 @@ func addRegexPatternRule() { }) } -func regexPatternValidator(errs binding.Errors, name string, val interface{}) (bool, binding.Errors) { +func regexPatternValidator(errs binding.Errors, name string, val any) (bool, binding.Errors) { str := fmt.Sprintf("%v", val) if _, err := regexp.Compile(str); err != nil { @@ -141,7 +141,7 @@ func addGlobOrRegexPatternRule() { IsMatch: func(rule string) bool { return rule == "GlobOrRegexPattern" }, - IsValid: func(errs binding.Errors, name string, val interface{}) (bool, binding.Errors) { + IsValid: func(errs binding.Errors, name string, val any) (bool, binding.Errors) { str := strings.TrimSpace(fmt.Sprintf("%v", val)) if len(str) >= 2 && strings.HasPrefix(str, "/") && strings.HasSuffix(str, "/") { @@ -157,7 +157,7 @@ func addUsernamePatternRule() { IsMatch: func(rule string) bool { return rule == "Username" }, - IsValid: func(errs binding.Errors, name string, val interface{}) (bool, binding.Errors) { + IsValid: func(errs binding.Errors, name string, val any) (bool, binding.Errors) { str := fmt.Sprintf("%v", val) if !IsValidUsername(str) { errs.Add([]string{name}, ErrUsername, "invalid username") @@ -173,7 +173,7 @@ func addValidGroupTeamMapRule() { IsMatch: func(rule string) bool { return strings.HasPrefix(rule, "ValidGroupTeamMap") }, - IsValid: func(errs binding.Errors, name string, val interface{}) (bool, binding.Errors) { + IsValid: func(errs binding.Errors, name string, val any) (bool, binding.Errors) { _, err := auth.UnmarshalGroupTeamMapping(fmt.Sprintf("%v", val)) if err != nil { errs.Add([]string{name}, ErrInvalidGroupTeamMap, err.Error()) diff --git a/modules/validation/binding_test.go b/modules/validation/binding_test.go index 9ca93784a85c5..01ff4e34356a0 100644 --- a/modules/validation/binding_test.go +++ b/modules/validation/binding_test.go @@ -20,7 +20,7 @@ const ( type ( validationTestCase struct { description string - data interface{} + data any expectedErrors binding.Errors } diff --git a/modules/web/middleware/binding.go b/modules/web/middleware/binding.go index 8b74a864d9571..d9bcdf3b2ad12 100644 --- a/modules/web/middleware/binding.go +++ b/modules/web/middleware/binding.go @@ -25,7 +25,7 @@ func init() { } // AssignForm assign form values back to the template data. -func AssignForm(form interface{}, data map[string]interface{}) { +func AssignForm(form any, data map[string]any) { typ := reflect.TypeOf(form) val := reflect.ValueOf(form) @@ -79,7 +79,7 @@ func GetInclude(field reflect.StructField) string { } // Validate validate TODO: -func Validate(errs binding.Errors, data map[string]interface{}, f Form, l translation.Locale) binding.Errors { +func Validate(errs binding.Errors, data map[string]any, f Form, l translation.Locale) binding.Errors { if errs.Len() == 0 { return errs } diff --git a/modules/web/route.go b/modules/web/route.go index db511aeb185e9..8685062a8e5f9 100644 --- a/modules/web/route.go +++ b/modules/web/route.go @@ -25,12 +25,12 @@ func Bind[T any](_ T) http.HandlerFunc { } // SetForm set the form object -func SetForm(dataStore middleware.ContextDataStore, obj interface{}) { +func SetForm(dataStore middleware.ContextDataStore, obj any) { dataStore.GetData()["__form"] = obj } // GetForm returns the validate form information -func GetForm(dataStore middleware.ContextDataStore) interface{} { +func GetForm(dataStore middleware.ContextDataStore) any { return dataStore.GetData()["__form"] } @@ -38,7 +38,7 @@ func GetForm(dataStore middleware.ContextDataStore) interface{} { type Route struct { R chi.Router curGroupPrefix string - curMiddlewares []interface{} + curMiddlewares []any } // NewRoute creates a new route @@ -48,14 +48,14 @@ func NewRoute() *Route { } // Use supports two middlewares -func (r *Route) Use(middlewares ...interface{}) { +func (r *Route) Use(middlewares ...any) { for _, m := range middlewares { r.R.Use(toHandlerProvider(m)) } } // Group mounts a sub-Router along a `pattern` string. -func (r *Route) Group(pattern string, fn func(), middlewares ...interface{}) { +func (r *Route) Group(pattern string, fn func(), middlewares ...any) { previousGroupPrefix := r.curGroupPrefix previousMiddlewares := r.curMiddlewares r.curGroupPrefix += pattern @@ -111,53 +111,53 @@ func (r *Route) Mount(pattern string, subR *Route) { } // Any delegate requests for all methods -func (r *Route) Any(pattern string, h ...interface{}) { +func (r *Route) Any(pattern string, h ...any) { middlewares, handlerFunc := r.wrapMiddlewareAndHandler(h) r.R.With(middlewares...).HandleFunc(r.getPattern(pattern), handlerFunc) } // RouteMethods delegate special methods, it is an alias of "Methods", while the "pattern" is the first parameter -func (r *Route) RouteMethods(pattern, methods string, h ...interface{}) { +func (r *Route) RouteMethods(pattern, methods string, h ...any) { r.Methods(methods, pattern, h) } // Delete delegate delete method -func (r *Route) Delete(pattern string, h ...interface{}) { +func (r *Route) Delete(pattern string, h ...any) { r.Methods("DELETE", pattern, h) } // Get delegate get method -func (r *Route) Get(pattern string, h ...interface{}) { +func (r *Route) Get(pattern string, h ...any) { r.Methods("GET", pattern, h) } // GetOptions delegate get and options method -func (r *Route) GetOptions(pattern string, h ...interface{}) { +func (r *Route) GetOptions(pattern string, h ...any) { r.Methods("GET,OPTIONS", pattern, h) } // PostOptions delegate post and options method -func (r *Route) PostOptions(pattern string, h ...interface{}) { +func (r *Route) PostOptions(pattern string, h ...any) { r.Methods("POST,OPTIONS", pattern, h) } // Head delegate head method -func (r *Route) Head(pattern string, h ...interface{}) { +func (r *Route) Head(pattern string, h ...any) { r.Methods("HEAD", pattern, h) } // Post delegate post method -func (r *Route) Post(pattern string, h ...interface{}) { +func (r *Route) Post(pattern string, h ...any) { r.Methods("POST", pattern, h) } // Put delegate put method -func (r *Route) Put(pattern string, h ...interface{}) { +func (r *Route) Put(pattern string, h ...any) { r.Methods("PUT", pattern, h) } // Patch delegate patch method -func (r *Route) Patch(pattern string, h ...interface{}) { +func (r *Route) Patch(pattern string, h ...any) { r.Methods("PATCH", pattern, h) } @@ -172,7 +172,7 @@ func (r *Route) NotFound(h http.HandlerFunc) { } // Combo delegates requests to Combo -func (r *Route) Combo(pattern string, h ...interface{}) *Combo { +func (r *Route) Combo(pattern string, h ...any) *Combo { return &Combo{r, pattern, h} } @@ -180,35 +180,35 @@ func (r *Route) Combo(pattern string, h ...interface{}) *Combo { type Combo struct { r *Route pattern string - h []interface{} + h []any } // Get delegates Get method -func (c *Combo) Get(h ...interface{}) *Combo { +func (c *Combo) Get(h ...any) *Combo { c.r.Get(c.pattern, append(c.h, h...)...) return c } // Post delegates Post method -func (c *Combo) Post(h ...interface{}) *Combo { +func (c *Combo) Post(h ...any) *Combo { c.r.Post(c.pattern, append(c.h, h...)...) return c } // Delete delegates Delete method -func (c *Combo) Delete(h ...interface{}) *Combo { +func (c *Combo) Delete(h ...any) *Combo { c.r.Delete(c.pattern, append(c.h, h...)...) return c } // Put delegates Put method -func (c *Combo) Put(h ...interface{}) *Combo { +func (c *Combo) Put(h ...any) *Combo { c.r.Put(c.pattern, append(c.h, h...)...) return c } // Patch delegates Patch method -func (c *Combo) Patch(h ...interface{}) *Combo { +func (c *Combo) Patch(h ...any) *Combo { c.r.Patch(c.pattern, append(c.h, h...)...) return c } diff --git a/modules/web/routing/context.go b/modules/web/routing/context.go index 0d5e7655431c2..c5e85a415b1eb 100644 --- a/modules/web/routing/context.go +++ b/modules/web/routing/context.go @@ -37,7 +37,7 @@ func MarkLongPolling(resp http.ResponseWriter, req *http.Request) { } // UpdatePanicError updates a context's error info, a panic may be recovered by other middlewares, but we still need to know that. -func UpdatePanicError(ctx context.Context, err interface{}) { +func UpdatePanicError(ctx context.Context, err any) { record, ok := ctx.Value(contextKey).(*requestRecord) if !ok { return diff --git a/modules/web/routing/funcinfo.go b/modules/web/routing/funcinfo.go index 499bc2c7aad9a..f4e9731a630d4 100644 --- a/modules/web/routing/funcinfo.go +++ b/modules/web/routing/funcinfo.go @@ -35,7 +35,7 @@ func (info *FuncInfo) String() string { } // GetFuncInfo returns the FuncInfo for a provided function and friendlyname -func GetFuncInfo(fn interface{}, friendlyName ...string) *FuncInfo { +func GetFuncInfo(fn any, friendlyName ...string) *FuncInfo { // ptr represents the memory position of the function passed in as v. // This will be used as program counter in FuncForPC below ptr := reflect.ValueOf(fn).Pointer() diff --git a/modules/web/routing/requestrecord.go b/modules/web/routing/requestrecord.go index 34a2d33893018..cc61fc4d34839 100644 --- a/modules/web/routing/requestrecord.go +++ b/modules/web/routing/requestrecord.go @@ -24,5 +24,5 @@ type requestRecord struct { // mutable fields isLongPolling bool funcInfo *FuncInfo - panicError interface{} + panicError any } diff --git a/options/locale/locale_cs-CZ.ini b/options/locale/locale_cs-CZ.ini index da550884c7983..0559b1f12f11c 100644 --- a/options/locale/locale_cs-CZ.ini +++ b/options/locale/locale_cs-CZ.ini @@ -383,7 +383,7 @@ hi_user_x=Ahoj %s, activate_account=Prosíme, aktivujte si váš účet activate_account.title=%s, prosím aktivujte si váš účet -activate_account.text_1=Ahoj %[1]s, děkujeme za registraci na %[2]! +activate_account.text_1=Ahoj %[1]s, děkujeme za registraci na %[2]s! activate_account.text_2=Pro aktivaci vašeho účtu do %s klikněte na následující odkaz: activate_email=Ověřte vaši e-mailovou adresu @@ -402,8 +402,8 @@ reset_password.text=Klikněte prosím na následující odkaz pro obnovení vaš register_success=Registrace byla úspěšná -issue_assigned.pull=@%[1]s vás přiřadil/a k požadavku na natažení %[2]v repozitáři %[3]s. -issue_assigned.issue=@%[1]s vás přiřadil/a k úkolu %[2]v repozitáři %[3]s. +issue_assigned.pull=@%[1]s vás přiřadil/a k požadavku na natažení %[2]s repozitáři %[3]s. +issue_assigned.issue=@%[1]s vás přiřadil/a k úkolu %[2]s repozitáři %[3]s. issue.x_mentioned_you=@%s vás zmínil/a: issue.action.force_push=%[1]s vynutil/a nahrání %[2]s z %[3]s do %[4]s. @@ -2310,7 +2310,7 @@ members.member_role=Role člena: members.owner=Vlastník members.member=Člen members.remove=Smazat -members.remove.detail=Odstranit %[1]s z %[2]? +members.remove.detail=Odstranit %[1]s z %[2]s? members.leave=Opustit members.leave.detail=Opustit %s? members.invite_desc=Přidat nového člena do %s: diff --git a/options/locale/locale_de-DE.ini b/options/locale/locale_de-DE.ini index 10f83b34aad5e..0cffa24938123 100644 --- a/options/locale/locale_de-DE.ini +++ b/options/locale/locale_de-DE.ini @@ -19,6 +19,7 @@ active_stopwatch=Aktive Zeiterfassung create_new=Erstellen… user_profile_and_more=Profil und Einstellungen… signed_in_as=Angemeldet als +enable_javascript=Diese Website benötigt JavaScript. toc=Inhaltsverzeichnis licenses=Lizenzen return_to_gitea=Zurück zu Gitea @@ -92,6 +93,7 @@ copy_url=URL kopieren copy_branch=Branchenname kopieren copy_success=Kopiert! copy_error=Kopieren fehlgeschlagen +copy_type_unsupported=Dieser Dateityp kann nicht kopiert werden write=Verfassen preview=Vorschau @@ -104,22 +106,42 @@ error=Fehler error404=Die Seite, die du gerade versuchst aufzurufen, existiert entweder nicht oder du bist nicht berechtigt, diese anzusehen. never=Niemals +unknown=Unbekannt rss_feed=RSS Feed +artifacts=Artefakte +concept_system_global=Global concept_code_repository=Repository concept_user_organization=Organisation +show_log_seconds=Sekunden anzeigen [aria] +footer.software=Über die Software +footer.links=Links [heatmap] +less=Weniger +more=Mehr [editor] +buttons.heading.tooltip=Titel hinzufügen +buttons.quote.tooltip=Text zitieren +buttons.code.tooltip=Code hinzufügen +buttons.link.tooltip=Link hinzufügen +buttons.list.ordered.tooltip=Nummerierte Liste hinzufügen +buttons.list.task.tooltip=Aufgabenliste hinzufügen +buttons.mention.tooltip=Benutzer oder Team erwähnen +buttons.ref.tooltip=Issue oder Pull-Request referenzieren +buttons.enable_monospace_font=Monospace-Schrift aktivieren +buttons.disable_monospace_font=Monospace-Schrift deaktivieren [filter] +string.asc=A–Z +string.desc=Z–A [error] occurred=Ein Fehler ist aufgetreten @@ -228,6 +250,7 @@ install_btn_confirm=Gitea installieren test_git_failed=Fehler beim Test des „git“-Befehls: %v sqlite3_not_available=Diese Gitea-Version unterstützt SQLite3 nicht. Bitte lade die offizielle binäre Version von %s herunter (nicht die „gobuild“-Version). invalid_db_setting=Datenbankeinstellungen sind ungültig: %v +invalid_db_table=Die Datenbanktabelle "%s" ist ungültig: %v invalid_repo_path=Repository-Verzeichnis ist ungültig: %v invalid_app_data_path=Der App-Daten-Pfad ist ungültig: %v run_user_not_match=Der „Ausführen als“-Benutzername ist nicht der aktuelle Benutzername: %s -> %s @@ -245,6 +268,7 @@ default_enable_timetracking_popup=Zeiterfassung standardmäßig für neue Reposi no_reply_address=Versteckte E-Mail-Domain no_reply_address_helper=Domain-Name für Benutzer mit einer versteckten Emailadresse. Zum Beispiel wird der Benutzername „Joe“ in Git als „joe@noreply.example.org“ protokolliert, wenn die versteckte E-Mail-Domain „noreply.example.org“ festgelegt ist. password_algorithm=Passwort Hashing Algorithmus +invalid_password_algorithm=Ungültiger Passwort-Hash-Algorithmus [home] uname_holder=E-Mail-Adresse oder Benutzername @@ -279,6 +303,7 @@ users=Benutzer organizations=Organisationen search=Suche code=Code +search.type.tooltip=Suchmodus search.fuzzy=Ähnlich search.match=Genau code_search_unavailable=Derzeit ist die Code-Suche nicht verfügbar. Bitte wende dich an den Website-Administrator. @@ -545,6 +570,7 @@ location=Standort update_theme=Theme ändern update_profile=Profil aktualisieren update_language=Sprache aktualisieren +update_language_not_found=Sprache "%s" ist nicht verfügbar. update_language_success=Sprache wurde aktualisiert. update_profile_success=Dein Profil wurde aktualisiert. change_username=Dein Benutzername wurde geändert. @@ -655,6 +681,7 @@ gpg_token_help=Du kannst eine Signatur wie folgt generieren: gpg_token_code=echo "%s" | gpg -a --default-key %s --detach-sig gpg_token_signature=GPG Textsignatur (armored signature) key_signature_gpg_placeholder=Beginnt mit '-----BEGIN PGP SIGNATURE-----' +verify_gpg_key_success=GPG-Schlüssel "%s" wurde verifiziert. ssh_key_verified=Verifizierter Schlüssel ssh_key_verified_long=Der Schlüssel wurde mit einem Token verifiziert. Er kann verwendet werden, um Commits zu verifizieren, die mit irgendeiner für diesen Nutzer aktivierten E-Mail-Adresse und irgendeiner Identität dieses Schlüssels übereinstimmen. ssh_key_verify=Verifizieren @@ -975,6 +1002,7 @@ download_archive=Repository herunterladen no_desc=Keine Beschreibung quick_guide=Kurzanleitung clone_this_repo=Dieses Repository klonen +cite_this_repo=Dieses Repository zitieren create_new_repo_command=Erstelle ein neues Repository von der Kommandozeile aus push_exist_repo=Bestehendes Repository via Kommandozeile pushen empty_message=Dieses Repository hat keinen Inhalt. @@ -993,6 +1021,7 @@ issues=Issues pulls=Pull-Requests project_board=Projekte packages=Pakete +actions=Actions labels=Label org_labels_desc=Labels der Organisationsebene, die mit allen Repositories in dieser Organisation verwendet werden können org_labels_desc_manage=verwalten @@ -1012,6 +1041,7 @@ file_view_rendered=Ansicht rendern file_view_raw=Originalformat anzeigen file_permalink=Permalink file_too_large=Die Datei ist zu groß zum Anzeigen. +invisible_runes_header=`Diese Datei enthält unsichtbare Unicode-Zeichen!` ambiguous_character=`%[1]c [U+%04[1]X] kann mit %[2]c [U+%04[2]X] verwechselt werden` escape_control_characters=Escapen @@ -1032,6 +1062,7 @@ download_file=Datei herunterladen normal_view=Normale Ansicht line=zeile lines=Zeilen +from_comment=(Kommentar) editor.add_file=Datei hinzufügen editor.new_file=Neue Datei @@ -1046,6 +1077,7 @@ editor.must_be_on_a_branch=Du musst dich in einem Branch befinden, um Änderunge editor.fork_before_edit=Du musst dieses Repository forken, um Änderungen an dieser Datei vorzuschlagen oder vorzunehmen. editor.delete_this_file=Datei löschen editor.must_have_write_access=Du benötigst Schreibzugriff, um Änderungen an dieser Datei vorzuschlagen oder vorzunehmen. +editor.file_delete_success=Datei "%s" wurde gelöscht. editor.name_your_file=Dateinamen eingeben… editor.filename_help=Füge einen Ordner hinzu, indem du seinen Namen und anschließend '/' eingibst. Entferne einen Ordner indem du die Zurücktaste am Anfang des Feldes drückst. editor.or=oder @@ -1681,6 +1713,7 @@ activity.git_stats_deletion_n=%d Löschungen search=Suchen search.search_repo=Repository durchsuchen +search.type.tooltip=Suchmodus search.fuzzy=Ähnlich search.match=Genau search.results=Suchergebnisse für „%s“ in %s @@ -2158,6 +2191,8 @@ branch.delete_html=Branch löschen branch.delete_desc=Das Löschen eines Branches ist permanent. Es KANN NICHT rückgängig gemacht werden. Fortfahren? branch.create_branch=Erstelle Branch %s branch.deleted_by=Von %s gelöscht +branch.restore=Branch "%s" wiederherstellen +branch.download=Branch "%s" herunterladen branch.included_desc=Dieser Branch ist im Standard-Branch enthalten branch.included=Enthalten branch.create_new_branch=Branch aus Branch erstellen: @@ -2165,12 +2200,15 @@ branch.confirm_create_branch=Branch erstellen branch.confirm_rename_branch=Branch umbennen branch.create_branch_operation=Branch erstellen branch.new_branch=Neue Branch erstellen +branch.new_branch_from=Neuen Branch von "%s" erstellen branch.renamed=Branch %s wurde in %s umbenannt. tag.create_tag=Tag %s erstellen tag.create_tag_operation=Tag erstellen tag.confirm_create_tag=Tag erstellen +tag.create_tag_from=Neuen Tag von "%s" erstellen +tag.create_success=Tag "%s" wurde erstellt. topic.manage_topics=Themen verwalten topic.done=Fertig @@ -2407,6 +2445,7 @@ users.created=Registriert am users.last_login=Letzte Anmeldung users.never_login=Hat sich noch nie eingeloggt users.send_register_notify=Benutzer-Registrierungsbenachrichtigung senden +users.new_success=Der Account "%s" wurde erstellt. users.edit=Bearbeiten users.auth_source=Authentifizierungsquelle users.local=Lokal @@ -2770,7 +2809,7 @@ monitor.queue.review=Konfiguration überprüfen monitor.queue.review_add=Worker hinzufügen/prüfen monitor.queue.settings.title=Pool-Einstellungen monitor.queue.settings.maxnumberworkers=Maximale Anzahl an Workern -monitor.queue.settings.maxnumberworkers.placeholder=Derzeit %[1]v +monitor.queue.settings.maxnumberworkers.placeholder=Derzeit %[1]d monitor.queue.settings.maxnumberworkers.error=Die Anzahl der Worker muss eine Zahl sein monitor.queue.settings.submit=Einstellungen aktualisieren monitor.queue.settings.changed=Einstellungen aktualisiert @@ -2979,6 +3018,7 @@ settings.delete.description=Das Löschen eines Pakets ist dauerhaft und kann nic settings.delete.notice=Du bist dabei, %s (%s) zu löschen. Dieser Vorgang ist unwiderruflich. Bist du sicher? settings.delete.success=Das Paket wurde gelöscht. settings.delete.error=Löschen des Pakets fehlgeschlagen. +owner.settings.cargo.initialize=Index initialisieren owner.settings.cleanuprules.enabled=Aktiviert [secrets] @@ -2986,8 +3026,10 @@ value=Wert name=Name [actions] +actions=Actions +status.unknown=Unbekannt runners.id=ID runners.name=Name @@ -2997,10 +3039,16 @@ runners.labels=Labels runners.task_list.run=Ausführen runners.task_list.repository=Repository runners.task_list.commit=Commit +runners.status.unspecified=Unbekannt +runners.status.idle=Inaktiv runners.status.active=Aktiv +runners.status.offline=Offline runners.version=Version +runs.all_workflows=Alle Workflows runs.commit=Commit +runs.pushed_by=Gepushed von +runs.no_matching_runner_helper=Kein passender Runner: %s [projects] diff --git a/options/locale/locale_el-GR.ini b/options/locale/locale_el-GR.ini index 288181afcdf0c..5bea835e79ac7 100644 --- a/options/locale/locale_el-GR.ini +++ b/options/locale/locale_el-GR.ini @@ -408,7 +408,7 @@ hi_user_x=Γειά σου %s, activate_account=Παρακαλώ ενεργοποιήστε το λογαριασμό σας activate_account.title=%s, παρακαλώ ενεργοποιήστε το λογαριασμό σας -activate_account.text_1=Γεια σας %[1]s, ευχαριστούμε για την εγγραφή στο %[2]! +activate_account.text_1=Γεια σας %[1]s, ευχαριστούμε για την εγγραφή στο %[2]s! activate_account.text_2=Παρακαλούμε κάντε κλικ στον παρακάτω σύνδεσμο για να ενεργοποιήσετε το λογαριασμό σας μέσα σε %s: activate_email=Επιβεβαιώστε τη διεύθυνση email σας @@ -462,7 +462,7 @@ repo.collaborator.added.subject=%s σας πρόσθεσε στο %s repo.collaborator.added.text=Έχετε προστεθεί ως συνεργάτης του αποθετηρίου: team_invite.subject=%[1]s σας προσκάλεσε να συμμετέχετε στον οργανισμό %[2]s -team_invite.text_1=%[1]s σας προσκάλεσε να συμμετέχετε στην ομάδα %[2]s στον οργανισμός %[3]. +team_invite.text_1=%[1]s σας προσκάλεσε να συμμετέχετε στην ομάδα %[2]s στον οργανισμός %[3]s. team_invite.text_2=Παρακαλώ κάντε κλικ στον παρακάτω σύνδεσμο για να συμμετάσχετε στην ομάδα: team_invite.text_3=Σημείωση: Αυτή η πρόσκληση προοριζόταν για %[1]s. Αν δεν περιμένατε αυτή την πρόσκληση, μπορείτε να αγνοήσετε αυτό το email. @@ -2565,7 +2565,7 @@ dashboard.task.process=Εργασία: %[1]s dashboard.task.cancelled=Εργασία: %[1]s ακυρώθηκε: %[3]s dashboard.task.error=Σφάλμα στην Εργασία: %[1]s: %[3]s dashboard.task.finished=Εργασία: %[1]s που εκκινήθηκε από %[2]s τελείωσε -dashboard.task.unknown=Άγνωστη εργασία: %[1] +dashboard.task.unknown=Άγνωστη εργασία: %[1]s dashboard.cron.started=Εκκίνηση Προγραμματισμένης Εργασίας: %[1]s dashboard.cron.process=Προγραμματισμένη Εργασία: %[1]s dashboard.cron.cancelled=Προγραμματισμένη Εργασία: %s ακυρώθηκε: %[3]s diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index ff59fbc96f9dd..f10d6620ff0d6 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -2650,7 +2650,7 @@ dashboard.task.finished=Task: %[1]s started by %[2]s has finished dashboard.task.unknown=Unknown task: %[1]s dashboard.cron.started=Started Cron: %[1]s dashboard.cron.process=Cron: %[1]s -dashboard.cron.cancelled=Cron: %s cancelled: %[3]s +dashboard.cron.cancelled=Cron: %[1]s cancelled: %[3]s dashboard.cron.error=Error in Cron: %s: %[3]s dashboard.cron.finished=Cron: %[1]s has finished dashboard.delete_inactive_accounts = Delete all unactivated accounts @@ -3463,7 +3463,7 @@ runners.reset_registration_token_success = Runner registration token reset succe runs.all_workflows = All Workflows runs.commit = Commit -runs.pushed_by = Pushed by +runs.pushed_by = pushed by runs.invalid_workflow_helper = Workflow config file is invalid. Please check your config file: %s runs.no_matching_runner_helper = No matching runner: %s runs.actor = Actor diff --git a/options/locale/locale_fa-IR.ini b/options/locale/locale_fa-IR.ini index a2995f5100d4f..7d9f49c1a883d 100644 --- a/options/locale/locale_fa-IR.ini +++ b/options/locale/locale_fa-IR.ini @@ -357,7 +357,7 @@ reset_password.text=لطفاً روی پیوند زیر کلیک کنید تا register_success=ثبت‌نام با موفقیت انجام شد -issue_assigned.pull=@%[1] به شما برای درخواست pull %[2] در ریپازیتوری %[3] محول شده. +issue_assigned.pull=@%[1]s به شما برای درخواست pull %[2]s در ریپازیتوری %[3]s محول شده. issue_assigned.issue=@%[1]s به شما واگذار شده است برای صدور %[2]s در انبار %[3]s. issue.x_mentioned_you=@%s به شما اشاره کرد: diff --git a/options/locale/locale_is-IS.ini b/options/locale/locale_is-IS.ini index 42ed8c5f249e2..977f22bf292f2 100644 --- a/options/locale/locale_is-IS.ini +++ b/options/locale/locale_is-IS.ini @@ -803,7 +803,7 @@ issues.action_milestone=Tímamót issues.action_milestone_no_select=Ekkert tímamót issues.action_assignee=Úthlutað að issues.opened_by=opnað %[1]s af %[3]s -issues.opened_by_fake=opnað %[1] af %[2]s +issues.opened_by_fake=opnað %[1]s af %[2]s issues.previous=Fyrri issues.next=Áfram issues.open_title=Opið diff --git a/options/locale/locale_lv-LV.ini b/options/locale/locale_lv-LV.ini index 2d5b40bd0b68f..4e99d52fa735f 100644 --- a/options/locale/locale_lv-LV.ini +++ b/options/locale/locale_lv-LV.ini @@ -438,7 +438,7 @@ repo.collaborator.added.subject=%s pievienoja Jūs repozitorijam %s repo.collaborator.added.text=Jūs tikāt pievienots kā līdzstrādnieks repozitorijam: team_invite.subject=%[1]s uzaicināja Jūs pievienoties organizācijai %[2]s -team_invite.text_1=%[1]s uzaicināja Jūs pievienoties komandai %[2] organizācijā %[3]s. +team_invite.text_1=%[1]s uzaicināja Jūs pievienoties komandai %[2]s organizācijā %[3]s. team_invite.text_2=Uzspiediet uz šīs saites, lai pievienoties komandai: team_invite.text_3=Piezīme: Šis uzaicinājums ir paredzēts %[1]s. Ja uzskatāt, ka tas nav domāts Jums, varat ignorēt šo e-pastu. diff --git a/options/locale/locale_nl-NL.ini b/options/locale/locale_nl-NL.ini index f68ec11bbaf89..2eca35e81e99e 100644 --- a/options/locale/locale_nl-NL.ini +++ b/options/locale/locale_nl-NL.ini @@ -384,7 +384,7 @@ reset_password.text=Klik op de volgende link om je account te herstellen binnen register_success=Registratie succesvol issue_assigned.pull=@%[1]s heeft u toegewezen aan de pull request %[2]s in repository %[3]s. -issue_assigned.issue=@%[1]heeft u toegewezen aan issue %[2]s in repository %[3]s. +issue_assigned.issue=@%[1]s heeft u toegewezen aan issue %[2]s in repository %[3]s. issue.x_mentioned_you=@%s heeft u vermeld: issue.action.force_push=%[1]s heeft een force-push uitgevoerd %[2]s van %[3]s naar %[4]s. @@ -392,7 +392,7 @@ issue.action.push_1=@%[1]s heeft %[3]d commits gepusht naar %[2]s issue.action.push_n=@%[1]s heeft %[3]d commits gepusht naar %[2]s issue.action.close=@%[1]s sloot #%[2]d. issue.action.reopen=@%[1]s heropend #%[2]d. -issue.action.merge=@%[1] heeft een merge uitgevoerd van #%[2]d naar %[3]s. +issue.action.merge=@%[1]s heeft een merge uitgevoerd van #%[2]d naar %[3]s. issue.action.approve=@%[1]s heeft deze pull request goedgekeurd. issue.action.reject=@%[1]s vraagt om wijzigingen op deze pull request. issue.action.review=@%[1]s heeft gereageerd op deze pull request. diff --git a/options/locale/locale_pl-PL.ini b/options/locale/locale_pl-PL.ini index 32a4582db36c1..09384f28bfc30 100644 --- a/options/locale/locale_pl-PL.ini +++ b/options/locale/locale_pl-PL.ini @@ -2494,7 +2494,7 @@ monitor.queue.review=Przejrzyj konfigurację monitor.queue.review_add=Przejrzyj/Dodaj procesy pracujące monitor.queue.settings.title=Ustawienia Puli monitor.queue.settings.maxnumberworkers=Maksymalna liczba procesów pracujących -monitor.queue.settings.maxnumberworkers.placeholder=Obecnie %[1]v +monitor.queue.settings.maxnumberworkers.placeholder=Obecnie %[1]d monitor.queue.settings.maxnumberworkers.error=Maksymalna liczba procesów pracujących musi być liczbą monitor.queue.settings.submit=Aktualizuj ustawienia monitor.queue.settings.changed=Zaktualizowano ustawienia diff --git a/options/locale/locale_pt-BR.ini b/options/locale/locale_pt-BR.ini index dfffb92d2f679..a4cf7dd4531db 100644 --- a/options/locale/locale_pt-BR.ini +++ b/options/locale/locale_pt-BR.ini @@ -437,7 +437,7 @@ reset_password.text=Por favor clique no link a seguir para recuperar sua conta e register_success=Cadastro bem-sucedido -issue_assigned.pull=@%[1]atribuiu a você o pull request %[2]s no repositório %[3]s. +issue_assigned.pull=@%[1]s atribuiu a você o pull request %[2]s no repositório %[3]s. issue_assigned.issue=@%[1]s atribuiu a você a issue %[2]s no repositório %[3]s. issue.x_mentioned_you=@%s mencionou você: @@ -1535,7 +1535,7 @@ issues.due_date_form_remove=Remover issues.due_date_not_writer=Você deve ter permissão de escrita no repositório para atualizar a data limite de uma issue. issues.due_date_not_set=Data limite não informada. issues.due_date_added=adicionou a data limite %s %s -issues.due_date_modified=modificou a data limite de %[2]para %[1]s %[3]s +issues.due_date_modified=modificou a data limite de %[2]s para %[1]s %[3]s issues.due_date_remove=removeu a data limite %s %s issues.due_date_overdue=Em atraso issues.due_date_invalid=A data limite é inválida ou está fora do intervalo. Por favor, use o formato 'dd/mm/aaaa'. @@ -2557,7 +2557,7 @@ dashboard.clean_unbind_oauth_success=Todas as conexões de OAuth não vinculadas dashboard.task.started=Tarefa Iniciada: %[1]s dashboard.task.process=Tarefa: %[1]s dashboard.task.cancelled=Tarefa: %[1]s cancelada: %[3]s -dashboard.task.error=Erro na Tarefa: %[1]: %[3]s +dashboard.task.error=Erro na Tarefa: %[1]s: %[3]s dashboard.task.finished=Tarefa: %[1]s iniciada por %[2]s foi finalizada dashboard.task.unknown=Tarefa desconhecida: %[1]s dashboard.cron.started=Cron Iniciado: %[1]s diff --git a/options/locale/locale_ru-RU.ini b/options/locale/locale_ru-RU.ini index 3688a42d71fc2..0fe6277695337 100644 --- a/options/locale/locale_ru-RU.ini +++ b/options/locale/locale_ru-RU.ini @@ -472,7 +472,7 @@ repo.transfer.body=Для того чтобы принять или отклон repo.collaborator.added.subject=%s добавил(а) вас в %s repo.collaborator.added.text=Вы были добавлены в качестве соавтора репозитория: -team_invite.subject=%[1] приглашает вас присоединиться к организации %[2] +team_invite.subject=%[1]s приглашает вас присоединиться к организации %[2]s team_invite.text_1=%[1]s приглашает вас присоединиться к команде %[2]s в организации %[3]s. team_invite.text_2=Перейдите по ссылке, чтобы присоединиться к команде: team_invite.text_3=Примечание: Это приглашение было направлено для %[1]s. Если вы не ожидали этого приглашения, можете проигнорировать это письмо. diff --git a/options/locale/locale_si-LK.ini b/options/locale/locale_si-LK.ini index 58e2fe044a471..009594dfdb11d 100644 --- a/options/locale/locale_si-LK.ini +++ b/options/locale/locale_si-LK.ini @@ -353,17 +353,17 @@ issue.action.push_1=@%[1]s pushed%[3]d%[2]s කිරීමට කැප issue.action.push_n=@%[1]s pushed%[3]d%[2]s දක්වා කැපේ issue.action.close=@%[1]s වසා #%[2]d. issue.action.reopen=@%[1]s නැවත විවෘත කරන ලද #%[2]d. -issue.action.merge=@%[1]ගේ ඒකාබද්ධ #%[2]ඈ into%[3]s. +issue.action.merge=@%[1]s ගේ ඒකාබද්ධ #%[2]d ඈ into%[3]s. issue.action.approve=@%[1]s මෙම අදින්න ඉල්ලීම අනුමත. issue.action.reject=@%[1]s මෙම අදින්න ඉල්ලීම මත වෙනස්කම් ඉල්ලා. issue.action.review=@%[1]s මෙම අදින්න ඉල්ලීම පිළිබඳව අදහස් දැක්වීය. issue.action.review_dismissed=@%[1]s මෙම අදින්න ඉල්ලීම සඳහා%[2]s සිට පසුගිය සමාලෝචනය බැහැර. issue.action.ready_for_review=@%[1]s සමාලෝචනය සඳහා සූදානම් මෙම අදින්න ඉල්ලීම සලකුණු. -issue.action.new=@%[1]ගේ නිර්මාණය #%[2]ඈ. +issue.action.new=@%[1]s ගේ නිර්මාණය #%[2]d ඈ. issue.in_tree_path=%sදී: release.new.subject=%s %s නිදහස් -release.new.text=@%[1]හි නිකුතුව%[2]හි[3]හි +release.new.text=@%[1]s හි නිකුතුව%[2]s හි %[3]s හි release.title=සිරැසිය: %s release.note=සටහන: release.downloads=බාගැනීම්: @@ -844,7 +844,7 @@ migrate.permission_denied_blocked=ඔබට අවසර නොලත් ධා migrate.invalid_lfs_endpoint=මෙම LFS අවසන් ලක්ෂ්යය වලංගු නොවේ. migrate.failed=සංක්රමණය අසාර්ථකයි: %v migrate.migrate_items_options=අමතර අයිතම සංක්රමණය කිරීම සඳහා ප්රවේශ ටෝකනය අවශ්ය වේ -migrated_from=%[2]සිටදක්වා සංක්රමණය වී ඇත +migrated_from=%[2]s සිටදක්වා සංක්රමණය වී ඇත migrated_from_fake=සංක්රමණය වූ ගෙම්%[1]s migrate.migrate=%sසිට සංක්රමණය migrate.migrating=%s සිට සංක්රමණය වීම... @@ -1071,7 +1071,7 @@ issues.remove_ref_at=`ඉවත් කරන ලද යොමු %s %s` issues.add_ref_at=`එකතු කරන ලද යොමු %s %s` issues.delete_branch_at=`මකාදැමූ ශාඛාව %s %s` issues.filter_label=ලේබලය -issues.filter_label_exclude=Labels` ඉවත් කිරීමට alt + ක්ලික් කරන්න/ඇතුළු කරන්න +issues.filter_label_exclude=ලේබල බැහැර කිරීමට alt + click/enter භාවිත කරන්න issues.filter_label_no_select=සියලු ලේබල issues.filter_label_select_no_label=ලේබලයක් නැත issues.filter_milestone=සන්ධිස්ථානය @@ -1127,7 +1127,7 @@ issues.reopen_comment_issue=අදහස් දක්වා විවෘත ක issues.create_comment=අදහස issues.closed_at=`මෙම ගැටළුව වසා %[2]s` issues.reopened_at=`මෙම ගැටළුව නැවත විවෘත කරන ලදි %[2]s` -issues.ref_issue_from=මෙම නිකුතුව%[4]හි %[2]s +issues.ref_issue_from=මෙම නිකුතුව %[4]s හි %[2]s issues.ref_pull_from=මෙම අදින්න ඉල්ලීම%[4]s %[2]s issues.ref_closing_from=මෙම ගැටළුව වසා දමනු ඇත%[4]s මෙම ගැටළුව %[2]s issues.ref_reopening_from=මෙම ගැටළුව නැවත විවෘත කරනු ඇත%[4]s මෙම ගැටළුව %[2]s @@ -1214,7 +1214,7 @@ issues.error_modifying_due_date=නියමිත දිනය වෙනස් issues.error_removing_due_date=නියමිත දිනය ඉවත් කිරීමට අපොහොසත් විය. issues.push_commit_1=එකතු %d කැප %s issues.push_commits_n=එකතු %d විවරයන් %s -issues.force_push_codes=`බලය-pushed%[1]s සිට %[2]s %[4]ගේ %[6]s` +issues.force_push_codes=`බලය-pushed%[1]s සිට %[2]s %[4]s ගේ %[6]s` issues.force_push_compare=සසඳන්න issues.due_date_form=Yyy-mm-dd issues.due_date_form_add=නියමිත දිනය එකතු කරන්න @@ -2039,7 +2039,7 @@ members.member_role=සාමාජික කාර්යභාරය: members.owner=හිමිකරු members.member=සාමාජික members.remove=ඉවත් කරන්න -members.remove.detail=%[1]ගේ සිට%[2]ගේ ඉවත්? +members.remove.detail=%[1]s ගේ සිට%[2]s ගේ ඉවත්? members.leave=හැරයන්න members.leave.detail=%s හැරයනවාද? members.invite_desc=%sවෙත නව සාමාජිකයෙකු එක් කරන්න: @@ -2111,13 +2111,13 @@ dashboard.clean_unbind_oauth=පිරිසිදු නොබැඳි OAUTH dashboard.clean_unbind_oauth_success=සියලුම නොබැඳි OAUTH සම්බන්ධතා මකා දමා ඇත. dashboard.task.started=ආරම්භ කාර්යය:%[1]s dashboard.task.process=කාර්යය:%[1]s -dashboard.task.cancelled=කාර්යය:%[1]ගේ අවලංගු:%[3]ගේ +dashboard.task.cancelled=කාර්යය: %[1]s ගේ අවලංගු: %[3]s ගේ dashboard.task.error=කාර්යයයේ දෝෂය:%[1]s:%[3]s dashboard.task.finished=කාර්යය:%[1]s[2]s විසින් ආරම්භ කර ඇත dashboard.task.unknown=නොදන්නා කාර්යය:%[1]s dashboard.cron.started=ආරම්භ Con:%[1]s dashboard.cron.process=ක්රෝන්:%[1]s -dashboard.cron.cancelled=Con: %s අවලංගු:%[3]ගේ +dashboard.cron.cancelled=Cron: %s අවලංගු:%[3]sගේ dashboard.cron.error=ක්රෝන් හි දෝෂය: %s:%[3]s dashboard.cron.finished=ක්රෝන්:%[1]s අවසන් වී ඇත dashboard.delete_inactive_accounts=සියලුම අක්රීය ගිණුම් මකන්න @@ -2551,16 +2551,16 @@ comment_issue=`නිකුතුව පිළිබඳ අදහස් %[3]s #%[2]s` merge_pull_request=`ඒකාබද්ධ අදින්න ඉල්ලීම %[3]s #%[2]s` transfer_repo=මාරු කරන ලද ගබඩාව %s සිට %s -push_tag=තල්ලු ටැගය %[3]ගේ %[4]ගේ -delete_tag=මකාදැමුවා ටැගය%[2]සිට %[3]s -delete_branch=මකාදැමූ ශාඛාව%[2]සිට %[3]s +push_tag=තල්ලු ටැගය %[3]s ගේ %[4]s ගේ +delete_tag=මකාදැමුවා ටැගය%[2]s සිට %[3]s +delete_branch=මකාදැමූ ශාඛාව %[2]s සිට %[3]s compare_branch=සසඳන්න compare_commits=%d විවරයන් සසඳා බලන්න compare_commits_general=විවරයන් සසඳා බලන්න mirror_sync_push=සමමුහුර්ත %[3]s%[4]s කැඩපත සිට mirror_sync_create=සමමුහුර්ත නව යොමු %[3]s සිට %[4]s කැඩපත සිට mirror_sync_delete=සමමුහුර්ත සහ මකාදැමූ යොමු %[2]s හි %[3]s කැඩපතෙන් -approve_pull_request=`අනුමත %[3]s #%[2]ගේ` +approve_pull_request=`අනුමත %[3]s #%[2]s ගේ` reject_pull_request=%[3]s #%[2]sසඳහා යෝජිත වෙනස්කම් publish_release=`නිදහස් "%[4]s" හි %[3]s` review_dismissed_reason=හේතුව: diff --git a/options/locale/locale_sk-SK.ini b/options/locale/locale_sk-SK.ini index 2ac69fe196ec5..4132b2d4a3a3e 100644 --- a/options/locale/locale_sk-SK.ini +++ b/options/locale/locale_sk-SK.ini @@ -382,7 +382,7 @@ reset_password.text=Pre obnovenie vašeho účtu kliknite, prosím, na nasledovn register_success=Registrácia prebehla úspešne -issue_assigned.pull=@%[1]s vám pridelil pull request %[2] v repozitári %[3]s. +issue_assigned.pull=@%[1]s vám pridelil pull request %[2]s repozitári %[3]s. issue_assigned.issue=@%[1]s vám pridelil úkol %[2]s v repozitári %[3]s. issue.x_mentioned_you=@%s vás zmienil: @@ -397,7 +397,7 @@ issue.action.reject=@%[1]s požadoval zmeny v tomto pull requeste. issue.action.review=@%[1]s okomentoval tento pull request. issue.action.review_dismissed=@%[1]s zamietol poslednú recenziu od %[2]s pre tento pull request. issue.action.ready_for_review=@%[1]s označil tento pull request ako pripravený na revíziu. -issue.action.new=@%[1] vytvoril/a #%[2]d. +issue.action.new=@%[1]s vytvoril/a #%[2]d. issue.in_tree_path=V %s: release.new.subject=%s v %s vydané diff --git a/options/locale/locale_tr-TR.ini b/options/locale/locale_tr-TR.ini index 71b92cbee111e..c75b60af44e60 100644 --- a/options/locale/locale_tr-TR.ini +++ b/options/locale/locale_tr-TR.ini @@ -461,10 +461,10 @@ repo.transfer.body=Kabul veya reddetmek için %s ziyaret edin veya görmezden ge repo.collaborator.added.subject=%s sizi %s ekledi repo.collaborator.added.text=Bu depo için katkıcı olarak eklendiniz: -team_invite.subject=%[1] sizi %[2] organizasyonuna katılmaya davet etti -team_invite.text_1=%[1] sizi %[3] organizasyonundaki %[2] takımına katılmaya davet etti. +team_invite.subject=%[1]s sizi %[2]s organizasyonuna katılmaya davet etti +team_invite.text_1=%[1]s sizi %[3]s organizasyonundaki %[2]s takımına katılmaya davet etti. team_invite.text_2=Takıma katılmak lütfen aşağıdaki bağlantıya tıklayın: -team_invite.text_3=Not: Bu davet %[1] içindi. Bu daveti beklemiyorsanız, e-postayı yok sayabilirsiniz. +team_invite.text_3=Not: Bu davet %[1]s içindi. Bu daveti beklemiyorsanız, e-postayı yok sayabilirsiniz. [modal] yes=Evet diff --git a/options/locale/locale_uk-UA.ini b/options/locale/locale_uk-UA.ini index 9a4476d1d1538..1eaf6ae3b541c 100644 --- a/options/locale/locale_uk-UA.ini +++ b/options/locale/locale_uk-UA.ini @@ -1182,10 +1182,10 @@ issues.create_comment=Коментар issues.closed_at=`закрив цю задачу %[2]s` issues.reopened_at=`повторно відкрив цю задачу %[2]s` issues.commit_ref_at=`згадано цю задачу в коміті %[2]s` -issues.ref_issue_from=`посилання на цю задачу %[4] %[2]s` +issues.ref_issue_from=`посилання на цю задачу %[4]s %[2]s` issues.ref_pull_from=`послався на цей запит злиття %[4]s %[2]s` -issues.ref_closing_from=`згадав запит на злиття %[4]с, які закриють цю задачу %[2]s` -issues.ref_reopening_from=`згадав запит на злиття %[4]с, які повторно відкриють цю задачу %[2]s` +issues.ref_closing_from=`згадав запит на злиття %[4]s, які закриють цю задачу %[2]s` +issues.ref_reopening_from=`згадав запит на злиття %[4]s, які повторно відкриють цю задачу %[2]s` issues.ref_closed_from=`закрив цю задачу %[4]s %[2]s` issues.ref_reopened_from=`повторно відкрито цю задачу %[4]s %[2]s` issues.ref_from=`із %[1]s` @@ -1269,7 +1269,7 @@ issues.error_modifying_due_date=Не вдалося змінити дату за issues.error_removing_due_date=Не вдалося видалити дату завершення. issues.push_commit_1=додав %d коміт %s issues.push_commits_n=додав %d коміти(-ів) %s -issues.force_push_codes=`примусово залито %[1]s з %[2] до %[4]s %[6]s` +issues.force_push_codes=`примусово залито %[1]s з %[2]s до %[4]s %[6]s` issues.force_push_compare=Порівняти issues.due_date_form=рррр-мм-дд issues.due_date_form_add=Додати дату завершення @@ -2613,7 +2613,7 @@ comment_issue=`прокоментував задачу %[3]s#%[2 comment_pull=`прокоментував запит злиття %[3]s#%[2]s` merge_pull_request=`прийняв запит злиття %[3]s#%[2]s` transfer_repo=перенесено репозиторій %s у %s -push_tag=створив мітку %[3] в %[4]s +push_tag=створив мітку %[3]s в %[4]s delete_tag=видалено мітку %[2]s з %[3]s delete_branch=видалено гілку %[2]s з %[3]s compare_branch=Порівняти @@ -2622,14 +2622,14 @@ compare_commits_general=Порівняти коміти mirror_sync_push=синхронізував коміти в %[3]s в %[4]s із дзеркала mirror_sync_create=синхронізував нове посилання %[3]s в %[4]s із дзеркала mirror_sync_delete=синхронізовано й видалено посилання %[2]s на %[3]s із дзеркала -approve_pull_request=`схвалив %[3]s#%[2]` +approve_pull_request=`схвалив %[3]s#%[2]s` reject_pull_request=`запропонував зміни до %[3]s#%[2]s` publish_release=`опублікував випуск "%[4]s" з %[3]s` -review_dismissed=`відхилив відгук від %[4] для %[3]s#%[2]s` +review_dismissed=`відхилив відгук від %[4]s для %[3]s#%[2]s` review_dismissed_reason=Причина: create_branch=створив гілку %[3]s в %[4]s starred_repo=додав %[2]s у обране -watched_repo=почав слідкувати за %[2] +watched_repo=почав слідкувати за %[2]s [tool] now=зараз diff --git a/routers/api/actions/runner/utils.go b/routers/api/actions/runner/utils.go index 3370355f15c75..834a8c44000c7 100644 --- a/routers/api/actions/runner/utils.go +++ b/routers/api/actions/runner/utils.go @@ -116,7 +116,7 @@ func getVariablesOfTask(ctx context.Context, task *actions_model.ActionTask) map } func generateTaskContext(t *actions_model.ActionTask) *structpb.Struct { - event := map[string]interface{}{} + event := map[string]any{} _ = json.Unmarshal([]byte(t.Job.Run.EventPayload), &event) // TriggerEvent is added in https://github.com/go-gitea/gitea/pull/25229 @@ -136,7 +136,7 @@ func generateTaskContext(t *actions_model.ActionTask) *structpb.Struct { refName := git.RefName(t.Job.Run.Ref) - taskContext, err := structpb.NewStruct(map[string]interface{}{ + taskContext, err := structpb.NewStruct(map[string]any{ // standard contexts, see https://docs.github.com/en/actions/learn-github-actions/contexts#github-context "action": "", // string, The name of the action currently running, or the id of a step. GitHub removes special characters, and uses the name __run when the current step runs a script without an id. If you use the same action more than once in the same job, the name will include a suffix with the sequence number with underscore before it. For example, the first script you run will have the name __run, and the second script will be named __run_2. Similarly, the second invocation of actions/checkout will be actionscheckout2. "action_path": "", // string, The path where an action is located. This property is only supported in composite actions. You can use this path to access files located in the same repository as the action. diff --git a/routers/api/packages/alpine/alpine.go b/routers/api/packages/alpine/alpine.go index 9a551a219b64b..51a5c784e0280 100644 --- a/routers/api/packages/alpine/alpine.go +++ b/routers/api/packages/alpine/alpine.go @@ -24,7 +24,7 @@ import ( alpine_service "code.gitea.io/gitea/services/packages/alpine" ) -func apiError(ctx *context.Context, status int, obj interface{}) { +func apiError(ctx *context.Context, status int, obj any) { helper.LogAndProcessError(ctx, status, obj, func(message string) { ctx.PlainText(status, message) }) @@ -68,7 +68,7 @@ func GetRepositoryFile(ctx *context.Context) { return } - s, pf, err := packages_service.GetFileStreamByPackageVersion( + s, u, pf, err := packages_service.GetFileStreamByPackageVersion( ctx, pv, &packages_service.PackageFileInfo{ @@ -84,12 +84,8 @@ func GetRepositoryFile(ctx *context.Context) { } return } - defer s.Close() - ctx.ServeContent(s, &context.ServeHeaderOptions{ - Filename: pf.Name, - LastModified: pf.CreatedUnix.AsLocalTime(), - }) + helper.ServePackageFile(ctx, s, u, pf) } func UploadPackageFile(ctx *context.Context) { @@ -200,7 +196,7 @@ func DownloadPackageFile(ctx *context.Context) { return } - s, pf, err := packages_service.GetPackageFileStream(ctx, pfs[0]) + s, u, pf, err := packages_service.GetPackageFileStream(ctx, pfs[0]) if err != nil { if errors.Is(err, util.ErrNotExist) { apiError(ctx, http.StatusNotFound, err) @@ -209,12 +205,8 @@ func DownloadPackageFile(ctx *context.Context) { } return } - defer s.Close() - ctx.ServeContent(s, &context.ServeHeaderOptions{ - Filename: pf.Name, - LastModified: pf.CreatedUnix.AsLocalTime(), - }) + helper.ServePackageFile(ctx, s, u, pf) } func DeletePackageFile(ctx *context.Context) { diff --git a/routers/api/packages/cargo/cargo.go b/routers/api/packages/cargo/cargo.go index b666bdde6c9f2..a2e835df578b4 100644 --- a/routers/api/packages/cargo/cargo.go +++ b/routers/api/packages/cargo/cargo.go @@ -33,7 +33,7 @@ type StatusMessage struct { Message string `json:"detail"` } -func apiError(ctx *context.Context, status int, obj interface{}) { +func apiError(ctx *context.Context, status int, obj any) { helper.LogAndProcessError(ctx, status, obj, func(message string) { ctx.JSON(status, StatusResponse{ OK: false, @@ -165,7 +165,7 @@ func ListOwners(ctx *context.Context) { // DownloadPackageFile serves the content of a package func DownloadPackageFile(ctx *context.Context) { - s, pf, err := packages_service.GetFileStreamByPackageNameAndVersion( + s, u, pf, err := packages_service.GetFileStreamByPackageNameAndVersion( ctx, &packages_service.PackageInfo{ Owner: ctx.Package.Owner, @@ -185,12 +185,8 @@ func DownloadPackageFile(ctx *context.Context) { apiError(ctx, http.StatusInternalServerError, err) return } - defer s.Close() - ctx.ServeContent(s, &context.ServeHeaderOptions{ - Filename: pf.Name, - LastModified: pf.CreatedUnix.AsLocalTime(), - }) + helper.ServePackageFile(ctx, s, u, pf) } // https://doc.rust-lang.org/cargo/reference/registries.html#publish diff --git a/routers/api/packages/chef/chef.go b/routers/api/packages/chef/chef.go index b48b1778c42d1..908f9fc4be1b2 100644 --- a/routers/api/packages/chef/chef.go +++ b/routers/api/packages/chef/chef.go @@ -24,7 +24,7 @@ import ( packages_service "code.gitea.io/gitea/services/packages" ) -func apiError(ctx *context.Context, status int, obj interface{}) { +func apiError(ctx *context.Context, status int, obj any) { type Error struct { ErrorMessages []string `json:"error_messages"` } @@ -341,17 +341,13 @@ func DownloadPackage(ctx *context.Context) { pf := pd.Files[0].File - s, _, err := packages_service.GetPackageFileStream(ctx, pf) + s, u, _, err := packages_service.GetPackageFileStream(ctx, pf) if err != nil { apiError(ctx, http.StatusInternalServerError, err) return } - defer s.Close() - ctx.ServeContent(s, &context.ServeHeaderOptions{ - Filename: pf.Name, - LastModified: pf.CreatedUnix.AsLocalTime(), - }) + helper.ServePackageFile(ctx, s, u, pf) } // https://github.com/chef/chef/blob/main/knife/lib/chef/knife/supermarket_unshare.rb diff --git a/routers/api/packages/composer/composer.go b/routers/api/packages/composer/composer.go index d93b11efdf66d..bf5bda743f560 100644 --- a/routers/api/packages/composer/composer.go +++ b/routers/api/packages/composer/composer.go @@ -26,7 +26,7 @@ import ( "github.com/hashicorp/go-version" ) -func apiError(ctx *context.Context, status int, obj interface{}) { +func apiError(ctx *context.Context, status int, obj any) { helper.LogAndProcessError(ctx, status, obj, func(message string) { type Error struct { Status int `json:"status"` @@ -162,7 +162,7 @@ func PackageMetadata(ctx *context.Context) { // DownloadPackageFile serves the content of a package func DownloadPackageFile(ctx *context.Context) { - s, pf, err := packages_service.GetFileStreamByPackageNameAndVersion( + s, u, pf, err := packages_service.GetFileStreamByPackageNameAndVersion( ctx, &packages_service.PackageInfo{ Owner: ctx.Package.Owner, @@ -182,12 +182,8 @@ func DownloadPackageFile(ctx *context.Context) { apiError(ctx, http.StatusInternalServerError, err) return } - defer s.Close() - ctx.ServeContent(s, &context.ServeHeaderOptions{ - Filename: pf.Name, - LastModified: pf.CreatedUnix.AsLocalTime(), - }) + helper.ServePackageFile(ctx, s, u, pf) } // UploadPackage creates a new package diff --git a/routers/api/packages/conan/conan.go b/routers/api/packages/conan/conan.go index caeb8c11bc4c8..6e1727fd76471 100644 --- a/routers/api/packages/conan/conan.go +++ b/routers/api/packages/conan/conan.go @@ -47,7 +47,7 @@ var ( ) ) -func jsonResponse(ctx *context.Context, status int, obj interface{}) { +func jsonResponse(ctx *context.Context, status int, obj any) { // https://github.com/conan-io/conan/issues/6613 ctx.Resp.Header().Set("Content-Type", "application/json") ctx.Status(status) @@ -56,7 +56,7 @@ func jsonResponse(ctx *context.Context, status int, obj interface{}) { } } -func apiError(ctx *context.Context, status int, obj interface{}) { +func apiError(ctx *context.Context, status int, obj any) { helper.LogAndProcessError(ctx, status, obj, func(message string) { jsonResponse(ctx, status, map[string]string{ "message": message, @@ -453,7 +453,7 @@ func downloadFile(ctx *context.Context, fileFilter container.Set[string], fileKe return } - s, pf, err := packages_service.GetFileStreamByPackageNameAndVersion( + s, u, pf, err := packages_service.GetFileStreamByPackageNameAndVersion( ctx, &packages_service.PackageInfo{ Owner: ctx.Package.Owner, @@ -474,12 +474,8 @@ func downloadFile(ctx *context.Context, fileFilter container.Set[string], fileKe apiError(ctx, http.StatusInternalServerError, err) return } - defer s.Close() - ctx.ServeContent(s, &context.ServeHeaderOptions{ - Filename: pf.Name, - LastModified: pf.CreatedUnix.AsLocalTime(), - }) + helper.ServePackageFile(ctx, s, u, pf) } // DeleteRecipeV1 deletes the requested recipe(s) @@ -800,13 +796,13 @@ func listRevisionFiles(ctx *context.Context, fileKey string) { return } - files := make(map[string]interface{}) + files := make(map[string]any) for _, pf := range pfs { files[pf.Name] = nil } type FileList struct { - Files map[string]interface{} `json:"files"` + Files map[string]any `json:"files"` } jsonResponse(ctx, http.StatusOK, &FileList{ diff --git a/routers/api/packages/conda/conda.go b/routers/api/packages/conda/conda.go index f7786906309b1..0bf0fc1f625b3 100644 --- a/routers/api/packages/conda/conda.go +++ b/routers/api/packages/conda/conda.go @@ -24,7 +24,7 @@ import ( "github.com/dsnet/compress/bzip2" ) -func apiError(ctx *context.Context, status int, obj interface{}) { +func apiError(ctx *context.Context, status int, obj any) { helper.LogAndProcessError(ctx, status, obj, func(message string) { ctx.JSON(status, struct { Reason string `json:"reason"` @@ -292,15 +292,11 @@ func DownloadPackageFile(ctx *context.Context) { pf := pfs[0] - s, _, err := packages_service.GetPackageFileStream(ctx, pf) + s, u, _, err := packages_service.GetPackageFileStream(ctx, pf) if err != nil { apiError(ctx, http.StatusInternalServerError, err) return } - defer s.Close() - ctx.ServeContent(s, &context.ServeHeaderOptions{ - Filename: pf.Name, - LastModified: pf.CreatedUnix.AsLocalTime(), - }) + helper.ServePackageFile(ctx, s, u, pf) } diff --git a/routers/api/packages/container/container.go b/routers/api/packages/container/container.go index 63c49809a7be7..126be43cdd59c 100644 --- a/routers/api/packages/container/container.go +++ b/routers/api/packages/container/container.go @@ -75,7 +75,7 @@ func setResponseHeaders(resp http.ResponseWriter, h *containerHeaders) { resp.WriteHeader(h.Status) } -func jsonResponse(ctx *context.Context, status int, obj interface{}) { +func jsonResponse(ctx *context.Context, status int, obj any) { setResponseHeaders(ctx.Resp, &containerHeaders{ Status: status, ContentType: "application/json", @@ -482,22 +482,7 @@ func GetBlob(ctx *context.Context) { return } - s, _, err := packages_service.GetPackageFileStream(ctx, blob.File) - if err != nil { - apiError(ctx, http.StatusInternalServerError, err) - return - } - defer s.Close() - - setResponseHeaders(ctx.Resp, &containerHeaders{ - ContentDigest: blob.Properties.GetByName(container_module.PropertyDigest), - ContentType: blob.Properties.GetByName(container_module.PropertyMediaType), - ContentLength: blob.Blob.Size, - Status: http.StatusOK, - }) - if _, err := io.Copy(ctx.Resp, s); err != nil { - log.Error("Error whilst copying content to response: %v", err) - } + serveBlob(ctx, blob) } // https://github.com/opencontainers/distribution-spec/blob/main/spec.md#deleting-blobs @@ -636,22 +621,7 @@ func GetManifest(ctx *context.Context) { return } - s, _, err := packages_service.GetPackageFileStream(ctx, manifest.File) - if err != nil { - apiError(ctx, http.StatusInternalServerError, err) - return - } - defer s.Close() - - setResponseHeaders(ctx.Resp, &containerHeaders{ - ContentDigest: manifest.Properties.GetByName(container_module.PropertyDigest), - ContentType: manifest.Properties.GetByName(container_module.PropertyMediaType), - ContentLength: manifest.Blob.Size, - Status: http.StatusOK, - }) - if _, err := io.Copy(ctx.Resp, s); err != nil { - log.Error("Error whilst copying content to response: %v", err) - } + serveBlob(ctx, manifest) } // https://github.com/opencontainers/distribution-spec/blob/main/spec.md#deleting-tags @@ -686,6 +656,36 @@ func DeleteManifest(ctx *context.Context) { }) } +func serveBlob(ctx *context.Context, pfd *packages_model.PackageFileDescriptor) { + s, u, _, err := packages_service.GetPackageBlobStream(ctx, pfd.File, pfd.Blob) + if err != nil { + apiError(ctx, http.StatusInternalServerError, err) + return + } + + headers := &containerHeaders{ + ContentDigest: pfd.Properties.GetByName(container_module.PropertyDigest), + ContentType: pfd.Properties.GetByName(container_module.PropertyMediaType), + ContentLength: pfd.Blob.Size, + Status: http.StatusOK, + } + + if u != nil { + headers.Status = http.StatusTemporaryRedirect + headers.Location = u.String() + + setResponseHeaders(ctx.Resp, headers) + return + } + + defer s.Close() + + setResponseHeaders(ctx.Resp, headers) + if _, err := io.Copy(ctx.Resp, s); err != nil { + log.Error("Error whilst copying content to response: %v", err) + } +} + // https://github.com/opencontainers/distribution-spec/blob/main/spec.md#content-discovery func GetTagList(ctx *context.Context) { image := ctx.Params("image") diff --git a/routers/api/packages/cran/cran.go b/routers/api/packages/cran/cran.go index eb3f9a452b1ac..0ef6eff88d65f 100644 --- a/routers/api/packages/cran/cran.go +++ b/routers/api/packages/cran/cran.go @@ -21,7 +21,7 @@ import ( packages_service "code.gitea.io/gitea/services/packages" ) -func apiError(ctx *context.Context, status int, obj interface{}) { +func apiError(ctx *context.Context, status int, obj any) { helper.LogAndProcessError(ctx, status, obj, func(message string) { ctx.PlainText(status, message) }) @@ -249,7 +249,7 @@ func downloadPackageFile(ctx *context.Context, opts *cran_model.SearchOptions) { return } - s, _, err := packages_service.GetPackageFileStream(ctx, pf) + s, u, _, err := packages_service.GetPackageFileStream(ctx, pf) if err != nil { if errors.Is(err, util.ErrNotExist) { apiError(ctx, http.StatusNotFound, err) @@ -258,10 +258,6 @@ func downloadPackageFile(ctx *context.Context, opts *cran_model.SearchOptions) { } return } - defer s.Close() - ctx.ServeContent(s, &context.ServeHeaderOptions{ - Filename: pf.Name, - LastModified: pf.CreatedUnix.AsLocalTime(), - }) + helper.ServePackageFile(ctx, s, u, pf) } diff --git a/routers/api/packages/debian/debian.go b/routers/api/packages/debian/debian.go index cfc03ae522a6f..f7270e0ae0ea6 100644 --- a/routers/api/packages/debian/debian.go +++ b/routers/api/packages/debian/debian.go @@ -23,7 +23,7 @@ import ( debian_service "code.gitea.io/gitea/services/packages/debian" ) -func apiError(ctx *context.Context, status int, obj interface{}) { +func apiError(ctx *context.Context, status int, obj any) { helper.LogAndProcessError(ctx, status, obj, func(message string) { ctx.PlainText(status, message) }) @@ -59,7 +59,7 @@ func GetRepositoryFile(ctx *context.Context) { key += "|" + component + "|" + architecture } - s, pf, err := packages_service.GetFileStreamByPackageVersion( + s, u, pf, err := packages_service.GetFileStreamByPackageVersion( ctx, pv, &packages_service.PackageFileInfo{ @@ -75,12 +75,8 @@ func GetRepositoryFile(ctx *context.Context) { } return } - defer s.Close() - ctx.ServeContent(s, &context.ServeHeaderOptions{ - Filename: pf.Name, - LastModified: pf.CreatedUnix.AsLocalTime(), - }) + helper.ServePackageFile(ctx, s, u, pf) } // https://wiki.debian.org/DebianRepository/Format#indices_acquisition_via_hashsums_.28by-hash.29 @@ -110,7 +106,7 @@ func GetRepositoryFileByHash(ctx *context.Context) { return } - s, pf, err := packages_service.GetPackageFileStream(ctx, pfs[0]) + s, u, pf, err := packages_service.GetPackageFileStream(ctx, pfs[0]) if err != nil { if errors.Is(err, util.ErrNotExist) { apiError(ctx, http.StatusNotFound, err) @@ -119,12 +115,8 @@ func GetRepositoryFileByHash(ctx *context.Context) { } return } - defer s.Close() - ctx.ServeContent(s, &context.ServeHeaderOptions{ - Filename: pf.Name, - LastModified: pf.CreatedUnix.AsLocalTime(), - }) + helper.ServePackageFile(ctx, s, u, pf) } func UploadPackageFile(ctx *context.Context) { @@ -217,7 +209,7 @@ func DownloadPackageFile(ctx *context.Context) { name := ctx.Params("name") version := ctx.Params("version") - s, pf, err := packages_service.GetFileStreamByPackageNameAndVersion( + s, u, pf, err := packages_service.GetFileStreamByPackageNameAndVersion( ctx, &packages_service.PackageInfo{ Owner: ctx.Package.Owner, @@ -238,9 +230,8 @@ func DownloadPackageFile(ctx *context.Context) { } return } - defer s.Close() - ctx.ServeContent(s, &context.ServeHeaderOptions{ + helper.ServePackageFile(ctx, s, u, pf, &context.ServeHeaderOptions{ ContentType: "application/vnd.debian.binary-package", Filename: pf.Name, LastModified: pf.CreatedUnix.AsLocalTime(), diff --git a/routers/api/packages/generic/generic.go b/routers/api/packages/generic/generic.go index 0c873119ef54d..c5866ef9c354b 100644 --- a/routers/api/packages/generic/generic.go +++ b/routers/api/packages/generic/generic.go @@ -22,7 +22,7 @@ var ( filenameRegex = packageNameRegex ) -func apiError(ctx *context.Context, status int, obj interface{}) { +func apiError(ctx *context.Context, status int, obj any) { helper.LogAndProcessError(ctx, status, obj, func(message string) { ctx.PlainText(status, message) }) @@ -30,7 +30,7 @@ func apiError(ctx *context.Context, status int, obj interface{}) { // DownloadPackageFile serves the specific generic package. func DownloadPackageFile(ctx *context.Context) { - s, pf, err := packages_service.GetFileStreamByPackageNameAndVersion( + s, u, pf, err := packages_service.GetFileStreamByPackageNameAndVersion( ctx, &packages_service.PackageInfo{ Owner: ctx.Package.Owner, @@ -50,12 +50,8 @@ func DownloadPackageFile(ctx *context.Context) { apiError(ctx, http.StatusInternalServerError, err) return } - defer s.Close() - ctx.ServeContent(s, &context.ServeHeaderOptions{ - Filename: pf.Name, - LastModified: pf.CreatedUnix.AsLocalTime(), - }) + helper.ServePackageFile(ctx, s, u, pf) } // UploadPackage uploads the specific generic package. diff --git a/routers/api/packages/goproxy/goproxy.go b/routers/api/packages/goproxy/goproxy.go index d0bc9c1e98c37..bacdc4ec62f47 100644 --- a/routers/api/packages/goproxy/goproxy.go +++ b/routers/api/packages/goproxy/goproxy.go @@ -20,7 +20,7 @@ import ( packages_service "code.gitea.io/gitea/services/packages" ) -func apiError(ctx *context.Context, status int, obj interface{}) { +func apiError(ctx *context.Context, status int, obj any) { helper.LogAndProcessError(ctx, status, obj, func(message string) { ctx.PlainText(status, message) }) @@ -105,7 +105,7 @@ func DownloadPackageFile(ctx *context.Context) { return } - s, _, err := packages_service.GetPackageFileStream(ctx, pfs[0]) + s, u, _, err := packages_service.GetPackageFileStream(ctx, pfs[0]) if err != nil { if errors.Is(err, util.ErrNotExist) { apiError(ctx, http.StatusNotFound, err) @@ -114,12 +114,8 @@ func DownloadPackageFile(ctx *context.Context) { } return } - defer s.Close() - ctx.ServeContent(s, &context.ServeHeaderOptions{ - Filename: pfs[0].Name, - LastModified: pfs[0].CreatedUnix.AsLocalTime(), - }) + helper.ServePackageFile(ctx, s, u, pfs[0]) } func resolvePackage(ctx *context.Context, ownerID int64, name, version string) (*packages_model.PackageVersion, error) { diff --git a/routers/api/packages/helm/helm.go b/routers/api/packages/helm/helm.go index b7edc8b7fef8a..9097adf29e7bf 100644 --- a/routers/api/packages/helm/helm.go +++ b/routers/api/packages/helm/helm.go @@ -26,7 +26,7 @@ import ( "gopkg.in/yaml.v3" ) -func apiError(ctx *context.Context, status int, obj interface{}) { +func apiError(ctx *context.Context, status int, obj any) { helper.LogAndProcessError(ctx, status, obj, func(message string) { type Error struct { Error string `json:"error"` @@ -121,7 +121,7 @@ func DownloadPackageFile(ctx *context.Context) { return } - s, pf, err := packages_service.GetFileStreamByPackageVersion( + s, u, pf, err := packages_service.GetFileStreamByPackageVersion( ctx, pvs[0], &packages_service.PackageFileInfo{ @@ -136,12 +136,8 @@ func DownloadPackageFile(ctx *context.Context) { apiError(ctx, http.StatusInternalServerError, err) return } - defer s.Close() - ctx.ServeContent(s, &context.ServeHeaderOptions{ - Filename: pf.Name, - LastModified: pf.CreatedUnix.AsLocalTime(), - }) + helper.ServePackageFile(ctx, s, u, pf) } // UploadPackage creates a new package diff --git a/routers/api/packages/helper/helper.go b/routers/api/packages/helper/helper.go index 660aaec1a3a5f..aadb10376c81e 100644 --- a/routers/api/packages/helper/helper.go +++ b/routers/api/packages/helper/helper.go @@ -5,8 +5,11 @@ package helper import ( "fmt" + "io" "net/http" + "net/url" + packages_model "code.gitea.io/gitea/models/packages" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" @@ -14,7 +17,7 @@ import ( // LogAndProcessError logs an error and calls a custom callback with the processed error message. // If the error is an InternalServerError the message is stripped if the user is not an admin. -func LogAndProcessError(ctx *context.Context, status int, obj interface{}, cb func(string)) { +func LogAndProcessError(ctx *context.Context, status int, obj any, cb func(string)) { var message string if err, ok := obj.(error); ok { message = err.Error() @@ -35,3 +38,26 @@ func LogAndProcessError(ctx *context.Context, status int, obj interface{}, cb fu cb(message) } } + +// Serves the content of the package file +// If the url is set it will redirect the request, otherwise the content is copied to the response. +func ServePackageFile(ctx *context.Context, s io.ReadSeekCloser, u *url.URL, pf *packages_model.PackageFile, forceOpts ...*context.ServeHeaderOptions) { + if u != nil { + ctx.Redirect(u.String()) + return + } + + defer s.Close() + + var opts *context.ServeHeaderOptions + if len(forceOpts) > 0 { + opts = forceOpts[0] + } else { + opts = &context.ServeHeaderOptions{ + Filename: pf.Name, + LastModified: pf.CreatedUnix.AsLocalTime(), + } + } + + ctx.ServeContent(s, opts) +} diff --git a/routers/api/packages/maven/maven.go b/routers/api/packages/maven/maven.go index dd270ff0edd2f..84e3324367814 100644 --- a/routers/api/packages/maven/maven.go +++ b/routers/api/packages/maven/maven.go @@ -47,7 +47,7 @@ var ( illegalCharacters = regexp.MustCompile(`[\\/:"<>|?\*]`) ) -func apiError(ctx *context.Context, status int, obj interface{}) { +func apiError(ctx *context.Context, status int, obj any) { helper.LogAndProcessError(ctx, status, obj, func(message string) { ctx.PlainText(status, message) }) @@ -210,21 +210,15 @@ func servePackageFile(ctx *context.Context, params parameters, serveContent bool return } - s, err := packages_module.NewContentStore().Get(packages_module.BlobHash256Key(pb.HashSHA256)) + s, u, _, err := packages_service.GetPackageBlobStream(ctx, pf, pb) if err != nil { apiError(ctx, http.StatusInternalServerError, err) - } - defer s.Close() - - if pf.IsLead { - if err := packages_model.IncrementDownloadCounter(ctx, pv.ID); err != nil { - log.Error("Error incrementing download counter: %v", err) - } + return } opts.Filename = pf.Name - ctx.ServeContent(s, opts) + helper.ServePackageFile(ctx, s, u, pf, opts) } // UploadPackageFile adds a file to the package. If the package does not exist, it gets created. diff --git a/routers/api/packages/npm/npm.go b/routers/api/packages/npm/npm.go index 89476a776a0dd..3616211d61845 100644 --- a/routers/api/packages/npm/npm.go +++ b/routers/api/packages/npm/npm.go @@ -30,7 +30,7 @@ import ( // errInvalidTagName indicates an invalid tag name var errInvalidTagName = errors.New("The tag name is invalid") -func apiError(ctx *context.Context, status int, obj interface{}) { +func apiError(ctx *context.Context, status int, obj any) { helper.LogAndProcessError(ctx, status, obj, func(message string) { ctx.JSON(status, map[string]string{ "error": message, @@ -83,7 +83,7 @@ func DownloadPackageFile(ctx *context.Context) { packageVersion := ctx.Params("version") filename := ctx.Params("filename") - s, pf, err := packages_service.GetFileStreamByPackageNameAndVersion( + s, u, pf, err := packages_service.GetFileStreamByPackageNameAndVersion( ctx, &packages_service.PackageInfo{ Owner: ctx.Package.Owner, @@ -103,12 +103,8 @@ func DownloadPackageFile(ctx *context.Context) { apiError(ctx, http.StatusInternalServerError, err) return } - defer s.Close() - ctx.ServeContent(s, &context.ServeHeaderOptions{ - Filename: pf.Name, - LastModified: pf.CreatedUnix.AsLocalTime(), - }) + helper.ServePackageFile(ctx, s, u, pf) } // DownloadPackageFileByName finds the version and serves the contents of a package @@ -134,7 +130,7 @@ func DownloadPackageFileByName(ctx *context.Context) { return } - s, pf, err := packages_service.GetFileStreamByPackageVersion( + s, u, pf, err := packages_service.GetFileStreamByPackageVersion( ctx, pvs[0], &packages_service.PackageFileInfo{ @@ -149,12 +145,8 @@ func DownloadPackageFileByName(ctx *context.Context) { apiError(ctx, http.StatusInternalServerError, err) return } - defer s.Close() - ctx.ServeContent(s, &context.ServeHeaderOptions{ - Filename: pf.Name, - LastModified: pf.CreatedUnix.AsLocalTime(), - }) + helper.ServePackageFile(ctx, s, u, pf) } // UploadPackage creates a new package diff --git a/routers/api/packages/nuget/nuget.go b/routers/api/packages/nuget/nuget.go index 716d8a969d665..edeba19b3bbdb 100644 --- a/routers/api/packages/nuget/nuget.go +++ b/routers/api/packages/nuget/nuget.go @@ -25,7 +25,7 @@ import ( packages_service "code.gitea.io/gitea/services/packages" ) -func apiError(ctx *context.Context, status int, obj interface{}) { +func apiError(ctx *context.Context, status int, obj any) { helper.LogAndProcessError(ctx, status, obj, func(message string) { ctx.JSON(status, map[string]string{ "Message": message, @@ -33,7 +33,7 @@ func apiError(ctx *context.Context, status int, obj interface{}) { }) } -func xmlResponse(ctx *context.Context, status int, obj interface{}) { +func xmlResponse(ctx *context.Context, status int, obj any) { ctx.Resp.Header().Set("Content-Type", "application/atom+xml; charset=utf-8") ctx.Resp.WriteHeader(status) if _, err := ctx.Resp.Write([]byte(xml.Header)); err != nil { @@ -362,7 +362,7 @@ func DownloadPackageFile(ctx *context.Context) { packageVersion := ctx.Params("version") filename := ctx.Params("filename") - s, pf, err := packages_service.GetFileStreamByPackageNameAndVersion( + s, u, pf, err := packages_service.GetFileStreamByPackageNameAndVersion( ctx, &packages_service.PackageInfo{ Owner: ctx.Package.Owner, @@ -382,12 +382,8 @@ func DownloadPackageFile(ctx *context.Context) { apiError(ctx, http.StatusInternalServerError, err) return } - defer s.Close() - ctx.ServeContent(s, &context.ServeHeaderOptions{ - Filename: pf.Name, - LastModified: pf.CreatedUnix.AsLocalTime(), - }) + helper.ServePackageFile(ctx, s, u, pf) } // UploadPackage creates a new package with the metadata contained in the uploaded nupgk file @@ -600,7 +596,7 @@ func DownloadSymbolFile(ctx *context.Context) { return } - s, pf, err := packages_service.GetPackageFileStream(ctx, pfs[0]) + s, u, pf, err := packages_service.GetPackageFileStream(ctx, pfs[0]) if err != nil { if err == packages_model.ErrPackageNotExist || err == packages_model.ErrPackageFileNotExist { apiError(ctx, http.StatusNotFound, err) @@ -609,12 +605,8 @@ func DownloadSymbolFile(ctx *context.Context) { apiError(ctx, http.StatusInternalServerError, err) return } - defer s.Close() - ctx.ServeContent(s, &context.ServeHeaderOptions{ - Filename: pf.Name, - LastModified: pf.CreatedUnix.AsLocalTime(), - }) + helper.ServePackageFile(ctx, s, u, pf) } // DeletePackage hard deletes the package diff --git a/routers/api/packages/pub/pub.go b/routers/api/packages/pub/pub.go index ae0c6e7859898..ef07836b8860b 100644 --- a/routers/api/packages/pub/pub.go +++ b/routers/api/packages/pub/pub.go @@ -25,7 +25,7 @@ import ( packages_service "code.gitea.io/gitea/services/packages" ) -func jsonResponse(ctx *context.Context, status int, obj interface{}) { +func jsonResponse(ctx *context.Context, status int, obj any) { resp := ctx.Resp resp.Header().Set("Content-Type", "application/vnd.pub.v2+json") resp.WriteHeader(status) @@ -34,7 +34,7 @@ func jsonResponse(ctx *context.Context, status int, obj interface{}) { } } -func apiError(ctx *context.Context, status int, obj interface{}) { +func apiError(ctx *context.Context, status int, obj any) { type Error struct { Code string `json:"code"` Message string `json:"message"` @@ -60,10 +60,10 @@ type packageVersions struct { } type versionMetadata struct { - Version string `json:"version"` - ArchiveURL string `json:"archive_url"` - Published time.Time `json:"published"` - Pubspec interface{} `json:"pubspec,omitempty"` + Version string `json:"version"` + ArchiveURL string `json:"archive_url"` + Published time.Time `json:"published"` + Pubspec any `json:"pubspec,omitempty"` } func packageDescriptorToMetadata(baseURL string, pd *packages_model.PackageDescriptor) *versionMetadata { @@ -273,15 +273,11 @@ func DownloadPackageFile(ctx *context.Context) { pf := pd.Files[0].File - s, _, err := packages_service.GetPackageFileStream(ctx, pf) + s, u, _, err := packages_service.GetPackageFileStream(ctx, pf) if err != nil { apiError(ctx, http.StatusInternalServerError, err) return } - defer s.Close() - ctx.ServeContent(s, &context.ServeHeaderOptions{ - Filename: pf.Name, - LastModified: pf.CreatedUnix.AsLocalTime(), - }) + helper.ServePackageFile(ctx, s, u, pf) } diff --git a/routers/api/packages/pypi/pypi.go b/routers/api/packages/pypi/pypi.go index 90a37ec2a8f1a..d97b894bbed8a 100644 --- a/routers/api/packages/pypi/pypi.go +++ b/routers/api/packages/pypi/pypi.go @@ -37,7 +37,7 @@ var versionMatcher = regexp.MustCompile(`\Av?` + `(?:\+[a-z0-9]+(?:[-_\.][a-z0-9]+)*)?` + // local version `\z`) -func apiError(ctx *context.Context, status int, obj interface{}) { +func apiError(ctx *context.Context, status int, obj any) { helper.LogAndProcessError(ctx, status, obj, func(message string) { ctx.PlainText(status, message) }) @@ -80,7 +80,7 @@ func DownloadPackageFile(ctx *context.Context) { packageVersion := ctx.Params("version") filename := ctx.Params("filename") - s, pf, err := packages_service.GetFileStreamByPackageNameAndVersion( + s, u, pf, err := packages_service.GetFileStreamByPackageNameAndVersion( ctx, &packages_service.PackageInfo{ Owner: ctx.Package.Owner, @@ -100,12 +100,8 @@ func DownloadPackageFile(ctx *context.Context) { apiError(ctx, http.StatusInternalServerError, err) return } - defer s.Close() - ctx.ServeContent(s, &context.ServeHeaderOptions{ - Filename: pf.Name, - LastModified: pf.CreatedUnix.AsLocalTime(), - }) + helper.ServePackageFile(ctx, s, u, pf) } // UploadPackageFile adds a file to the package. If the package does not exist, it gets created. diff --git a/routers/api/packages/rpm/rpm.go b/routers/api/packages/rpm/rpm.go index 73e457237ab4a..930b20208ae17 100644 --- a/routers/api/packages/rpm/rpm.go +++ b/routers/api/packages/rpm/rpm.go @@ -25,7 +25,7 @@ import ( rpm_service "code.gitea.io/gitea/services/packages/rpm" ) -func apiError(ctx *context.Context, status int, obj interface{}) { +func apiError(ctx *context.Context, status int, obj any) { helper.LogAndProcessError(ctx, status, obj, func(message string) { ctx.PlainText(status, message) }) @@ -65,7 +65,7 @@ func GetRepositoryFile(ctx *context.Context) { return } - s, pf, err := packages_service.GetFileStreamByPackageVersion( + s, u, pf, err := packages_service.GetFileStreamByPackageVersion( ctx, pv, &packages_service.PackageFileInfo{ @@ -80,12 +80,8 @@ func GetRepositoryFile(ctx *context.Context) { } return } - defer s.Close() - ctx.ServeContent(s, &context.ServeHeaderOptions{ - Filename: pf.Name, - LastModified: pf.CreatedUnix.AsLocalTime(), - }) + helper.ServePackageFile(ctx, s, u, pf) } func UploadPackageFile(ctx *context.Context) { @@ -173,7 +169,7 @@ func DownloadPackageFile(ctx *context.Context) { name := ctx.Params("name") version := ctx.Params("version") - s, pf, err := packages_service.GetFileStreamByPackageNameAndVersion( + s, u, pf, err := packages_service.GetFileStreamByPackageNameAndVersion( ctx, &packages_service.PackageInfo{ Owner: ctx.Package.Owner, @@ -193,13 +189,8 @@ func DownloadPackageFile(ctx *context.Context) { } return } - defer s.Close() - ctx.ServeContent(s, &context.ServeHeaderOptions{ - ContentType: "application/x-rpm", - Filename: pf.Name, - LastModified: pf.CreatedUnix.AsLocalTime(), - }) + helper.ServePackageFile(ctx, s, u, pf) } func DeletePackageFile(webctx *context.Context) { diff --git a/routers/api/packages/rubygems/rubygems.go b/routers/api/packages/rubygems/rubygems.go index 740efa9baba8b..88d70f10bdce6 100644 --- a/routers/api/packages/rubygems/rubygems.go +++ b/routers/api/packages/rubygems/rubygems.go @@ -21,7 +21,7 @@ import ( packages_service "code.gitea.io/gitea/services/packages" ) -func apiError(ctx *context.Context, status int, obj interface{}) { +func apiError(ctx *context.Context, status int, obj any) { helper.LogAndProcessError(ctx, status, obj, func(message string) { ctx.PlainText(status, message) }) @@ -65,9 +65,9 @@ func enumeratePackages(ctx *context.Context, filename string, pvs []*packages_mo return } - specs := make([]interface{}, 0, len(pds)) + specs := make([]any, 0, len(pds)) for _, p := range pds { - specs = append(specs, []interface{}{ + specs = append(specs, []any{ p.Package.Name, &rubygems_module.RubyUserMarshal{ Name: "Gem::Version", @@ -129,7 +129,7 @@ func ServePackageSpecification(ctx *context.Context) { // create a Ruby Gem::Specification object spec := &rubygems_module.RubyUserDef{ Name: "Gem::Specification", - Value: []interface{}{ + Value: []any{ "3.2.3", // @rubygems_version 4, // @specification_version, pd.Package.Name, @@ -142,7 +142,7 @@ func ServePackageSpecification(ctx *context.Context) { nil, // @required_ruby_version nil, // @required_rubygems_version metadata.Platform, // @original_platform - []interface{}{}, // @dependencies + []any{}, // @dependencies nil, // rubyforge_project "", // @email metadata.Authors, @@ -175,7 +175,7 @@ func DownloadPackageFile(ctx *context.Context) { return } - s, pf, err := packages_service.GetFileStreamByPackageVersion( + s, u, pf, err := packages_service.GetFileStreamByPackageVersion( ctx, pvs[0], &packages_service.PackageFileInfo{ @@ -190,12 +190,8 @@ func DownloadPackageFile(ctx *context.Context) { apiError(ctx, http.StatusInternalServerError, err) return } - defer s.Close() - ctx.ServeContent(s, &context.ServeHeaderOptions{ - Filename: pf.Name, - LastModified: pf.CreatedUnix.AsLocalTime(), - }) + helper.ServePackageFile(ctx, s, u, pf) } // UploadPackageFile adds a file to the package. If the package does not exist, it gets created. diff --git a/routers/api/packages/swift/swift.go b/routers/api/packages/swift/swift.go index 06f592dd648f9..bd4b8095c2c97 100644 --- a/routers/api/packages/swift/swift.go +++ b/routers/api/packages/swift/swift.go @@ -69,7 +69,7 @@ func setResponseHeaders(resp http.ResponseWriter, h *headers) { } // https://github.com/apple/swift-package-manager/blob/main/Documentation/Registry.md#33-error-handling -func apiError(ctx *context.Context, status int, obj interface{}) { +func apiError(ctx *context.Context, status int, obj any) { // https://www.rfc-editor.org/rfc/rfc7807 type Problem struct { Status int `json:"status"` @@ -397,18 +397,17 @@ func DownloadPackageFile(ctx *context.Context) { pf := pd.Files[0].File - s, _, err := packages_service.GetPackageFileStream(ctx, pf) + s, u, _, err := packages_service.GetPackageFileStream(ctx, pf) if err != nil { apiError(ctx, http.StatusInternalServerError, err) return } - defer s.Close() setResponseHeaders(ctx.Resp, &headers{ Digest: pd.Files[0].Blob.HashSHA256, }) - ctx.ServeContent(s, &context.ServeHeaderOptions{ + helper.ServePackageFile(ctx, s, u, pf, &context.ServeHeaderOptions{ Filename: pf.Name, ContentType: "application/zip", LastModified: pf.CreatedUnix.AsLocalTime(), diff --git a/routers/api/packages/vagrant/vagrant.go b/routers/api/packages/vagrant/vagrant.go index cefdc45b10ff4..9fe7ab56f6626 100644 --- a/routers/api/packages/vagrant/vagrant.go +++ b/routers/api/packages/vagrant/vagrant.go @@ -22,7 +22,7 @@ import ( "github.com/hashicorp/go-version" ) -func apiError(ctx *context.Context, status int, obj interface{}) { +func apiError(ctx *context.Context, status int, obj any) { helper.LogAndProcessError(ctx, status, obj, func(message string) { ctx.JSON(status, struct { Errors []string `json:"errors"` @@ -216,7 +216,7 @@ func UploadPackageFile(ctx *context.Context) { } func DownloadPackageFile(ctx *context.Context) { - s, pf, err := packages_service.GetFileStreamByPackageNameAndVersion( + s, u, pf, err := packages_service.GetFileStreamByPackageNameAndVersion( ctx, &packages_service.PackageInfo{ Owner: ctx.Package.Owner, @@ -236,10 +236,6 @@ func DownloadPackageFile(ctx *context.Context) { apiError(ctx, http.StatusInternalServerError, err) return } - defer s.Close() - ctx.ServeContent(s, &context.ServeHeaderOptions{ - Filename: pf.Name, - LastModified: pf.CreatedUnix.AsLocalTime(), - }) + helper.ServePackageFile(ctx, s, u, pf) } diff --git a/routers/api/v1/org/team.go b/routers/api/v1/org/team.go index 1aaefacdd596c..0e11acc901fb4 100644 --- a/routers/api/v1/org/team.go +++ b/routers/api/v1/org/team.go @@ -792,7 +792,7 @@ func SearchTeam(ctx *context.APIContext) { teams, maxResults, err := organization.SearchTeam(opts) if err != nil { log.Error("SearchTeam failed: %v", err) - ctx.JSON(http.StatusInternalServerError, map[string]interface{}{ + ctx.JSON(http.StatusInternalServerError, map[string]any{ "ok": false, "error": "SearchTeam internal failure", }) @@ -807,7 +807,7 @@ func SearchTeam(ctx *context.APIContext) { ctx.SetLinkHeader(int(maxResults), listOptions.PageSize) ctx.SetTotalCountHeader(maxResults) - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "ok": true, "data": apiTeams, }) diff --git a/routers/api/v1/repo/repo.go b/routers/api/v1/repo/repo.go index a9f8b5b7e7307..d9424d9e7698b 100644 --- a/routers/api/v1/repo/repo.go +++ b/routers/api/v1/repo/repo.go @@ -378,7 +378,7 @@ func Generate(ctx *context.APIContext) { ctxUser, err = user_model.GetUserByName(ctx, form.Owner) if err != nil { if user_model.IsErrUserNotExist(err) { - ctx.JSON(http.StatusNotFound, map[string]interface{}{ + ctx.JSON(http.StatusNotFound, map[string]any{ "error": "request owner `" + form.Owner + "` does not exist", }) return diff --git a/routers/api/v1/repo/topic.go b/routers/api/v1/repo/topic.go index 7d27fe7d25a0d..8bf3012d48822 100644 --- a/routers/api/v1/repo/topic.go +++ b/routers/api/v1/repo/topic.go @@ -63,7 +63,7 @@ func ListTopics(ctx *context.APIContext) { } ctx.SetTotalCountHeader(total) - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "topics": topicNames, }) } @@ -101,7 +101,7 @@ func UpdateTopics(ctx *context.APIContext) { validTopics, invalidTopics := repo_model.SanitizeAndValidateTopics(topicNames) if len(validTopics) > 25 { - ctx.JSON(http.StatusUnprocessableEntity, map[string]interface{}{ + ctx.JSON(http.StatusUnprocessableEntity, map[string]any{ "invalidTopics": nil, "message": "Exceeding maximum number of topics per repo", }) @@ -109,7 +109,7 @@ func UpdateTopics(ctx *context.APIContext) { } if len(invalidTopics) > 0 { - ctx.JSON(http.StatusUnprocessableEntity, map[string]interface{}{ + ctx.JSON(http.StatusUnprocessableEntity, map[string]any{ "invalidTopics": invalidTopics, "message": "Topic names are invalid", }) @@ -158,7 +158,7 @@ func AddTopic(ctx *context.APIContext) { topicName := strings.TrimSpace(strings.ToLower(ctx.Params(":topic"))) if !repo_model.ValidateTopic(topicName) { - ctx.JSON(http.StatusUnprocessableEntity, map[string]interface{}{ + ctx.JSON(http.StatusUnprocessableEntity, map[string]any{ "invalidTopics": topicName, "message": "Topic name is invalid", }) @@ -175,7 +175,7 @@ func AddTopic(ctx *context.APIContext) { return } if count >= 25 { - ctx.JSON(http.StatusUnprocessableEntity, map[string]interface{}{ + ctx.JSON(http.StatusUnprocessableEntity, map[string]any{ "message": "Exceeding maximum allowed topics per repo.", }) return @@ -223,7 +223,7 @@ func DeleteTopic(ctx *context.APIContext) { topicName := strings.TrimSpace(strings.ToLower(ctx.Params(":topic"))) if !repo_model.ValidateTopic(topicName) { - ctx.JSON(http.StatusUnprocessableEntity, map[string]interface{}{ + ctx.JSON(http.StatusUnprocessableEntity, map[string]any{ "invalidTopics": topicName, "message": "Topic name is invalid", }) @@ -289,7 +289,7 @@ func TopicSearch(ctx *context.APIContext) { } ctx.SetTotalCountHeader(total) - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "topics": topicResponses, }) } diff --git a/routers/api/v1/user/user.go b/routers/api/v1/user/user.go index 314116962b559..2a2361be678bf 100644 --- a/routers/api/v1/user/user.go +++ b/routers/api/v1/user/user.go @@ -62,7 +62,7 @@ func Search(ctx *context.APIContext) { ListOptions: listOptions, }) if err != nil { - ctx.JSON(http.StatusInternalServerError, map[string]interface{}{ + ctx.JSON(http.StatusInternalServerError, map[string]any{ "ok": false, "error": err.Error(), }) @@ -72,7 +72,7 @@ func Search(ctx *context.APIContext) { ctx.SetLinkHeader(int(maxResults), listOptions.PageSize) ctx.SetTotalCountHeader(maxResults) - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "ok": true, "data": convert.ToUsers(ctx, ctx.Doer, users), }) diff --git a/routers/private/manager_process.go b/routers/private/manager_process.go index a5993bf3718d3..68e4a21805b2f 100644 --- a/routers/private/manager_process.go +++ b/routers/private/manager_process.go @@ -49,7 +49,7 @@ func Processes(ctx *context.PrivateContext) { } if json { - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "TotalNumberOfGoroutines": goroutineCount, "TotalNumberOfProcesses": processCount, "Processes": processes, diff --git a/routers/web/admin/auths.go b/routers/web/admin/auths.go index b6ea3ff40300a..adde26f0b56e1 100644 --- a/routers/web/admin/auths.go +++ b/routers/web/admin/auths.go @@ -60,7 +60,7 @@ func Authentications(ctx *context.Context) { type dropdownItem struct { Name string - Type interface{} + Type any } var ( @@ -454,7 +454,7 @@ func DeleteAuthSource(ctx *context.Context) { } else { ctx.Flash.Error(fmt.Sprintf("auth_service.DeleteSource: %v", err)) } - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "redirect": setting.AppSubURL + "/admin/auths/" + url.PathEscape(ctx.Params(":authid")), }) return @@ -462,7 +462,7 @@ func DeleteAuthSource(ctx *context.Context) { log.Trace("Authentication deleted by admin(%s): %d", ctx.Doer.Name, source.ID) ctx.Flash.Success(ctx.Tr("admin.auths.deletion_success")) - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "redirect": setting.AppSubURL + "/admin/auths", }) } diff --git a/routers/web/admin/config.go b/routers/web/admin/config.go index 2c6989a71dbb3..1c233ae852ac9 100644 --- a/routers/web/admin/config.go +++ b/routers/web/admin/config.go @@ -207,7 +207,7 @@ func ChangeConfig(ctx *context.Context) { return } - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "version": version + 1, }) } diff --git a/routers/web/admin/hooks.go b/routers/web/admin/hooks.go index 46dc734d252fa..2e4122c9048bf 100644 --- a/routers/web/admin/hooks.go +++ b/routers/web/admin/hooks.go @@ -26,8 +26,8 @@ func DefaultOrSystemWebhooks(ctx *context.Context) { ctx.Data["PageIsAdminSystemHooks"] = true ctx.Data["PageIsAdminDefaultHooks"] = true - def := make(map[string]interface{}, len(ctx.Data)) - sys := make(map[string]interface{}, len(ctx.Data)) + def := make(map[string]any, len(ctx.Data)) + sys := make(map[string]any, len(ctx.Data)) for k, v := range ctx.Data { def[k] = v sys[k] = v @@ -67,7 +67,7 @@ func DeleteDefaultOrSystemWebhook(ctx *context.Context) { ctx.Flash.Success(ctx.Tr("repo.settings.webhook_deletion_success")) } - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "redirect": setting.AppSubURL + "/admin/hooks", }) } diff --git a/routers/web/admin/packages.go b/routers/web/admin/packages.go index 4d5987e780b6f..ace54fc0d80ea 100644 --- a/routers/web/admin/packages.go +++ b/routers/web/admin/packages.go @@ -97,7 +97,7 @@ func DeletePackageVersion(ctx *context.Context) { } ctx.Flash.Success(ctx.Tr("packages.settings.delete.success")) - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "redirect": setting.AppSubURL + "/admin/packages?page=" + url.QueryEscape(ctx.FormString("page")) + "&q=" + url.QueryEscape(ctx.FormString("q")) + "&type=" + url.QueryEscape(ctx.FormString("type")), }) } diff --git a/routers/web/admin/repos.go b/routers/web/admin/repos.go index 9a0e467b48712..2ea8a2ad35819 100644 --- a/routers/web/admin/repos.go +++ b/routers/web/admin/repos.go @@ -58,7 +58,7 @@ func DeleteRepo(ctx *context.Context) { log.Trace("Repository deleted: %s", repo.FullName()) ctx.Flash.Success(ctx.Tr("repo.settings.deletion_success")) - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "redirect": setting.AppSubURL + "/admin/repos?page=" + url.QueryEscape(ctx.FormString("page")) + "&sort=" + url.QueryEscape(ctx.FormString("sort")), }) } diff --git a/routers/web/admin/stacktrace.go b/routers/web/admin/stacktrace.go index 4b225c2c8a4ce..f2d2be481a6a3 100644 --- a/routers/web/admin/stacktrace.go +++ b/routers/web/admin/stacktrace.go @@ -42,7 +42,7 @@ func Stacktrace(ctx *context.Context) { func StacktraceCancel(ctx *context.Context) { pid := ctx.Params("pid") process.GetManager().Cancel(process.IDType(pid)) - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "redirect": setting.AppSubURL + "/admin/monitor/stacktrace", }) } diff --git a/routers/web/admin/users.go b/routers/web/admin/users.go index 3895bcfdb9293..08a4076418897 100644 --- a/routers/web/admin/users.go +++ b/routers/web/admin/users.go @@ -56,7 +56,7 @@ func Users(ctx *context.Context) { sortType = explore.UserSearchDefaultAdminSort ctx.SetFormString("sort", sortType) } - ctx.PageData["adminUserListSearchForm"] = map[string]interface{}{ + ctx.PageData["adminUserListSearchForm"] = map[string]any{ "StatusFilterMap": statusFilterMap, "SortType": sortType, } diff --git a/routers/web/auth/auth.go b/routers/web/auth/auth.go index bc8f6d58c9270..9f13952257472 100644 --- a/routers/web/auth/auth.go +++ b/routers/web/auth/auth.go @@ -78,7 +78,7 @@ func AutoSignIn(ctx *context.Context) (bool, error) { isSucceed = true - if err := updateSession(ctx, nil, map[string]interface{}{ + if err := updateSession(ctx, nil, map[string]any{ // Set session IDs "uid": u.ID, "uname": u.Name, @@ -201,7 +201,7 @@ func SignInPost(ctx *context.Context) { u, source, err := auth_service.UserSignIn(form.UserName, form.Password) if err != nil { - if user_model.IsErrUserNotExist(err) || user_model.IsErrEmailAddressNotExist(err) { + if errors.Is(err, util.ErrNotExist) || errors.Is(err, util.ErrInvalidArgument) { ctx.RenderWithErr(ctx.Tr("form.username_password_incorrect"), tplSignIn, &form) log.Info("Failed authentication attempt for %s from %s: %v", form.UserName, ctx.RemoteAddr(), err) } else if user_model.IsErrEmailAlreadyUsed(err) { @@ -255,7 +255,7 @@ func SignInPost(ctx *context.Context) { return } - updates := map[string]interface{}{ + updates := map[string]any{ // User will need to use 2FA TOTP or WebAuthn, save data "twofaUid": u.ID, "twofaRemember": form.Remember, @@ -305,7 +305,7 @@ func handleSignInFull(ctx *context.Context, u *user_model.User, remember, obeyRe "twofaUid", "twofaRemember", "linkAccount", - }, map[string]interface{}{ + }, map[string]any{ "uid": u.ID, "uname": u.Name, }); err != nil { @@ -476,7 +476,7 @@ func SignUpPost(ctx *context.Context) { // createAndHandleCreatedUser calls createUserInContext and // then handleUserCreated. -func createAndHandleCreatedUser(ctx *context.Context, tpl base.TplName, form interface{}, u *user_model.User, overwrites *user_model.CreateUserOverwriteOptions, gothUser *goth.User, allowLink bool) bool { +func createAndHandleCreatedUser(ctx *context.Context, tpl base.TplName, form any, u *user_model.User, overwrites *user_model.CreateUserOverwriteOptions, gothUser *goth.User, allowLink bool) bool { if !createUserInContext(ctx, tpl, form, u, overwrites, gothUser, allowLink) { return false } @@ -485,7 +485,7 @@ func createAndHandleCreatedUser(ctx *context.Context, tpl base.TplName, form int // createUserInContext creates a user and handles errors within a given context. // Optionally a template can be specified. -func createUserInContext(ctx *context.Context, tpl base.TplName, form interface{}, u *user_model.User, overwrites *user_model.CreateUserOverwriteOptions, gothUser *goth.User, allowLink bool) (ok bool) { +func createUserInContext(ctx *context.Context, tpl base.TplName, form any, u *user_model.User, overwrites *user_model.CreateUserOverwriteOptions, gothUser *goth.User, allowLink bool) (ok bool) { if err := user_model.CreateUser(u, overwrites); err != nil { if allowLink && (user_model.IsErrUserAlreadyExist(err) || user_model.IsErrEmailAlreadyUsed(err)) { if setting.OAuth2Client.AccountLinking == setting.OAuth2AccountLinkingAuto { @@ -707,7 +707,7 @@ func handleAccountActivation(ctx *context.Context, user *user_model.User) { log.Trace("User activated: %s", user.Name) - if err := updateSession(ctx, nil, map[string]interface{}{ + if err := updateSession(ctx, nil, map[string]any{ "uid": user.ID, "uname": user.Name, }); err != nil { @@ -760,7 +760,7 @@ func ActivateEmail(ctx *context.Context) { ctx.Redirect(setting.AppSubURL + "/user/settings/account") } -func updateSession(ctx *context.Context, deletes []string, updates map[string]interface{}) error { +func updateSession(ctx *context.Context, deletes []string, updates map[string]any) error { if _, err := session.RegenerateSession(ctx.Resp, ctx.Req); err != nil { return fmt.Errorf("regenerate session: %w", err) } diff --git a/routers/web/auth/linkaccount.go b/routers/web/auth/linkaccount.go index 865bcca15240d..0f7ecf1af49ae 100644 --- a/routers/web/auth/linkaccount.go +++ b/routers/web/auth/linkaccount.go @@ -13,7 +13,9 @@ import ( user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/web" auth_service "code.gitea.io/gitea/services/auth" "code.gitea.io/gitea/services/auth/source/oauth2" @@ -81,6 +83,32 @@ func LinkAccount(ctx *context.Context) { ctx.HTML(http.StatusOK, tplLinkAccount) } +func handleSignInError(ctx *context.Context, userName string, ptrForm any, tmpl base.TplName, invoker string, err error) { + if errors.Is(err, util.ErrNotExist) { + ctx.RenderWithErr(ctx.Tr("form.username_password_incorrect"), tmpl, ptrForm) + } else if errors.Is(err, util.ErrInvalidArgument) { + ctx.Data["user_exists"] = true + ctx.RenderWithErr(ctx.Tr("form.username_password_incorrect"), tmpl, ptrForm) + } else if user_model.IsErrUserProhibitLogin(err) { + ctx.Data["user_exists"] = true + log.Info("Failed authentication attempt for %s from %s: %v", userName, ctx.RemoteAddr(), err) + ctx.Data["Title"] = ctx.Tr("auth.prohibit_login") + ctx.HTML(http.StatusOK, "user/auth/prohibit_login") + } else if user_model.IsErrUserInactive(err) { + ctx.Data["user_exists"] = true + if setting.Service.RegisterEmailConfirm { + ctx.Data["Title"] = ctx.Tr("auth.active_your_account") + ctx.HTML(http.StatusOK, TplActivate) + } else { + log.Info("Failed authentication attempt for %s from %s: %v", userName, ctx.RemoteAddr(), err) + ctx.Data["Title"] = ctx.Tr("auth.prohibit_login") + ctx.HTML(http.StatusOK, "user/auth/prohibit_login") + } + } else { + ctx.ServerError(invoker, err) + } +} + // LinkAccountPostSignIn handle the coupling of external account with another account using signIn func LinkAccountPostSignIn(ctx *context.Context) { signInForm := web.GetForm(ctx).(*forms.SignInForm) @@ -116,12 +144,7 @@ func LinkAccountPostSignIn(ctx *context.Context) { u, _, err := auth_service.UserSignIn(signInForm.UserName, signInForm.Password) if err != nil { - if user_model.IsErrUserNotExist(err) { - ctx.Data["user_exists"] = true - ctx.RenderWithErr(ctx.Tr("form.username_password_incorrect"), tplLinkAccount, &signInForm) - } else { - ctx.ServerError("UserLinkAccount", err) - } + handleSignInError(ctx, signInForm.UserName, &signInForm, tplLinkAccount, "UserLinkAccount", err) return } @@ -151,7 +174,7 @@ func linkAccount(ctx *context.Context, u *user_model.User, gothUser goth.User, r return } - if err := updateSession(ctx, nil, map[string]interface{}{ + if err := updateSession(ctx, nil, map[string]any{ // User needs to use 2FA, save data and redirect to 2FA page. "twofaUid": u.ID, "twofaRemember": remember, diff --git a/routers/web/auth/oauth.go b/routers/web/auth/oauth.go index 0ce3bbde00314..db15bf2e3d1a5 100644 --- a/routers/web/auth/oauth.go +++ b/routers/web/auth/oauth.go @@ -1008,13 +1008,13 @@ func SignInOAuthCallback(ctx *context.Context) { handleOAuth2SignIn(ctx, authSource, u, gothUser) } -func claimValueToStringSet(claimValue interface{}) container.Set[string] { +func claimValueToStringSet(claimValue any) container.Set[string] { var groups []string switch rawGroup := claimValue.(type) { case []string: groups = rawGroup - case []interface{}: + case []any: for _, group := range rawGroup { groups = append(groups, fmt.Sprintf("%s", group)) } @@ -1067,7 +1067,7 @@ func setUserAdminAndRestrictedFromGroupClaims(source *oauth2.Source, u *user_mod } func showLinkingLogin(ctx *context.Context, gothUser goth.User) { - if err := updateSession(ctx, nil, map[string]interface{}{ + if err := updateSession(ctx, nil, map[string]any{ "linkAccountGothUser": gothUser, }); err != nil { ctx.ServerError("updateSession", err) @@ -1119,7 +1119,7 @@ func handleOAuth2SignIn(ctx *context.Context, source *auth.Source, u *user_model // If this user is enrolled in 2FA and this source doesn't override it, // we can't sign the user in just yet. Instead, redirect them to the 2FA authentication page. if !needs2FA { - if err := updateSession(ctx, nil, map[string]interface{}{ + if err := updateSession(ctx, nil, map[string]any{ "uid": u.ID, "uname": u.Name, }); err != nil { @@ -1189,7 +1189,7 @@ func handleOAuth2SignIn(ctx *context.Context, source *auth.Source, u *user_model } } - if err := updateSession(ctx, nil, map[string]interface{}{ + if err := updateSession(ctx, nil, map[string]any{ // User needs to use 2FA, save data and redirect to 2FA page. "twofaUid": u.ID, "twofaRemember": false, diff --git a/routers/web/auth/oauth_test.go b/routers/web/auth/oauth_test.go index 62f723600d3b1..adf933fd239bf 100644 --- a/routers/web/auth/oauth_test.go +++ b/routers/web/auth/oauth_test.go @@ -26,7 +26,7 @@ func createAndParseToken(t *testing.T, grant *auth.OAuth2Grant) *oauth2.OIDCToke assert.Nil(t, terr) assert.NotNil(t, response) - parsedToken, err := jwt.ParseWithClaims(response.IDToken, &oauth2.OIDCToken{}, func(token *jwt.Token) (interface{}, error) { + parsedToken, err := jwt.ParseWithClaims(response.IDToken, &oauth2.OIDCToken{}, func(token *jwt.Token) (any, error) { assert.NotNil(t, token.Method) assert.Equal(t, signingKey.SigningMethod().Alg(), token.Method.Alg()) return signingKey.VerifyKey(), nil diff --git a/routers/web/auth/openid.go b/routers/web/auth/openid.go index 5e0e7b258f665..00fc17f098019 100644 --- a/routers/web/auth/openid.go +++ b/routers/web/auth/openid.go @@ -230,7 +230,7 @@ func signInOpenIDVerify(ctx *context.Context) { if u != nil { nickname = u.LowerName } - if err := updateSession(ctx, nil, map[string]interface{}{ + if err := updateSession(ctx, nil, map[string]any{ "openid_verified_uri": id, "openid_determined_email": email, "openid_determined_username": nickname, @@ -282,11 +282,7 @@ func ConnectOpenIDPost(ctx *context.Context) { u, _, err := auth.UserSignIn(form.UserName, form.Password) if err != nil { - if user_model.IsErrUserNotExist(err) { - ctx.RenderWithErr(ctx.Tr("form.username_password_incorrect"), tplConnectOID, &form) - } else { - ctx.ServerError("ConnectOpenIDPost", err) - } + handleSignInError(ctx, form.UserName, &form, tplConnectOID, "ConnectOpenIDPost", err) return } diff --git a/routers/web/devtest/devtest.go b/routers/web/devtest/devtest.go index 64b732c035671..525ca9be53c63 100644 --- a/routers/web/devtest/devtest.go +++ b/routers/web/devtest/devtest.go @@ -34,7 +34,7 @@ func List(ctx *context.Context) { func FetchActionTest(ctx *context.Context) { _ = ctx.Req.ParseForm() - ctx.Flash.Info(ctx.Req.Method + " " + ctx.Req.RequestURI + "
" + + ctx.Flash.Info("fetch-action: " + ctx.Req.Method + " " + ctx.Req.RequestURI + "
" + "Form: " + ctx.Req.Form.Encode() + "
" + "PostForm: " + ctx.Req.PostForm.Encode(), ) @@ -52,5 +52,15 @@ func Tmpl(ctx *context.Context) { ctx.Data["TimePast1y"] = now.Add(-1 * 366 * 86400 * time.Second) ctx.Data["TimeFuture1y"] = now.Add(1 * 366 * 86400 * time.Second) + if ctx.Req.Method == "POST" { + _ = ctx.Req.ParseForm() + ctx.Flash.Info("form: "+ctx.Req.Method+" "+ctx.Req.RequestURI+"
"+ + "Form: "+ctx.Req.Form.Encode()+"
"+ + "PostForm: "+ctx.Req.PostForm.Encode(), + true, + ) + time.Sleep(2 * time.Second) + } + ctx.HTML(http.StatusOK, base.TplName("devtest"+path.Clean("/"+ctx.Params("sub")))) } diff --git a/routers/web/explore/topic.go b/routers/web/explore/topic.go index e172d9e04d018..132ef23fa757d 100644 --- a/routers/web/explore/topic.go +++ b/routers/web/explore/topic.go @@ -35,7 +35,7 @@ func TopicSearch(ctx *context.Context) { } ctx.SetTotalCountHeader(total) - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "topics": topicResponses, }) } diff --git a/routers/web/org/members.go b/routers/web/org/members.go index 1953a8b2849b3..8da0f0b9fd012 100644 --- a/routers/web/org/members.go +++ b/routers/web/org/members.go @@ -101,7 +101,7 @@ func MembersAction(ctx *context.Context) { err = models.RemoveOrgUser(org.ID, uid) if organization.IsErrLastOrgOwner(err) { ctx.Flash.Error(ctx.Tr("form.last_org_owner")) - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "redirect": ctx.Org.OrgLink + "/members", }) return @@ -110,12 +110,12 @@ func MembersAction(ctx *context.Context) { err = models.RemoveOrgUser(org.ID, ctx.Doer.ID) if err == nil { ctx.Flash.Success(ctx.Tr("form.organization_leave_success", org.DisplayName())) - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "redirect": "", // keep the user stay on current page, in case they want to do other operations. }) } else if organization.IsErrLastOrgOwner(err) { ctx.Flash.Error(ctx.Tr("form.last_org_owner")) - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "redirect": ctx.Org.OrgLink + "/members", }) } else { @@ -126,7 +126,7 @@ func MembersAction(ctx *context.Context) { if err != nil { log.Error("Action(%s): %v", ctx.Params(":action"), err) - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "ok": false, "err": err.Error(), }) @@ -138,7 +138,7 @@ func MembersAction(ctx *context.Context) { redirect = setting.AppSubURL + "/" } - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "redirect": redirect, }) } diff --git a/routers/web/org/org_labels.go b/routers/web/org/org_labels.go index 9ce05680d7bd2..08566637a8780 100644 --- a/routers/web/org/org_labels.go +++ b/routers/web/org/org_labels.go @@ -90,7 +90,7 @@ func DeleteLabel(ctx *context.Context) { ctx.Flash.Success(ctx.Tr("repo.issues.label_deletion_success")) } - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "redirect": ctx.Org.OrgLink + "/settings/labels", }) } diff --git a/routers/web/org/projects.go b/routers/web/org/projects.go index e525f2c43f3ac..4b33d943b379f 100644 --- a/routers/web/org/projects.go +++ b/routers/web/org/projects.go @@ -218,7 +218,7 @@ func DeleteProject(ctx *context.Context) { ctx.Flash.Success(ctx.Tr("repo.projects.deletion_success")) } - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "redirect": ctx.ContextUser.HomeLink() + "/-/projects", }) } @@ -436,9 +436,11 @@ func UpdateIssueProject(ctx *context.Context) { projectID := ctx.FormInt64("id") for _, issue := range issues { - oldProjectID := issue.Project.ID - if oldProjectID == projectID { - continue + if issue.Project != nil { + oldProjectID := issue.Project.ID + if oldProjectID == projectID { + continue + } } if err := issues_model.ChangeProjectAssign(issue, ctx.Doer, projectID); err != nil { @@ -447,7 +449,7 @@ func UpdateIssueProject(ctx *context.Context) { } } - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "ok": true, }) } @@ -495,7 +497,7 @@ func DeleteProjectBoard(ctx *context.Context) { return } - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "ok": true, }) } @@ -524,7 +526,7 @@ func AddBoardToProjectPost(ctx *context.Context) { return } - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "ok": true, }) } @@ -592,7 +594,7 @@ func EditProjectBoard(ctx *context.Context) { return } - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "ok": true, }) } @@ -609,7 +611,7 @@ func SetDefaultProjectBoard(ctx *context.Context) { return } - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "ok": true, }) } @@ -626,7 +628,7 @@ func UnsetDefaultProjectBoard(ctx *context.Context) { return } - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "ok": true, }) } @@ -728,7 +730,7 @@ func MoveIssues(ctx *context.Context) { return } - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "ok": true, }) } diff --git a/routers/web/org/setting.go b/routers/web/org/setting.go index 2c4a6b93e39e0..b5653160a26d5 100644 --- a/routers/web/org/setting.go +++ b/routers/web/org/setting.go @@ -224,7 +224,7 @@ func DeleteWebhook(ctx *context.Context) { ctx.Flash.Success(ctx.Tr("repo.settings.webhook_deletion_success")) } - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "redirect": ctx.Org.OrgLink + "/settings/hooks", }) } diff --git a/routers/web/org/teams.go b/routers/web/org/teams.go index 2ce4bf5322717..aefadaf809e82 100644 --- a/routers/web/org/teams.go +++ b/routers/web/org/teams.go @@ -79,7 +79,7 @@ func TeamsAction(ctx *context.Context) { ctx.Flash.Error(ctx.Tr("form.last_org_owner")) } else { log.Error("Action(%s): %v", ctx.Params(":action"), err) - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "ok": false, "err": err.Error(), }) @@ -95,7 +95,7 @@ func TeamsAction(ctx *context.Context) { redirect = setting.AppSubURL + "/" } ctx.JSON(http.StatusOK, - map[string]interface{}{ + map[string]any{ "redirect": redirect, }) return @@ -117,7 +117,7 @@ func TeamsAction(ctx *context.Context) { ctx.Flash.Error(ctx.Tr("form.last_org_owner")) } else { log.Error("Action(%s): %v", ctx.Params(":action"), err) - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "ok": false, "err": err.Error(), }) @@ -125,7 +125,7 @@ func TeamsAction(ctx *context.Context) { } } ctx.JSON(http.StatusOK, - map[string]interface{}{ + map[string]any{ "redirect": ctx.Org.OrgLink + "/teams/" + url.PathEscape(ctx.Org.Team.LowerName), }) return @@ -199,7 +199,7 @@ func TeamsAction(ctx *context.Context) { ctx.Flash.Error(ctx.Tr("form.last_org_owner")) } else { log.Error("Action(%s): %v", ctx.Params(":action"), err) - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "ok": false, "err": err.Error(), }) @@ -256,7 +256,7 @@ func TeamsRepoAction(ctx *context.Context) { } if action == "addall" || action == "removeall" { - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "redirect": ctx.Org.OrgLink + "/teams/" + url.PathEscape(ctx.Org.Team.LowerName) + "/repositories", }) return @@ -414,7 +414,7 @@ func SearchTeam(ctx *context.Context) { teams, maxResults, err := org_model.SearchTeam(opts) if err != nil { log.Error("SearchTeam failed: %v", err) - ctx.JSON(http.StatusInternalServerError, map[string]interface{}{ + ctx.JSON(http.StatusInternalServerError, map[string]any{ "ok": false, "error": "SearchTeam internal failure", }) @@ -424,7 +424,7 @@ func SearchTeam(ctx *context.Context) { apiTeams, err := convert.ToTeams(ctx, teams, false) if err != nil { log.Error("convert ToTeams failed: %v", err) - ctx.JSON(http.StatusInternalServerError, map[string]interface{}{ + ctx.JSON(http.StatusInternalServerError, map[string]any{ "ok": false, "error": "SearchTeam failed to get units", }) @@ -432,7 +432,7 @@ func SearchTeam(ctx *context.Context) { } ctx.SetTotalCountHeader(maxResults) - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "ok": true, "data": apiTeams, }) @@ -530,7 +530,7 @@ func DeleteTeam(ctx *context.Context) { ctx.Flash.Success(ctx.Tr("org.teams.delete_team_success")) } - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "redirect": ctx.Org.OrgLink + "/teams", }) } diff --git a/routers/web/repo/branch.go b/routers/web/repo/branch.go index f0282a71b876b..999104d7872dd 100644 --- a/routers/web/repo/branch.go +++ b/routers/web/repo/branch.go @@ -57,7 +57,25 @@ func Branches(ctx *context.Context) { return } + commitIDs := []string{defaultBranch.DBBranch.CommitID} + for _, branch := range branches { + commitIDs = append(commitIDs, branch.DBBranch.CommitID) + } + + commitStatuses, err := git_model.GetLatestCommitStatusForRepoCommitIDs(ctx, ctx.Repo.Repository.ID, commitIDs) + if err != nil { + ctx.ServerError("LoadBranches", err) + return + } + + commitStatus := make(map[string]*git_model.CommitStatus) + for commitID, cs := range commitStatuses { + commitStatus[commitID] = git_model.CalcCommitStatus(cs) + } + ctx.Data["Branches"] = branches + ctx.Data["CommitStatus"] = commitStatus + ctx.Data["CommitStatuses"] = commitStatuses ctx.Data["DefaultBranchBranch"] = defaultBranch pager := context.NewPagination(int(branchesCount), pageSize, page, 5) pager.SetDefaultParams(ctx) @@ -144,7 +162,7 @@ func RestoreBranchPost(ctx *context.Context) { } func redirect(ctx *context.Context) { - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "redirect": ctx.Repo.RepoLink + "/branches?page=" + url.QueryEscape(ctx.FormString("page")), }) } @@ -205,7 +223,7 @@ func CreateBranch(ctx *context.Context) { if len(e.Message) == 0 { ctx.Flash.Error(ctx.Tr("repo.editor.push_rejected_no_message")) } else { - flashError, err := ctx.RenderToString(tplAlertDetails, map[string]interface{}{ + flashError, err := ctx.RenderToString(tplAlertDetails, map[string]any{ "Message": ctx.Tr("repo.editor.push_rejected"), "Summary": ctx.Tr("repo.editor.push_rejected_summary"), "Details": utils.SanitizeFlashErrorString(e.Message), diff --git a/routers/web/repo/editor.go b/routers/web/repo/editor.go index a63b08126c931..88f9e42f3bf43 100644 --- a/routers/web/repo/editor.go +++ b/routers/web/repo/editor.go @@ -344,7 +344,7 @@ func editFilePost(ctx *context.Context, form forms.EditRepoFileForm, isNewFile b if len(errPushRej.Message) == 0 { ctx.RenderWithErr(ctx.Tr("repo.editor.push_rejected_no_message"), tplEditFile, &form) } else { - flashError, err := ctx.RenderToString(tplAlertDetails, map[string]interface{}{ + flashError, err := ctx.RenderToString(tplAlertDetails, map[string]any{ "Message": ctx.Tr("repo.editor.push_rejected"), "Summary": ctx.Tr("repo.editor.push_rejected_summary"), "Details": utils.SanitizeFlashErrorString(errPushRej.Message), @@ -356,7 +356,7 @@ func editFilePost(ctx *context.Context, form forms.EditRepoFileForm, isNewFile b ctx.RenderWithErr(flashError, tplEditFile, &form) } } else { - flashError, err := ctx.RenderToString(tplAlertDetails, map[string]interface{}{ + flashError, err := ctx.RenderToString(tplAlertDetails, map[string]any{ "Message": ctx.Tr("repo.editor.fail_to_update_file", form.TreePath), "Summary": ctx.Tr("repo.editor.fail_to_update_file_summary"), "Details": utils.SanitizeFlashErrorString(err.Error()), @@ -543,7 +543,7 @@ func DeleteFilePost(ctx *context.Context) { if len(errPushRej.Message) == 0 { ctx.RenderWithErr(ctx.Tr("repo.editor.push_rejected_no_message"), tplDeleteFile, &form) } else { - flashError, err := ctx.RenderToString(tplAlertDetails, map[string]interface{}{ + flashError, err := ctx.RenderToString(tplAlertDetails, map[string]any{ "Message": ctx.Tr("repo.editor.push_rejected"), "Summary": ctx.Tr("repo.editor.push_rejected_summary"), "Details": utils.SanitizeFlashErrorString(errPushRej.Message), @@ -743,7 +743,7 @@ func UploadFilePost(ctx *context.Context) { if len(errPushRej.Message) == 0 { ctx.RenderWithErr(ctx.Tr("repo.editor.push_rejected_no_message"), tplUploadFile, &form) } else { - flashError, err := ctx.RenderToString(tplAlertDetails, map[string]interface{}{ + flashError, err := ctx.RenderToString(tplAlertDetails, map[string]any{ "Message": ctx.Tr("repo.editor.push_rejected"), "Summary": ctx.Tr("repo.editor.push_rejected_summary"), "Details": utils.SanitizeFlashErrorString(errPushRej.Message), diff --git a/routers/web/repo/issue.go b/routers/web/repo/issue.go index 4f14cc381f9d3..5e15df330c2e5 100644 --- a/routers/web/repo/issue.go +++ b/routers/web/repo/issue.go @@ -952,7 +952,7 @@ func renderErrorOfTemplates(ctx *context.Context, errs map[string]error) string lines = append(lines, fmt.Sprintf("%s: %v", file, errs[file])) } - flashError, err := ctx.RenderToString(tplAlertDetails, map[string]interface{}{ + flashError, err := ctx.RenderToString(tplAlertDetails, map[string]any{ "Message": ctx.Tr("repo.issues.choose.ignore_invalid_templates"), "Summary": ctx.Tr("repo.issues.choose.invalid_templates", len(errs)), "Details": utils.SanitizeFlashErrorString(strings.Join(lines, "\n")), @@ -2081,7 +2081,7 @@ func UpdateIssueTitle(ctx *context.Context) { return } - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "title": issue.Title, }) } @@ -2105,7 +2105,7 @@ func UpdateIssueRef(ctx *context.Context) { return } - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "ref": ref, }) } @@ -2146,7 +2146,7 @@ func UpdateIssueContent(ctx *context.Context) { return } - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "content": content, "attachments": attachmentsHTML(ctx, issue.Attachments, issue.Content), }) @@ -2206,7 +2206,7 @@ func UpdateIssueMilestone(ctx *context.Context) { } } - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "ok": true, }) } @@ -2252,7 +2252,7 @@ func UpdateIssueAssignee(ctx *context.Context) { } } } - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "ok": true, }) } @@ -2377,7 +2377,7 @@ func UpdatePullReviewRequest(ctx *context.Context) { } } - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "ok": true, }) } @@ -2763,7 +2763,7 @@ func UpdateIssueStatus(ctx *context.Context) { if issue.IsClosed != isClosed { if err := issue_service.ChangeStatus(issue, ctx.Doer, "", isClosed); err != nil { if issues_model.IsErrDependenciesLeft(err) { - ctx.JSON(http.StatusPreconditionFailed, map[string]interface{}{ + ctx.JSON(http.StatusPreconditionFailed, map[string]any{ "error": ctx.Tr("repo.issues.dependency.issue_batch_close_blocked", issue.Index), }) return @@ -2978,7 +2978,7 @@ func UpdateCommentContent(ctx *context.Context) { oldContent := comment.Content comment.Content = ctx.FormString("content") if len(comment.Content) == 0 { - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "content": "", }) return @@ -3012,7 +3012,7 @@ func UpdateCommentContent(ctx *context.Context) { return } - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "content": content, "attachments": attachmentsHTML(ctx, comment.Attachments, comment.Content), }) @@ -3122,14 +3122,14 @@ func ChangeIssueReaction(ctx *context.Context) { } if len(issue.Reactions) == 0 { - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "empty": true, "html": "", }) return } - html, err := ctx.RenderToString(tplReactions, map[string]interface{}{ + html, err := ctx.RenderToString(tplReactions, map[string]any{ "ctxData": ctx.Data, "ActionURL": fmt.Sprintf("%s/issues/%d/reactions", ctx.Repo.RepoLink, issue.Index), "Reactions": issue.Reactions.GroupByType(), @@ -3138,7 +3138,7 @@ func ChangeIssueReaction(ctx *context.Context) { ctx.ServerError("ChangeIssueReaction.HTMLString", err) return } - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "html": html, }) } @@ -3224,14 +3224,14 @@ func ChangeCommentReaction(ctx *context.Context) { } if len(comment.Reactions) == 0 { - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "empty": true, "html": "", }) return } - html, err := ctx.RenderToString(tplReactions, map[string]interface{}{ + html, err := ctx.RenderToString(tplReactions, map[string]any{ "ctxData": ctx.Data, "ActionURL": fmt.Sprintf("%s/comments/%d/reactions", ctx.Repo.RepoLink, comment.ID), "Reactions": comment.Reactions.GroupByType(), @@ -3240,7 +3240,7 @@ func ChangeCommentReaction(ctx *context.Context) { ctx.ServerError("ChangeCommentReaction.HTMLString", err) return } - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "html": html, }) } @@ -3313,7 +3313,7 @@ func GetCommentAttachments(ctx *context.Context) { ctx.JSON(http.StatusOK, attachments) } -func updateAttachments(ctx *context.Context, item interface{}, files []string) error { +func updateAttachments(ctx *context.Context, item any, files []string) error { var attachments []*repo_model.Attachment switch content := item.(type) { case *issues_model.Issue: @@ -3357,7 +3357,7 @@ func updateAttachments(ctx *context.Context, item interface{}, files []string) e } func attachmentsHTML(ctx *context.Context, attachments []*repo_model.Attachment, content string) string { - attachHTML, err := ctx.RenderToString(tplAttachment, map[string]interface{}{ + attachHTML, err := ctx.RenderToString(tplAttachment, map[string]any{ "ctxData": ctx.Data, "Attachments": attachments, "Content": content, diff --git a/routers/web/repo/issue_content_history.go b/routers/web/repo/issue_content_history.go index 7e5295e757b7c..46a320a8cc801 100644 --- a/routers/web/repo/issue_content_history.go +++ b/routers/web/repo/issue_content_history.go @@ -29,8 +29,8 @@ func GetContentHistoryOverview(ctx *context.Context) { } editedHistoryCountMap, _ := issues_model.QueryIssueContentHistoryEditedCountMap(ctx, issue.ID) - ctx.JSON(http.StatusOK, map[string]interface{}{ - "i18n": map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ + "i18n": map[string]any{ "textEdited": ctx.Tr("repo.issues.content_history.edited"), "textDeleteFromHistory": ctx.Tr("repo.issues.content_history.delete_from_history"), "textDeleteFromHistoryConfirm": ctx.Tr("repo.issues.content_history.delete_from_history_confirm"), @@ -53,7 +53,7 @@ func GetContentHistoryList(ctx *context.Context) { // render history list to HTML for frontend dropdown items: (name, value) // name is HTML of "avatar + userName + userAction + timeSince" // value is historyId - var results []map[string]interface{} + var results []map[string]any for _, item := range items { var actionText string if item.IsDeleted { @@ -76,13 +76,13 @@ func GetContentHistoryList(ctx *context.Context) { avatarHTML := string(templates.AvatarHTML(src, 28, class, username)) timeSinceText := string(timeutil.TimeSinceUnix(item.EditedUnix, ctx.Locale)) - results = append(results, map[string]interface{}{ + results = append(results, map[string]any{ "name": avatarHTML + "" + name + " " + actionText + " " + timeSinceText, "value": item.HistoryID, }) } - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "results": results, }) } @@ -120,7 +120,7 @@ func GetContentHistoryDetail(ctx *context.Context) { historyID := ctx.FormInt64("history_id") history, prevHistory, err := issues_model.GetIssueContentHistoryAndPrev(ctx, historyID) if err != nil { - ctx.JSON(http.StatusNotFound, map[string]interface{}{ + ctx.JSON(http.StatusNotFound, map[string]any{ "message": "Can not find the content history", }) return @@ -168,7 +168,7 @@ func GetContentHistoryDetail(ctx *context.Context) { } diffHTMLBuf.WriteString("") - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "canSoftDelete": canSoftDeleteContentHistory(ctx, issue, comment, history), "historyId": historyID, "prevHistoryId": prevHistoryID, @@ -202,7 +202,7 @@ func SoftDeleteContentHistory(ctx *context.Context) { canSoftDelete := canSoftDeleteContentHistory(ctx, issue, comment, history) if !canSoftDelete { - ctx.JSON(http.StatusForbidden, map[string]interface{}{ + ctx.JSON(http.StatusForbidden, map[string]any{ "message": "Can not delete the content history", }) return @@ -210,7 +210,7 @@ func SoftDeleteContentHistory(ctx *context.Context) { err = issues_model.SoftDeleteIssueContentHistory(ctx, historyID) log.Debug("soft delete issue content history. issue=%d, comment=%d, history=%d", issue.ID, commentID, historyID) - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "ok": err == nil, }) } diff --git a/routers/web/repo/issue_label.go b/routers/web/repo/issue_label.go index 002acbf1d3c85..af5db83bd5d24 100644 --- a/routers/web/repo/issue_label.go +++ b/routers/web/repo/issue_label.go @@ -157,7 +157,7 @@ func DeleteLabel(ctx *context.Context) { ctx.Flash.Success(ctx.Tr("repo.issues.label_deletion_success")) } - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "redirect": ctx.Repo.RepoLink + "/labels", }) } @@ -226,7 +226,7 @@ func UpdateIssueLabel(ctx *context.Context) { return } - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "ok": true, }) } diff --git a/routers/web/repo/milestone.go b/routers/web/repo/milestone.go index 4b33fbcb16b70..38ef6939676f9 100644 --- a/routers/web/repo/milestone.go +++ b/routers/web/repo/milestone.go @@ -256,7 +256,7 @@ func DeleteMilestone(ctx *context.Context) { ctx.Flash.Success(ctx.Tr("repo.milestones.deletion_success")) } - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "redirect": ctx.Repo.RepoLink + "/milestones", }) } diff --git a/routers/web/repo/projects.go b/routers/web/repo/projects.go index 6da9edfd0b802..066cdbc5fd889 100644 --- a/routers/web/repo/projects.go +++ b/routers/web/repo/projects.go @@ -203,7 +203,7 @@ func DeleteProject(ctx *context.Context) { ctx.Flash.Success(ctx.Tr("repo.projects.deletion_success")) } - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "redirect": ctx.Repo.RepoLink + "/projects", }) } @@ -385,9 +385,11 @@ func UpdateIssueProject(ctx *context.Context) { projectID := ctx.FormInt64("id") for _, issue := range issues { - oldProjectID := issue.Project.ID - if oldProjectID == projectID { - continue + if issue.Project != nil { + oldProjectID := issue.Project.ID + if oldProjectID == projectID { + continue + } } if err := issues_model.ChangeProjectAssign(issue, ctx.Doer, projectID); err != nil { @@ -396,7 +398,7 @@ func UpdateIssueProject(ctx *context.Context) { } } - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "ok": true, }) } @@ -451,7 +453,7 @@ func DeleteProjectBoard(ctx *context.Context) { return } - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "ok": true, }) } @@ -486,7 +488,7 @@ func AddBoardToProjectPost(ctx *context.Context) { return } - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "ok": true, }) } @@ -560,7 +562,7 @@ func EditProjectBoard(ctx *context.Context) { return } - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "ok": true, }) } @@ -577,7 +579,7 @@ func SetDefaultProjectBoard(ctx *context.Context) { return } - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "ok": true, }) } @@ -594,7 +596,7 @@ func UnSetDefaultProjectBoard(ctx *context.Context) { return } - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "ok": true, }) } @@ -698,7 +700,7 @@ func MoveIssues(ctx *context.Context) { return } - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "ok": true, }) } diff --git a/routers/web/repo/pull.go b/routers/web/repo/pull.go index c543d90e190ae..ad04fb2d7165a 100644 --- a/routers/web/repo/pull.go +++ b/routers/web/repo/pull.go @@ -802,7 +802,7 @@ func ViewPullFiles(ctx *context.Context) { return } - ctx.PageData["prReview"] = map[string]interface{}{ + ctx.PageData["prReview"] = map[string]any{ "numberOfFiles": diff.NumFiles, "numberOfViewedFiles": diff.NumViewedFiles, } @@ -937,7 +937,7 @@ func UpdatePullRequest(ctx *context.Context) { if err = pull_service.Update(ctx, issue.PullRequest, ctx.Doer, message, rebase); err != nil { if models.IsErrMergeConflicts(err) { conflictError := err.(models.ErrMergeConflicts) - flashError, err := ctx.RenderToString(tplAlertDetails, map[string]interface{}{ + flashError, err := ctx.RenderToString(tplAlertDetails, map[string]any{ "Message": ctx.Tr("repo.pulls.merge_conflict"), "Summary": ctx.Tr("repo.pulls.merge_conflict_summary"), "Details": utils.SanitizeFlashErrorString(conflictError.StdErr) + "
" + utils.SanitizeFlashErrorString(conflictError.StdOut), @@ -951,7 +951,7 @@ func UpdatePullRequest(ctx *context.Context) { return } else if models.IsErrRebaseConflicts(err) { conflictError := err.(models.ErrRebaseConflicts) - flashError, err := ctx.RenderToString(tplAlertDetails, map[string]interface{}{ + flashError, err := ctx.RenderToString(tplAlertDetails, map[string]any{ "Message": ctx.Tr("repo.pulls.rebase_conflict", utils.SanitizeFlashErrorString(conflictError.CommitSHA)), "Summary": ctx.Tr("repo.pulls.rebase_conflict_summary"), "Details": utils.SanitizeFlashErrorString(conflictError.StdErr) + "
" + utils.SanitizeFlashErrorString(conflictError.StdOut), @@ -1086,7 +1086,7 @@ func MergePullRequest(ctx *context.Context) { ctx.Redirect(issue.Link()) } else if models.IsErrMergeConflicts(err) { conflictError := err.(models.ErrMergeConflicts) - flashError, err := ctx.RenderToString(tplAlertDetails, map[string]interface{}{ + flashError, err := ctx.RenderToString(tplAlertDetails, map[string]any{ "Message": ctx.Tr("repo.editor.merge_conflict"), "Summary": ctx.Tr("repo.editor.merge_conflict_summary"), "Details": utils.SanitizeFlashErrorString(conflictError.StdErr) + "
" + utils.SanitizeFlashErrorString(conflictError.StdOut), @@ -1099,7 +1099,7 @@ func MergePullRequest(ctx *context.Context) { ctx.Redirect(issue.Link()) } else if models.IsErrRebaseConflicts(err) { conflictError := err.(models.ErrRebaseConflicts) - flashError, err := ctx.RenderToString(tplAlertDetails, map[string]interface{}{ + flashError, err := ctx.RenderToString(tplAlertDetails, map[string]any{ "Message": ctx.Tr("repo.pulls.rebase_conflict", utils.SanitizeFlashErrorString(conflictError.CommitSHA)), "Summary": ctx.Tr("repo.pulls.rebase_conflict_summary"), "Details": utils.SanitizeFlashErrorString(conflictError.StdErr) + "
" + utils.SanitizeFlashErrorString(conflictError.StdOut), @@ -1129,7 +1129,7 @@ func MergePullRequest(ctx *context.Context) { if len(message) == 0 { ctx.Flash.Error(ctx.Tr("repo.pulls.push_rejected_no_message")) } else { - flashError, err := ctx.RenderToString(tplAlertDetails, map[string]interface{}{ + flashError, err := ctx.RenderToString(tplAlertDetails, map[string]any{ "Message": ctx.Tr("repo.pulls.push_rejected"), "Summary": ctx.Tr("repo.pulls.push_rejected_summary"), "Details": utils.SanitizeFlashErrorString(pushrejErr.Message), @@ -1302,7 +1302,7 @@ func CompareAndPullRequestPost(ctx *context.Context) { ctx.JSONError(ctx.Tr("repo.pulls.push_rejected_no_message")) return } - flashError, err := ctx.RenderToString(tplAlertDetails, map[string]interface{}{ + flashError, err := ctx.RenderToString(tplAlertDetails, map[string]any{ "Message": ctx.Tr("repo.pulls.push_rejected"), "Summary": ctx.Tr("repo.pulls.push_rejected_summary"), "Details": utils.SanitizeFlashErrorString(pushrejErr.Message), @@ -1407,7 +1407,7 @@ func CleanUpPullRequest(ctx *context.Context) { } defer func() { - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "redirect": issue.Link(), }) }() @@ -1519,7 +1519,7 @@ func UpdatePullRequestTarget(ctx *context.Context) { errorMessage := ctx.Tr("repo.pulls.has_pull_request", html.EscapeString(ctx.Repo.RepoLink+"/pulls/"+strconv.FormatInt(err.IssueID, 10)), html.EscapeString(RepoRelPath), err.IssueID) // FIXME: Creates url inside locale string ctx.Flash.Error(errorMessage) - ctx.JSON(http.StatusConflict, map[string]interface{}{ + ctx.JSON(http.StatusConflict, map[string]any{ "error": err.Error(), "user_error": errorMessage, }) @@ -1527,7 +1527,7 @@ func UpdatePullRequestTarget(ctx *context.Context) { errorMessage := ctx.Tr("repo.pulls.is_closed") ctx.Flash.Error(errorMessage) - ctx.JSON(http.StatusConflict, map[string]interface{}{ + ctx.JSON(http.StatusConflict, map[string]any{ "error": err.Error(), "user_error": errorMessage, }) @@ -1535,7 +1535,7 @@ func UpdatePullRequestTarget(ctx *context.Context) { errorMessage := ctx.Tr("repo.pulls.has_merged") ctx.Flash.Error(errorMessage) - ctx.JSON(http.StatusConflict, map[string]interface{}{ + ctx.JSON(http.StatusConflict, map[string]any{ "error": err.Error(), "user_error": errorMessage, }) @@ -1543,7 +1543,7 @@ func UpdatePullRequestTarget(ctx *context.Context) { errorMessage := ctx.Tr("repo.pulls.nothing_to_compare") ctx.Flash.Error(errorMessage) - ctx.JSON(http.StatusBadRequest, map[string]interface{}{ + ctx.JSON(http.StatusBadRequest, map[string]any{ "error": err.Error(), "user_error": errorMessage, }) @@ -1554,7 +1554,7 @@ func UpdatePullRequestTarget(ctx *context.Context) { } notification.NotifyPullRequestChangeTargetBranch(ctx, ctx.Doer, pr, targetBranch) - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "base_branch": pr.BaseBranch, }) } @@ -1582,7 +1582,7 @@ func SetAllowEdits(ctx *context.Context) { return } - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "allow_maintainer_edit": pr.AllowMaintainerEdit, }) } diff --git a/routers/web/repo/pull_review.go b/routers/web/repo/pull_review.go index 5aa5811367056..1645155bf86bb 100644 --- a/routers/web/repo/pull_review.go +++ b/routers/web/repo/pull_review.go @@ -153,7 +153,7 @@ func UpdateResolveConversation(ctx *context.Context) { renderConversation(ctx, comment) return } - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "ok": true, }) } diff --git a/routers/web/repo/release.go b/routers/web/repo/release.go index 5fddddb344080..32438a14daef2 100644 --- a/routers/web/repo/release.go +++ b/routers/web/repo/release.go @@ -607,13 +607,13 @@ func deleteReleaseOrTag(ctx *context.Context, isDelTag bool) { } if isDelTag { - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "redirect": ctx.Repo.RepoLink + "/tags", }) return } - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "redirect": ctx.Repo.RepoLink + "/releases", }) } diff --git a/routers/web/repo/repo.go b/routers/web/repo/repo.go index 781a12b2d9270..d1ccb011bb1f0 100644 --- a/routers/web/repo/repo.go +++ b/routers/web/repo/repo.go @@ -181,7 +181,7 @@ func Create(ctx *context.Context) { ctx.HTML(http.StatusOK, tplCreate) } -func handleCreateError(ctx *context.Context, owner *user_model.User, err error, name string, tpl base.TplName, form interface{}) { +func handleCreateError(ctx *context.Context, owner *user_model.User, err error, name string, tpl base.TplName, form any) { switch { case repo_model.IsErrReachLimitOfRepo(err): maxCreationLimit := owner.MaxCreationLimit() @@ -482,7 +482,7 @@ func InitiateDownload(ctx *context.Context) { completed = true } - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "complete": completed, }) } diff --git a/routers/web/repo/setting/collaboration.go b/routers/web/repo/setting/collaboration.go index d3a9959104a4a..8f2d30686207c 100644 --- a/routers/web/repo/setting/collaboration.go +++ b/routers/web/repo/setting/collaboration.go @@ -133,7 +133,7 @@ func DeleteCollaboration(ctx *context.Context) { ctx.Flash.Success(ctx.Tr("repo.settings.remove_collaborator_success")) } - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "redirect": ctx.Repo.RepoLink + "/settings/collaboration", }) } @@ -204,7 +204,7 @@ func DeleteTeam(ctx *context.Context) { } ctx.Flash.Success(ctx.Tr("repo.settings.remove_team_success")) - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "redirect": ctx.Repo.RepoLink + "/settings/collaboration", }) } diff --git a/routers/web/repo/setting/deploy_key.go b/routers/web/repo/setting/deploy_key.go index 9776095672ebb..d08c51f5e5c3b 100644 --- a/routers/web/repo/setting/deploy_key.go +++ b/routers/web/repo/setting/deploy_key.go @@ -105,7 +105,7 @@ func DeleteDeployKey(ctx *context.Context) { ctx.Flash.Success(ctx.Tr("repo.settings.deploy_key_deletion_success")) } - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "redirect": ctx.Repo.RepoLink + "/settings/keys", }) } diff --git a/routers/web/repo/setting/protected_branch.go b/routers/web/repo/setting/protected_branch.go index 962b85d0cd95c..777d52c858061 100644 --- a/routers/web/repo/setting/protected_branch.go +++ b/routers/web/repo/setting/protected_branch.go @@ -307,7 +307,7 @@ func DeleteProtectedBranchRulePost(ctx *context.Context) { ruleID := ctx.ParamsInt64("id") if ruleID <= 0 { ctx.Flash.Error(ctx.Tr("repo.settings.remove_protected_branch_failed", fmt.Sprintf("%d", ruleID))) - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "redirect": fmt.Sprintf("%s/settings/branches", ctx.Repo.RepoLink), }) return @@ -316,7 +316,7 @@ func DeleteProtectedBranchRulePost(ctx *context.Context) { rule, err := git_model.GetProtectedBranchRuleByID(ctx, ctx.Repo.Repository.ID, ruleID) if err != nil { ctx.Flash.Error(ctx.Tr("repo.settings.remove_protected_branch_failed", fmt.Sprintf("%d", ruleID))) - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "redirect": fmt.Sprintf("%s/settings/branches", ctx.Repo.RepoLink), }) return @@ -324,7 +324,7 @@ func DeleteProtectedBranchRulePost(ctx *context.Context) { if rule == nil { ctx.Flash.Error(ctx.Tr("repo.settings.remove_protected_branch_failed", fmt.Sprintf("%d", ruleID))) - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "redirect": fmt.Sprintf("%s/settings/branches", ctx.Repo.RepoLink), }) return @@ -332,14 +332,14 @@ func DeleteProtectedBranchRulePost(ctx *context.Context) { if err := git_model.DeleteProtectedBranch(ctx, ctx.Repo.Repository.ID, ruleID); err != nil { ctx.Flash.Error(ctx.Tr("repo.settings.remove_protected_branch_failed", rule.RuleName)) - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "redirect": fmt.Sprintf("%s/settings/branches", ctx.Repo.RepoLink), }) return } ctx.Flash.Success(ctx.Tr("repo.settings.remove_protected_branch_success", rule.RuleName)) - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "redirect": fmt.Sprintf("%s/settings/branches", ctx.Repo.RepoLink), }) } diff --git a/routers/web/repo/setting/webhook.go b/routers/web/repo/setting/webhook.go index a1cedd9a31a90..d85d5c8b07ff6 100644 --- a/routers/web/repo/setting/webhook.go +++ b/routers/web/repo/setting/webhook.go @@ -145,7 +145,7 @@ func WebhooksNew(ctx *context.Context) { return } if hookType == "discord" { - ctx.Data["DiscordHook"] = map[string]interface{}{ + ctx.Data["DiscordHook"] = map[string]any{ "Username": "Gitea", } } @@ -196,7 +196,7 @@ type webhookParams struct { Secret string HTTPMethod string WebhookForm forms.WebhookForm - Meta interface{} + Meta any } func createWebhook(ctx *context.Context, params webhookParams) { @@ -729,7 +729,7 @@ func DeleteWebhook(ctx *context.Context) { ctx.Flash.Success(ctx.Tr("repo.settings.webhook_deletion_success")) } - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "redirect": ctx.Repo.RepoLink + "/settings/hooks", }) } diff --git a/routers/web/repo/topic.go b/routers/web/repo/topic.go index 4c0b38bd91027..d22c3c6aa3748 100644 --- a/routers/web/repo/topic.go +++ b/routers/web/repo/topic.go @@ -15,7 +15,7 @@ import ( // TopicsPost response for creating repository func TopicsPost(ctx *context.Context) { if ctx.Doer == nil { - ctx.JSON(http.StatusForbidden, map[string]interface{}{ + ctx.JSON(http.StatusForbidden, map[string]any{ "message": "Only owners could change the topics.", }) return @@ -30,7 +30,7 @@ func TopicsPost(ctx *context.Context) { validTopics, invalidTopics := repo_model.SanitizeAndValidateTopics(topics) if len(validTopics) > 25 { - ctx.JSON(http.StatusUnprocessableEntity, map[string]interface{}{ + ctx.JSON(http.StatusUnprocessableEntity, map[string]any{ "invalidTopics": nil, "message": ctx.Tr("repo.topic.count_prompt"), }) @@ -38,7 +38,7 @@ func TopicsPost(ctx *context.Context) { } if len(invalidTopics) > 0 { - ctx.JSON(http.StatusUnprocessableEntity, map[string]interface{}{ + ctx.JSON(http.StatusUnprocessableEntity, map[string]any{ "invalidTopics": invalidTopics, "message": ctx.Tr("repo.topic.format_prompt"), }) @@ -48,13 +48,13 @@ func TopicsPost(ctx *context.Context) { err := repo_model.SaveTopics(ctx.Repo.Repository.ID, validTopics...) if err != nil { log.Error("SaveTopics failed: %v", err) - ctx.JSON(http.StatusInternalServerError, map[string]interface{}{ + ctx.JSON(http.StatusInternalServerError, map[string]any{ "message": "Save topics failed.", }) return } - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "status": "ok", }) } diff --git a/routers/web/repo/wiki.go b/routers/web/repo/wiki.go index 22cfe6dd25873..7da6917912e4b 100644 --- a/routers/web/repo/wiki.go +++ b/routers/web/repo/wiki.go @@ -791,7 +791,7 @@ func DeleteWikiPagePost(ctx *context.Context) { notification.NotifyDeleteWikiPage(ctx, ctx.Doer, ctx.Repo.Repository, string(wikiName)) - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "redirect": ctx.Repo.RepoLink + "/wiki/", }) } diff --git a/routers/web/repo/wiki_test.go b/routers/web/repo/wiki_test.go index d85879d1e5cf8..e1284fad6707f 100644 --- a/routers/web/repo/wiki_test.go +++ b/routers/web/repo/wiki_test.go @@ -62,7 +62,7 @@ func assertWikiNotExists(t *testing.T, repo *repo_model.Repository, wikiName wik assert.Nil(t, wikiEntry(t, repo, wikiName)) } -func assertPagesMetas(t *testing.T, expectedNames []string, metas interface{}) { +func assertPagesMetas(t *testing.T, expectedNames []string, metas any) { pageMetas, ok := metas.([]PageMeta) if !assert.True(t, ok) { return diff --git a/routers/web/shared/actions/runners.go b/routers/web/shared/actions/runners.go index c212c4ff25d4b..21e5a90d8f206 100644 --- a/routers/web/shared/actions/runners.go +++ b/routers/web/shared/actions/runners.go @@ -160,7 +160,7 @@ func RunnerDeletePost(ctx *context.Context, runnerID int64, log.Warn("DeleteRunnerPost.UpdateRunner failed: %v, url: %s", err, ctx.Req.URL) ctx.Flash.Warning(ctx.Tr("actions.runners.delete_runner_failed")) - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "redirect": failedRedirectTo, }) return @@ -170,7 +170,7 @@ func RunnerDeletePost(ctx *context.Context, runnerID int64, ctx.Flash.Success(ctx.Tr("actions.runners.delete_runner_success")) - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "redirect": successRedirectTo, }) } diff --git a/routers/web/user/home.go b/routers/web/user/home.go index 2513fc9a98383..1b0f651b07da9 100644 --- a/routers/web/user/home.go +++ b/routers/web/user/home.go @@ -97,7 +97,7 @@ func Dashboard(ctx *context.Context) { uid = ctxUser.ID } - ctx.PageData["dashboardRepoList"] = map[string]interface{}{ + ctx.PageData["dashboardRepoList"] = map[string]any{ "searchLimit": setting.UI.User.RepoPagingNum, "uid": uid, } diff --git a/routers/web/user/package.go b/routers/web/user/package.go index 20141914b655b..551e7f54c854d 100644 --- a/routers/web/user/package.go +++ b/routers/web/user/package.go @@ -22,6 +22,7 @@ import ( "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/web" + packages_helper "code.gitea.io/gitea/routers/api/packages/helper" shared_user "code.gitea.io/gitea/routers/web/shared/user" "code.gitea.io/gitea/services/forms" packages_service "code.gitea.io/gitea/services/packages" @@ -443,18 +444,11 @@ func DownloadPackageFile(ctx *context.Context) { return } - s, _, err := packages_service.GetPackageFileStream( - ctx, - pf, - ) + s, u, _, err := packages_service.GetPackageFileStream(ctx, pf) if err != nil { ctx.ServerError("GetPackageFileStream", err) return } - defer s.Close() - ctx.ServeContent(s, &context.ServeHeaderOptions{ - Filename: pf.Name, - LastModified: pf.CreatedUnix.AsLocalTime(), - }) + packages_helper.ServePackageFile(ctx, s, u, pf) } diff --git a/routers/web/user/search.go b/routers/web/user/search.go index bdc4116e3776b..fa2e52dd4194f 100644 --- a/routers/web/user/search.go +++ b/routers/web/user/search.go @@ -28,7 +28,7 @@ func Search(ctx *context.Context) { ListOptions: listOptions, }) if err != nil { - ctx.JSON(http.StatusInternalServerError, map[string]interface{}{ + ctx.JSON(http.StatusInternalServerError, map[string]any{ "ok": false, "error": err.Error(), }) @@ -37,7 +37,7 @@ func Search(ctx *context.Context) { ctx.SetTotalCountHeader(maxResults) - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "ok": true, "data": convert.ToUsers(ctx, ctx.Doer, users), }) diff --git a/routers/web/user/setting/account.go b/routers/web/user/setting/account.go index a67c2398fb0b7..532f0d8e39126 100644 --- a/routers/web/user/setting/account.go +++ b/routers/web/user/setting/account.go @@ -227,7 +227,7 @@ func DeleteEmail(ctx *context.Context) { log.Trace("Email address deleted: %s", ctx.Doer.Name) ctx.Flash.Success(ctx.Tr("settings.email_deletion_success")) - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "redirect": setting.AppSubURL + "/user/settings/account", }) } diff --git a/routers/web/user/setting/applications.go b/routers/web/user/setting/applications.go index f9e9ca5e52d31..81209376960d5 100644 --- a/routers/web/user/setting/applications.go +++ b/routers/web/user/setting/applications.go @@ -83,7 +83,7 @@ func DeleteApplication(ctx *context.Context) { ctx.Flash.Success(ctx.Tr("settings.delete_token_success")) } - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "redirect": setting.AppSubURL + "/user/settings/applications", }) } diff --git a/routers/web/user/setting/keys.go b/routers/web/user/setting/keys.go index 6debf95bbce06..d9412cae7cae8 100644 --- a/routers/web/user/setting/keys.go +++ b/routers/web/user/setting/keys.go @@ -256,7 +256,7 @@ func DeleteKey(ctx *context.Context) { ctx.Flash.Warning("Function not implemented") ctx.Redirect(setting.AppSubURL + "/user/settings/keys") } - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "redirect": setting.AppSubURL + "/user/settings/keys", }) } diff --git a/routers/web/user/setting/oauth2_common.go b/routers/web/user/setting/oauth2_common.go index 5de0f0e22f427..923ce4b4367b9 100644 --- a/routers/web/user/setting/oauth2_common.go +++ b/routers/web/user/setting/oauth2_common.go @@ -138,7 +138,7 @@ func (oa *OAuth2CommonHandlers) DeleteApp(ctx *context.Context) { } ctx.Flash.Success(ctx.Tr("settings.remove_oauth2_application_success")) - ctx.JSON(http.StatusOK, map[string]interface{}{"redirect": oa.BasePathList}) + ctx.JSON(http.StatusOK, map[string]any{"redirect": oa.BasePathList}) } // RevokeGrant revokes the grant @@ -149,5 +149,5 @@ func (oa *OAuth2CommonHandlers) RevokeGrant(ctx *context.Context) { } ctx.Flash.Success(ctx.Tr("settings.revoke_oauth2_grant_success")) - ctx.JSON(http.StatusOK, map[string]interface{}{"redirect": oa.BasePathList}) + ctx.JSON(http.StatusOK, map[string]any{"redirect": oa.BasePathList}) } diff --git a/routers/web/user/setting/security/openid.go b/routers/web/user/setting/security/openid.go index 08fcb6b62343c..f4133f3916026 100644 --- a/routers/web/user/setting/security/openid.go +++ b/routers/web/user/setting/security/openid.go @@ -112,7 +112,7 @@ func DeleteOpenID(ctx *context.Context) { log.Trace("OpenID address deleted: %s", ctx.Doer.Name) ctx.Flash.Success(ctx.Tr("settings.openid_deletion_success")) - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "redirect": setting.AppSubURL + "/user/settings/security", }) } diff --git a/routers/web/user/setting/security/security.go b/routers/web/user/setting/security/security.go index 6e6e7efb0b2c1..cc5f817a9d428 100644 --- a/routers/web/user/setting/security/security.go +++ b/routers/web/user/setting/security/security.go @@ -48,7 +48,7 @@ func DeleteAccountLink(ctx *context.Context) { } } - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "redirect": setting.AppSubURL + "/user/settings/security", }) } diff --git a/routers/web/user/setting/security/webauthn.go b/routers/web/user/setting/security/webauthn.go index 826562f15748d..89ac184a47e7c 100644 --- a/routers/web/user/setting/security/webauthn.go +++ b/routers/web/user/setting/security/webauthn.go @@ -116,7 +116,7 @@ func WebauthnDelete(ctx *context.Context) { ctx.ServerError("GetWebAuthnCredentialByID", err) return } - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "redirect": setting.AppSubURL + "/user/settings/security", }) } diff --git a/routers/web/user/setting/webhooks.go b/routers/web/user/setting/webhooks.go index 9b0b0c9611c1a..db03d7b1ed20d 100644 --- a/routers/web/user/setting/webhooks.go +++ b/routers/web/user/setting/webhooks.go @@ -42,7 +42,7 @@ func DeleteWebhook(ctx *context.Context) { ctx.Flash.Success(ctx.Tr("repo.settings.webhook_deletion_success")) } - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "redirect": setting.AppSubURL + "/user/settings/hooks", }) } diff --git a/routers/web/user/task.go b/routers/web/user/task.go index 3818682403d0f..d92bf64af0fb3 100644 --- a/routers/web/user/task.go +++ b/routers/web/user/task.go @@ -17,12 +17,12 @@ func TaskStatus(ctx *context.Context) { task, opts, err := admin_model.GetMigratingTaskByID(ctx.ParamsInt64("task"), ctx.Doer.ID) if err != nil { if admin_model.IsErrTaskDoesNotExist(err) { - ctx.JSON(http.StatusNotFound, map[string]interface{}{ + ctx.JSON(http.StatusNotFound, map[string]any{ "error": "task `" + strconv.FormatInt(ctx.ParamsInt64("task"), 10) + "` does not exist", }) return } - ctx.JSON(http.StatusInternalServerError, map[string]interface{}{ + ctx.JSON(http.StatusInternalServerError, map[string]any{ "err": err, }) return @@ -36,13 +36,13 @@ func TaskStatus(ctx *context.Context) { if err := json.Unmarshal([]byte(message), &translatableMessage); err != nil { translatableMessage = admin_model.TranslatableMessage{ Format: "migrate.migrating_failed.error", - Args: []interface{}{task.Message}, + Args: []any{task.Message}, } } message = ctx.Tr(translatableMessage.Format, translatableMessage.Args...) } - ctx.JSON(http.StatusOK, map[string]interface{}{ + ctx.JSON(http.StatusOK, map[string]any{ "status": task.Status, "message": message, "repo-id": task.RepoID, diff --git a/routers/web/webfinger.go b/routers/web/webfinger.go index 1442e09a31431..0966b04951a9b 100644 --- a/routers/web/webfinger.go +++ b/routers/web/webfinger.go @@ -18,18 +18,18 @@ import ( // https://datatracker.ietf.org/doc/html/draft-ietf-appsawg-webfinger-14#section-4.4 type webfingerJRD struct { - Subject string `json:"subject,omitempty"` - Aliases []string `json:"aliases,omitempty"` - Properties map[string]interface{} `json:"properties,omitempty"` - Links []*webfingerLink `json:"links,omitempty"` + Subject string `json:"subject,omitempty"` + Aliases []string `json:"aliases,omitempty"` + Properties map[string]any `json:"properties,omitempty"` + Links []*webfingerLink `json:"links,omitempty"` } type webfingerLink struct { - Rel string `json:"rel,omitempty"` - Type string `json:"type,omitempty"` - Href string `json:"href,omitempty"` - Titles map[string]string `json:"titles,omitempty"` - Properties map[string]interface{} `json:"properties,omitempty"` + Rel string `json:"rel,omitempty"` + Type string `json:"type,omitempty"` + Href string `json:"href,omitempty"` + Titles map[string]string `json:"titles,omitempty"` + Properties map[string]any `json:"properties,omitempty"` } // WebfingerQuery returns information about a resource diff --git a/services/auth/source/db/authenticate.go b/services/auth/source/db/authenticate.go index 773ec601ba338..34a0459149a9e 100644 --- a/services/auth/source/db/authenticate.go +++ b/services/auth/source/db/authenticate.go @@ -4,19 +4,54 @@ package db import ( + "fmt" + "code.gitea.io/gitea/models/db" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/util" ) +// ErrUserPasswordNotSet represents a "ErrUserPasswordNotSet" kind of error. +type ErrUserPasswordNotSet struct { + UID int64 + Name string +} + +func (err ErrUserPasswordNotSet) Error() string { + return fmt.Sprintf("user's password isn't set [uid: %d, name: %s]", err.UID, err.Name) +} + +// Unwrap unwraps this error as a ErrInvalidArgument error +func (err ErrUserPasswordNotSet) Unwrap() error { + return util.ErrInvalidArgument +} + +// ErrUserPasswordInvalid represents a "ErrUserPasswordInvalid" kind of error. +type ErrUserPasswordInvalid struct { + UID int64 + Name string +} + +func (err ErrUserPasswordInvalid) Error() string { + return fmt.Sprintf("user's password is invalid [uid: %d, name: %s]", err.UID, err.Name) +} + +// Unwrap unwraps this error as a ErrInvalidArgument error +func (err ErrUserPasswordInvalid) Unwrap() error { + return util.ErrInvalidArgument +} + // Authenticate authenticates the provided user against the DB func Authenticate(user *user_model.User, login, password string) (*user_model.User, error) { if user == nil { return nil, user_model.ErrUserNotExist{Name: login} } - if !user.IsPasswordSet() || !user.ValidatePassword(password) { - return nil, user_model.ErrUserNotExist{UID: user.ID, Name: user.Name} + if !user.IsPasswordSet() { + return nil, ErrUserPasswordNotSet{UID: user.ID, Name: user.Name} + } else if !user.ValidatePassword(password) { + return nil, ErrUserPasswordInvalid{UID: user.ID, Name: user.Name} } // Update password hash if server password hash algorithm have changed diff --git a/services/auth/source/oauth2/jwtsigningkey.go b/services/auth/source/oauth2/jwtsigningkey.go index ed0fc67ca0f94..33bd3648e717f 100644 --- a/services/auth/source/oauth2/jwtsigningkey.go +++ b/services/auth/source/oauth2/jwtsigningkey.go @@ -38,8 +38,8 @@ func (err ErrInvalidAlgorithmType) Error() string { type JWTSigningKey interface { IsSymmetric() bool SigningMethod() jwt.SigningMethod - SignKey() interface{} - VerifyKey() interface{} + SignKey() any + VerifyKey() any ToJWK() (map[string]string, error) PreProcessToken(*jwt.Token) } @@ -57,11 +57,11 @@ func (key hmacSigningKey) SigningMethod() jwt.SigningMethod { return key.signingMethod } -func (key hmacSigningKey) SignKey() interface{} { +func (key hmacSigningKey) SignKey() any { return key.secret } -func (key hmacSigningKey) VerifyKey() interface{} { +func (key hmacSigningKey) VerifyKey() any { return key.secret } @@ -101,11 +101,11 @@ func (key rsaSingingKey) SigningMethod() jwt.SigningMethod { return key.signingMethod } -func (key rsaSingingKey) SignKey() interface{} { +func (key rsaSingingKey) SignKey() any { return key.key } -func (key rsaSingingKey) VerifyKey() interface{} { +func (key rsaSingingKey) VerifyKey() any { return key.key.Public() } @@ -152,11 +152,11 @@ func (key eddsaSigningKey) SigningMethod() jwt.SigningMethod { return key.signingMethod } -func (key eddsaSigningKey) SignKey() interface{} { +func (key eddsaSigningKey) SignKey() any { return key.key } -func (key eddsaSigningKey) VerifyKey() interface{} { +func (key eddsaSigningKey) VerifyKey() any { return key.key.Public() } @@ -203,11 +203,11 @@ func (key ecdsaSingingKey) SigningMethod() jwt.SigningMethod { return key.signingMethod } -func (key ecdsaSingingKey) SignKey() interface{} { +func (key ecdsaSingingKey) SignKey() any { return key.key } -func (key ecdsaSingingKey) VerifyKey() interface{} { +func (key ecdsaSingingKey) VerifyKey() any { return key.key.Public() } @@ -229,7 +229,7 @@ func (key ecdsaSingingKey) PreProcessToken(token *jwt.Token) { } // CreateJWTSigningKey creates a signing key from an algorithm / key pair. -func CreateJWTSigningKey(algorithm string, key interface{}) (JWTSigningKey, error) { +func CreateJWTSigningKey(algorithm string, key any) (JWTSigningKey, error) { var signingMethod jwt.SigningMethod switch algorithm { case "HS256": @@ -292,7 +292,7 @@ var DefaultSigningKey JWTSigningKey // InitSigningKey creates the default signing key from settings or creates a random key. func InitSigningKey() error { var err error - var key interface{} + var key any switch setting.OAuth2.JWTSigningAlgorithm { case "HS256": @@ -335,7 +335,7 @@ func InitSigningKey() error { // loadSymmetricKey checks if the configured secret is valid. // If it is not valid, it will return an error. -func loadSymmetricKey() (interface{}, error) { +func loadSymmetricKey() (any, error) { key := make([]byte, 32) n, err := base64.RawURLEncoding.Decode(key, []byte(setting.OAuth2.JWTSecretBase64)) if err != nil { @@ -350,7 +350,7 @@ func loadSymmetricKey() (interface{}, error) { // loadOrCreateAsymmetricKey checks if the configured private key exists. // If it does not exist a new random key gets generated and saved on the configured path. -func loadOrCreateAsymmetricKey() (interface{}, error) { +func loadOrCreateAsymmetricKey() (any, error) { keyPath := setting.OAuth2.JWTSigningPrivateKeyFile isExist, err := util.IsExist(keyPath) @@ -359,7 +359,7 @@ func loadOrCreateAsymmetricKey() (interface{}, error) { } if !isExist { err := func() error { - key, err := func() (interface{}, error) { + key, err := func() (any, error) { switch { case strings.HasPrefix(setting.OAuth2.JWTSigningAlgorithm, "RS"): return rsa.GenerateKey(rand.Reader, 4096) diff --git a/services/auth/source/oauth2/token.go b/services/auth/source/oauth2/token.go index c5a064054e5a2..612c9db8cf5f0 100644 --- a/services/auth/source/oauth2/token.go +++ b/services/auth/source/oauth2/token.go @@ -41,7 +41,7 @@ type Token struct { // ParseToken parses a signed jwt string func ParseToken(jwtToken string, signingKey JWTSigningKey) (*Token, error) { - parsedToken, err := jwt.ParseWithClaims(jwtToken, &Token{}, func(token *jwt.Token) (interface{}, error) { + parsedToken, err := jwt.ParseWithClaims(jwtToken, &Token{}, func(token *jwt.Token) (any, error) { if token.Method == nil || token.Method.Alg() != signingKey.SigningMethod().Alg() { return nil, fmt.Errorf("unexpected signing algo: %v", token.Header["alg"]) } diff --git a/services/context/user.go b/services/context/user.go index 4e74aa50bd1e2..62d2dc0aa2347 100644 --- a/services/context/user.go +++ b/services/context/user.go @@ -15,7 +15,7 @@ import ( // UserAssignmentWeb returns a middleware to handle context-user assignment for web routes func UserAssignmentWeb() func(ctx *context.Context) { return func(ctx *context.Context) { - errorFn := func(status int, title string, obj interface{}) { + errorFn := func(status int, title string, obj any) { err, ok := obj.(error) if !ok { err = fmt.Errorf("%s", obj) @@ -58,7 +58,7 @@ func UserAssignmentAPI() func(ctx *context.APIContext) { } } -func userAssignment(ctx *context.Base, doer *user_model.User, errCb func(int, string, interface{})) (contextUser *user_model.User) { +func userAssignment(ctx *context.Base, doer *user_model.User, errCb func(int, string, any)) (contextUser *user_model.User) { username := ctx.Params(":username") if doer != nil && doer.LowerName == strings.ToLower(username) { diff --git a/services/cron/setting.go b/services/cron/setting.go index 952a4d17ab658..0656307cba0e9 100644 --- a/services/cron/setting.go +++ b/services/cron/setting.go @@ -14,7 +14,7 @@ type Config interface { IsEnabled() bool DoRunAtStart() bool GetSchedule() string - FormatMessage(locale translation.Locale, name, status, doer string, args ...interface{}) string + FormatMessage(locale translation.Locale, name, status, doer string, args ...any) string DoNoticeOnSuccess() bool } @@ -68,8 +68,8 @@ func (b *BaseConfig) DoNoticeOnSuccess() bool { // FormatMessage returns a message for the task // Please note the `status` string will be concatenated with `admin.dashboard.cron.` and `admin.dashboard.task.` to provide locale messages. Similarly `name` will be composed with `admin.dashboard.` to provide the locale name for the task. -func (b *BaseConfig) FormatMessage(locale translation.Locale, name, status, doer string, args ...interface{}) string { - realArgs := make([]interface{}, 0, len(args)+2) +func (b *BaseConfig) FormatMessage(locale translation.Locale, name, status, doer string, args ...any) string { + realArgs := make([]any, 0, len(args)+2) realArgs = append(realArgs, locale.Tr("admin.dashboard."+name)) if doer == "" { realArgs = append(realArgs, "(Cron)") diff --git a/services/externalaccount/link.go b/services/externalaccount/link.go index dcdc57ee489d8..a19d4c5ab3eb7 100644 --- a/services/externalaccount/link.go +++ b/services/externalaccount/link.go @@ -13,8 +13,8 @@ import ( // Store represents a thing that stores things type Store interface { - Get(interface{}) interface{} - Set(interface{}, interface{}) error + Get(any) any + Set(any, any) error Release() error } diff --git a/services/lfs/server.go b/services/lfs/server.go index b32f218785edc..cc0ec73105bd7 100644 --- a/services/lfs/server.go +++ b/services/lfs/server.go @@ -375,7 +375,7 @@ func VerifyHandler(ctx *context.Context) { writeStatus(ctx, status) } -func decodeJSON(req *http.Request, v interface{}) error { +func decodeJSON(req *http.Request, v any) error { defer req.Body.Close() dec := json.NewDecoder(req.Body) @@ -552,7 +552,7 @@ func handleLFSToken(ctx stdCtx.Context, tokenSHA string, target *repo_model.Repo if !strings.Contains(tokenSHA, ".") { return nil, nil } - token, err := jwt.ParseWithClaims(tokenSHA, &Claims{}, func(t *jwt.Token) (interface{}, error) { + token, err := jwt.ParseWithClaims(tokenSHA, &Claims{}, func(t *jwt.Token) (any, error) { if _, ok := t.Method.(*jwt.SigningMethodHMAC); !ok { return nil, fmt.Errorf("unexpected signing method: %v", t.Header["alg"]) } diff --git a/services/mailer/incoming/incoming.go b/services/mailer/incoming/incoming.go index 2653e80586d71..eade0cf271bf8 100644 --- a/services/mailer/incoming/incoming.go +++ b/services/mailer/incoming/incoming.go @@ -205,7 +205,7 @@ loop: if err := c.Store( handledSet, imap.FormatFlagsOp(imap.AddFlags, true), - []interface{}{imap.DeletedFlag}, + []any{imap.DeletedFlag}, nil, ); err != nil { return fmt.Errorf("imap store failed: %w", err) diff --git a/services/mailer/incoming/payload/payload.go b/services/mailer/incoming/payload/payload.go index eb82f5c3ed321..00ada7826bdaf 100644 --- a/services/mailer/incoming/payload/payload.go +++ b/services/mailer/incoming/payload/payload.go @@ -20,7 +20,7 @@ const ( ) // CreateReferencePayload creates data which GetReferenceFromPayload resolves to the reference again. -func CreateReferencePayload(reference interface{}) ([]byte, error) { +func CreateReferencePayload(reference any) ([]byte, error) { var refType payloadReferenceType var refID int64 @@ -44,7 +44,7 @@ func CreateReferencePayload(reference interface{}) ([]byte, error) { } // GetReferenceFromPayload resolves the reference from the payload -func GetReferenceFromPayload(ctx context.Context, payload []byte) (interface{}, error) { +func GetReferenceFromPayload(ctx context.Context, payload []byte) (any, error) { if len(payload) < 1 { return nil, util.NewInvalidArgumentErrorf("payload to small") } diff --git a/services/mailer/mail.go b/services/mailer/mail.go index 351b79b5df284..50d59a44527d1 100644 --- a/services/mailer/mail.go +++ b/services/mailer/mail.go @@ -67,7 +67,7 @@ func SendTestMail(email string) error { // sendUserMail sends a mail to the user func sendUserMail(language string, u *user_model.User, tpl base.TplName, code, subject, info string) { locale := translation.NewLocale(language) - data := map[string]interface{}{ + data := map[string]any{ "DisplayName": u.DisplayName(), "ActiveCodeLives": timeutil.MinutesToFriendly(setting.Service.ActiveCodeLives, locale), "ResetPwdCodeLives": timeutil.MinutesToFriendly(setting.Service.ResetPwdCodeLives, locale), @@ -118,7 +118,7 @@ func SendActivateEmailMail(u *user_model.User, email *user_model.EmailAddress) { return } locale := translation.NewLocale(u.Language) - data := map[string]interface{}{ + data := map[string]any{ "DisplayName": u.DisplayName(), "ActiveCodeLives": timeutil.MinutesToFriendly(setting.Service.ActiveCodeLives, locale), "Code": u.GenerateEmailActivateCode(email.Email), @@ -151,7 +151,7 @@ func SendRegisterNotifyMail(u *user_model.User) { } locale := translation.NewLocale(u.Language) - data := map[string]interface{}{ + data := map[string]any{ "DisplayName": u.DisplayName(), "Username": u.Name, "Language": locale.Language(), @@ -184,7 +184,7 @@ func SendCollaboratorMail(u, doer *user_model.User, repo *repo_model.Repository) repoName := repo.FullName() subject := locale.Tr("mail.repo.collaborator.added.subject", doer.DisplayName(), repoName) - data := map[string]interface{}{ + data := map[string]any{ "Subject": subject, "RepoName": repoName, "Link": repo.HTMLURL(), @@ -258,7 +258,7 @@ func composeIssueCommentMessages(ctx *mailCommentContext, lang string, recipient } locale := translation.NewLocale(lang) - mailMeta := map[string]interface{}{ + mailMeta := map[string]any{ "FallbackSubject": fallback, "Body": body, "Link": link, diff --git a/services/mailer/mail_release.go b/services/mailer/mail_release.go index ebf9285b0a2a1..fb638ebd42cf1 100644 --- a/services/mailer/mail_release.go +++ b/services/mailer/mail_release.go @@ -68,7 +68,7 @@ func mailNewRelease(ctx context.Context, lang string, tos []string, rel *repo_mo } subject := locale.Tr("mail.release.new.subject", rel.TagName, rel.Repo.FullName()) - mailMeta := map[string]interface{}{ + mailMeta := map[string]any{ "Release": rel, "Subject": subject, "Language": locale.Language(), diff --git a/services/mailer/mail_repo.go b/services/mailer/mail_repo.go index 9b2f24faa812d..e9c1991b5b80e 100644 --- a/services/mailer/mail_repo.go +++ b/services/mailer/mail_repo.go @@ -64,7 +64,7 @@ func sendRepoTransferNotifyMailPerLang(lang string, newOwner, doer *user_model.U subject = locale.Tr("mail.repo.transfer.subject_to", doer.DisplayName(), repo.FullName(), destination) } - data := map[string]interface{}{ + data := map[string]any{ "Doer": doer, "User": repo.Owner, "Repo": repo.FullName(), diff --git a/services/mailer/mail_team_invite.go b/services/mailer/mail_team_invite.go index 917e1844356d0..b6f47ee9215bc 100644 --- a/services/mailer/mail_team_invite.go +++ b/services/mailer/mail_team_invite.go @@ -34,7 +34,7 @@ func MailTeamInvite(ctx context.Context, inviter *user_model.User, team *org_mod locale := translation.NewLocale(inviter.Language) subject := locale.Tr("mail.team_invite.subject", inviter.DisplayName(), org.DisplayName()) - mailMeta := map[string]interface{}{ + mailMeta := map[string]any{ "Inviter": inviter, "Organization": org, "Team": team, diff --git a/services/migrations/codebase.go b/services/migrations/codebase.go index 22bf0f73de715..492fc908e904e 100644 --- a/services/migrations/codebase.go +++ b/services/migrations/codebase.go @@ -127,7 +127,7 @@ func (d *CodebaseDownloader) FormatCloneURL(opts base.MigrateOptions, remoteAddr return opts.CloneAddr, nil } -func (d *CodebaseDownloader) callAPI(endpoint string, parameter map[string]string, result interface{}) error { +func (d *CodebaseDownloader) callAPI(endpoint string, parameter map[string]string, result any) error { u, err := d.baseURL.Parse(endpoint) if err != nil { return err diff --git a/services/migrations/common.go b/services/migrations/common.go index 34d7c93ddf0b7..4f9837472d9dc 100644 --- a/services/migrations/common.go +++ b/services/migrations/common.go @@ -14,7 +14,7 @@ import ( ) // WarnAndNotice will log the provided message and send a repository notice -func WarnAndNotice(fmtStr string, args ...interface{}) { +func WarnAndNotice(fmtStr string, args ...any) { log.Warn(fmtStr, args...) if err := system_model.CreateRepositoryNotice(fmt.Sprintf(fmtStr, args...)); err != nil { log.Error("create repository notice failed: ", err) diff --git a/services/migrations/dump.go b/services/migrations/dump.go index 729112bcd2398..603954810cffa 100644 --- a/services/migrations/dump.go +++ b/services/migrations/dump.go @@ -112,7 +112,7 @@ func (g *RepositoryDumper) CreateRepo(repo *base.Repository, opts base.MigrateOp } defer f.Close() - bs, err := yaml.Marshal(map[string]interface{}{ + bs, err := yaml.Marshal(map[string]any{ "name": repo.Name, "owner": repo.Owner, "description": repo.Description, @@ -227,7 +227,7 @@ func (g *RepositoryDumper) CreateTopics(topics ...string) error { } defer f.Close() - bs, err := yaml.Marshal(map[string]interface{}{ + bs, err := yaml.Marshal(map[string]any{ "topics": topics, }) if err != nil { @@ -380,7 +380,7 @@ func (g *RepositoryDumper) CreateIssues(issues ...*base.Issue) error { return nil } -func (g *RepositoryDumper) createItems(dir string, itemFiles map[int64]*os.File, itemsMap map[int64][]interface{}) error { +func (g *RepositoryDumper) createItems(dir string, itemFiles map[int64]*os.File, itemsMap map[int64][]any) error { if err := os.MkdirAll(dir, os.ModePerm); err != nil { return err } @@ -394,7 +394,7 @@ func (g *RepositoryDumper) createItems(dir string, itemFiles map[int64]*os.File, return nil } -func (g *RepositoryDumper) encodeItems(number int64, items []interface{}, dir string, itemFiles map[int64]*os.File) error { +func (g *RepositoryDumper) encodeItems(number int64, items []any, dir string, itemFiles map[int64]*os.File) error { itemFile := itemFiles[number] if itemFile == nil { var err error @@ -413,7 +413,7 @@ func (g *RepositoryDumper) encodeItems(number int64, items []interface{}, dir st // CreateComments creates comments of issues func (g *RepositoryDumper) CreateComments(comments ...*base.Comment) error { - commentsMap := make(map[int64][]interface{}, len(comments)) + commentsMap := make(map[int64][]any, len(comments)) for _, comment := range comments { commentsMap[comment.IssueIndex] = append(commentsMap[comment.IssueIndex], comment) } @@ -621,7 +621,7 @@ func (g *RepositoryDumper) CreatePullRequests(prs ...*base.PullRequest) error { // CreateReviews create pull request reviews func (g *RepositoryDumper) CreateReviews(reviews ...*base.Review) error { - reviewsMap := make(map[int64][]interface{}, len(reviews)) + reviewsMap := make(map[int64][]any, len(reviews)) for _, review := range reviews { reviewsMap[review.IssueIndex] = append(reviewsMap[review.IssueIndex], review) } diff --git a/services/migrations/onedev.go b/services/migrations/onedev.go index 33fc43c349619..e2f7b771f369e 100644 --- a/services/migrations/onedev.go +++ b/services/migrations/onedev.go @@ -121,7 +121,7 @@ func (d *OneDevDownloader) LogString() string { return fmt.Sprintf("", d.baseURL, d.repoID, d.repoName) } -func (d *OneDevDownloader) callAPI(endpoint string, parameter map[string]string, result interface{}) error { +func (d *OneDevDownloader) callAPI(endpoint string, parameter map[string]string, result any) error { u, err := d.baseURL.Parse(endpoint) if err != nil { return err @@ -400,9 +400,9 @@ func (d *OneDevDownloader) GetComments(commentable base.Commentable) ([]*base.Co } rawChanges := make([]struct { - Date time.Time `json:"date"` - UserID int64 `json:"userId"` - Data map[string]interface{} `json:"data"` + Date time.Time `json:"date"` + UserID int64 `json:"userId"` + Data map[string]any `json:"data"` }, 0, 100) if context.IsPullRequest { diff --git a/services/mirror/mirror.go b/services/mirror/mirror.go index 35ba09521b663..abce1d3c2d45e 100644 --- a/services/mirror/mirror.go +++ b/services/mirror/mirror.go @@ -41,7 +41,7 @@ func Update(ctx context.Context, pullLimit, pushLimit int) error { } log.Trace("Doing: Update") - handler := func(idx int, bean interface{}) error { + handler := func(idx int, bean any) error { var repo *repo_model.Repository var mirrorType mirror_module.SyncType var referenceID int64 @@ -91,7 +91,7 @@ func Update(ctx context.Context, pullLimit, pushLimit int) error { pullMirrorsRequested := 0 if pullLimit != 0 { - if err := repo_model.MirrorsIterate(pullLimit, func(idx int, bean interface{}) error { + if err := repo_model.MirrorsIterate(pullLimit, func(idx int, bean any) error { if err := handler(idx, bean); err != nil { return err } @@ -105,7 +105,7 @@ func Update(ctx context.Context, pullLimit, pushLimit int) error { pushMirrorsRequested := 0 if pushLimit != 0 { - if err := repo_model.PushMirrorsIterate(ctx, pushLimit, func(idx int, bean interface{}) error { + if err := repo_model.PushMirrorsIterate(ctx, pushLimit, func(idx int, bean any) error { if err := handler(idx, bean); err != nil { return err } diff --git a/services/packages/auth.go b/services/packages/auth.go index a7acdaf1c3a9b..41d3a0a82511e 100644 --- a/services/packages/auth.go +++ b/services/packages/auth.go @@ -53,7 +53,7 @@ func ParseAuthorizationToken(req *http.Request) (int64, error) { return 0, fmt.Errorf("split token failed") } - token, err := jwt.ParseWithClaims(parts[1], &packageClaims{}, func(t *jwt.Token) (interface{}, error) { + token, err := jwt.ParseWithClaims(parts[1], &packageClaims{}, func(t *jwt.Token) (any, error) { if _, ok := t.Method.(*jwt.SigningMethodHMAC); !ok { return nil, fmt.Errorf("unexpected signing method: %v", t.Header["alg"]) } diff --git a/services/packages/packages.go b/services/packages/packages.go index 23aa8a5c31526..bdc56efeefa81 100644 --- a/services/packages/packages.go +++ b/services/packages/packages.go @@ -9,6 +9,7 @@ import ( "errors" "fmt" "io" + "net/url" "strings" "code.gitea.io/gitea/models/db" @@ -20,6 +21,7 @@ import ( "code.gitea.io/gitea/modules/notification" packages_module "code.gitea.io/gitea/modules/packages" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/storage" "code.gitea.io/gitea/modules/util" ) @@ -42,7 +44,7 @@ type PackageCreationInfo struct { PackageInfo SemverCompatible bool Creator *user_model.User - Metadata interface{} + Metadata any PackageProperties map[string]string VersionProperties map[string]string } @@ -562,70 +564,62 @@ func DeletePackageFile(ctx context.Context, pf *packages_model.PackageFile) erro } // GetFileStreamByPackageNameAndVersion returns the content of the specific package file -func GetFileStreamByPackageNameAndVersion(ctx context.Context, pvi *PackageInfo, pfi *PackageFileInfo) (io.ReadSeekCloser, *packages_model.PackageFile, error) { +func GetFileStreamByPackageNameAndVersion(ctx context.Context, pvi *PackageInfo, pfi *PackageFileInfo) (io.ReadSeekCloser, *url.URL, *packages_model.PackageFile, error) { log.Trace("Getting package file stream: %v, %v, %s, %s, %s, %s", pvi.Owner.ID, pvi.PackageType, pvi.Name, pvi.Version, pfi.Filename, pfi.CompositeKey) pv, err := packages_model.GetVersionByNameAndVersion(ctx, pvi.Owner.ID, pvi.PackageType, pvi.Name, pvi.Version) if err != nil { if err == packages_model.ErrPackageNotExist { - return nil, nil, err + return nil, nil, nil, err } log.Error("Error getting package: %v", err) - return nil, nil, err + return nil, nil, nil, err } return GetFileStreamByPackageVersion(ctx, pv, pfi) } -// GetFileStreamByPackageVersionAndFileID returns the content of the specific package file -func GetFileStreamByPackageVersionAndFileID(ctx context.Context, owner *user_model.User, versionID, fileID int64) (io.ReadSeekCloser, *packages_model.PackageFile, error) { - log.Trace("Getting package file stream: %v, %v, %v", owner.ID, versionID, fileID) - - pv, err := packages_model.GetVersionByID(ctx, versionID) - if err != nil { - if err != packages_model.ErrPackageNotExist { - log.Error("Error getting package version: %v", err) - } - return nil, nil, err - } - - p, err := packages_model.GetPackageByID(ctx, pv.PackageID) - if err != nil { - log.Error("Error getting package: %v", err) - return nil, nil, err - } - - if p.OwnerID != owner.ID { - return nil, nil, packages_model.ErrPackageNotExist - } - - pf, err := packages_model.GetFileForVersionByID(ctx, versionID, fileID) - if err != nil { - log.Error("Error getting file: %v", err) - return nil, nil, err - } - - return GetPackageFileStream(ctx, pf) -} - // GetFileStreamByPackageVersion returns the content of the specific package file -func GetFileStreamByPackageVersion(ctx context.Context, pv *packages_model.PackageVersion, pfi *PackageFileInfo) (io.ReadSeekCloser, *packages_model.PackageFile, error) { +func GetFileStreamByPackageVersion(ctx context.Context, pv *packages_model.PackageVersion, pfi *PackageFileInfo) (io.ReadSeekCloser, *url.URL, *packages_model.PackageFile, error) { pf, err := packages_model.GetFileForVersionByName(ctx, pv.ID, pfi.Filename, pfi.CompositeKey) if err != nil { - return nil, nil, err + return nil, nil, nil, err } return GetPackageFileStream(ctx, pf) } // GetPackageFileStream returns the content of the specific package file -func GetPackageFileStream(ctx context.Context, pf *packages_model.PackageFile) (io.ReadSeekCloser, *packages_model.PackageFile, error) { +func GetPackageFileStream(ctx context.Context, pf *packages_model.PackageFile) (io.ReadSeekCloser, *url.URL, *packages_model.PackageFile, error) { pb, err := packages_model.GetBlobByID(ctx, pf.BlobID) if err != nil { - return nil, nil, err + return nil, nil, nil, err + } + + return GetPackageBlobStream(ctx, pf, pb) +} + +// GetPackageBlobStream returns the content of the specific package blob +// If the storage supports direct serving and it's enabled, only the direct serving url is returned. +func GetPackageBlobStream(ctx context.Context, pf *packages_model.PackageFile, pb *packages_model.PackageBlob) (io.ReadSeekCloser, *url.URL, *packages_model.PackageFile, error) { + key := packages_module.BlobHash256Key(pb.HashSHA256) + + cs := packages_module.NewContentStore() + + var s io.ReadSeekCloser + var u *url.URL + var err error + + if cs.ShouldServeDirect() { + u, err = cs.GetServeDirectURL(key, pf.Name) + if err != nil && !errors.Is(err, storage.ErrURLNotSupported) { + log.Error("Error getting serve direct url: %v", err) + } + } + if u == nil { + s, err = cs.Get(key) } - s, err := packages_module.NewContentStore().Get(packages_module.BlobHash256Key(pb.HashSHA256)) if err == nil { if pf.IsLead { if err := packages_model.IncrementDownloadCounter(ctx, pf.VersionID); err != nil { @@ -633,7 +627,7 @@ func GetPackageFileStream(ctx context.Context, pf *packages_model.PackageFile) ( } } } - return s, pf, err + return s, u, pf, err } // RemoveAllPackages for User diff --git a/services/repository/files/content.go b/services/repository/files/content.go index c701431d6785d..30d62fbcdf7c0 100644 --- a/services/repository/files/content.go +++ b/services/repository/files/content.go @@ -40,9 +40,9 @@ func (ct *ContentType) String() string { // GetContentsOrList gets the meta data of a file's contents (*ContentsResponse) if treePath not a tree // directory, otherwise a listing of file contents ([]*ContentsResponse). Ref can be a branch, commit or tag -func GetContentsOrList(ctx context.Context, repo *repo_model.Repository, treePath, ref string) (interface{}, error) { +func GetContentsOrList(ctx context.Context, repo *repo_model.Repository, treePath, ref string) (any, error) { if repo.IsEmpty { - return make([]interface{}, 0), nil + return make([]any, 0), nil } if ref == "" { ref = repo.DefaultBranch diff --git a/services/task/migrate.go b/services/task/migrate.go index 98454482b5a6a..bebdb5078b26f 100644 --- a/services/task/migrate.go +++ b/services/task/migrate.go @@ -121,7 +121,7 @@ func runMigrateTask(t *admin_model.Task) (err error) { } }() - t.Repo, err = migrations.MigrateRepository(ctx, t.Doer, t.Owner.Name, *opts, func(format string, args ...interface{}) { + t.Repo, err = migrations.MigrateRepository(ctx, t.Doer, t.Owner.Name, *opts, func(format string, args ...any) { message := admin_model.TranslatableMessage{ Format: format, Args: args, diff --git a/templates/devtest/fomantic-modal.tmpl b/templates/devtest/fomantic-modal.tmpl index aaa4c2c12d1aa..799bab7594e2b 100644 --- a/templates/devtest/fomantic-modal.tmpl +++ b/templates/devtest/fomantic-modal.tmpl @@ -1,5 +1,18 @@ {{template "base/head" .}}
+ {{template "base/alert" .}} + + + + +
+