mirror of
https://github.com/go-gitea/gitea.git
synced 2026-09-23 02:28:34 +02:00
Merge remote-tracking branch 'upstream/main' into limit-repo-size
This commit is contained in:
+23
-29
@@ -14,67 +14,62 @@ import (
|
||||
|
||||
// XORMLogBridge a logger bridge from Logger to xorm
|
||||
type XORMLogBridge struct {
|
||||
showSQLint *int32
|
||||
logger log.Logger
|
||||
showSQL atomic.Bool
|
||||
logger log.Logger
|
||||
}
|
||||
|
||||
// NewXORMLogger inits a log bridge for xorm
|
||||
func NewXORMLogger(showSQL bool) xormlog.Logger {
|
||||
showSQLint := int32(0)
|
||||
if showSQL {
|
||||
showSQLint = 1
|
||||
}
|
||||
return &XORMLogBridge{
|
||||
showSQLint: &showSQLint,
|
||||
logger: log.GetLogger("xorm"),
|
||||
}
|
||||
l := &XORMLogBridge{logger: log.GetLogger("xorm")}
|
||||
l.showSQL.Store(showSQL)
|
||||
return l
|
||||
}
|
||||
|
||||
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{}) error {
|
||||
return l.logger.Log(skip+1, level, format, v...)
|
||||
func (l *XORMLogBridge) Log(skip int, level log.Level, format string, v ...interface{}) {
|
||||
l.logger.Log(skip+1, level, format, v...)
|
||||
}
|
||||
|
||||
// Debug show debug log
|
||||
func (l *XORMLogBridge) Debug(v ...interface{}) {
|
||||
_ = l.Log(stackLevel, log.DEBUG, fmt.Sprint(v...))
|
||||
l.Log(stackLevel, log.DEBUG, "%s", fmt.Sprint(v...))
|
||||
}
|
||||
|
||||
// Debugf show debug log
|
||||
func (l *XORMLogBridge) Debugf(format string, v ...interface{}) {
|
||||
_ = l.Log(stackLevel, log.DEBUG, format, v...)
|
||||
l.Log(stackLevel, log.DEBUG, format, v...)
|
||||
}
|
||||
|
||||
// Error show error log
|
||||
func (l *XORMLogBridge) Error(v ...interface{}) {
|
||||
_ = l.Log(stackLevel, log.ERROR, fmt.Sprint(v...))
|
||||
l.Log(stackLevel, log.ERROR, "%s", fmt.Sprint(v...))
|
||||
}
|
||||
|
||||
// Errorf show error log
|
||||
func (l *XORMLogBridge) Errorf(format string, v ...interface{}) {
|
||||
_ = l.Log(stackLevel, log.ERROR, format, v...)
|
||||
l.Log(stackLevel, log.ERROR, format, v...)
|
||||
}
|
||||
|
||||
// Info show information level log
|
||||
func (l *XORMLogBridge) Info(v ...interface{}) {
|
||||
_ = l.Log(stackLevel, log.INFO, fmt.Sprint(v...))
|
||||
l.Log(stackLevel, log.INFO, "%s", fmt.Sprint(v...))
|
||||
}
|
||||
|
||||
// Infof show information level log
|
||||
func (l *XORMLogBridge) Infof(format string, v ...interface{}) {
|
||||
_ = l.Log(stackLevel, log.INFO, format, v...)
|
||||
l.Log(stackLevel, log.INFO, format, v...)
|
||||
}
|
||||
|
||||
// Warn show warning log
|
||||
func (l *XORMLogBridge) Warn(v ...interface{}) {
|
||||
_ = l.Log(stackLevel, log.WARN, fmt.Sprint(v...))
|
||||
l.Log(stackLevel, log.WARN, "%s", fmt.Sprint(v...))
|
||||
}
|
||||
|
||||
// Warnf show warnning log
|
||||
func (l *XORMLogBridge) Warnf(format string, v ...interface{}) {
|
||||
_ = l.Log(stackLevel, log.WARN, format, v...)
|
||||
l.Log(stackLevel, log.WARN, format, v...)
|
||||
}
|
||||
|
||||
// Level get logger level
|
||||
@@ -86,10 +81,12 @@ func (l *XORMLogBridge) Level() xormlog.LogLevel {
|
||||
return xormlog.LOG_INFO
|
||||
case log.WARN:
|
||||
return xormlog.LOG_WARNING
|
||||
case log.ERROR, log.CRITICAL:
|
||||
case log.ERROR:
|
||||
return xormlog.LOG_ERR
|
||||
case log.NONE:
|
||||
return xormlog.LOG_OFF
|
||||
}
|
||||
return xormlog.LOG_OFF
|
||||
return xormlog.LOG_UNKNOWN
|
||||
}
|
||||
|
||||
// SetLevel set the logger level
|
||||
@@ -98,16 +95,13 @@ func (l *XORMLogBridge) SetLevel(lvl xormlog.LogLevel) {
|
||||
|
||||
// ShowSQL set if record SQL
|
||||
func (l *XORMLogBridge) ShowSQL(show ...bool) {
|
||||
showSQL := int32(1)
|
||||
if len(show) > 0 && !show[0] {
|
||||
showSQL = 0
|
||||
if len(show) == 0 {
|
||||
show = []bool{true}
|
||||
}
|
||||
atomic.StoreInt32(l.showSQLint, showSQL)
|
||||
l.showSQL.Store(show[0])
|
||||
}
|
||||
|
||||
// IsShowSQL if record SQL
|
||||
func (l *XORMLogBridge) IsShowSQL() bool {
|
||||
showSQL := atomic.LoadInt32(l.showSQLint)
|
||||
|
||||
return showSQL == 1
|
||||
return l.showSQL.Load()
|
||||
}
|
||||
|
||||
@@ -1048,7 +1048,7 @@ func (opts *FindCommentsOptions) ToConds() builder.Cond {
|
||||
}
|
||||
|
||||
// FindComments returns all comments according options
|
||||
func FindComments(ctx context.Context, opts *FindCommentsOptions) ([]*Comment, error) {
|
||||
func FindComments(ctx context.Context, opts *FindCommentsOptions) (CommentList, error) {
|
||||
comments := make([]*Comment, 0, 10)
|
||||
sess := db.GetEngine(ctx).Where(opts.ToConds())
|
||||
if opts.RepoID > 0 {
|
||||
|
||||
@@ -48,7 +48,7 @@ func fetchCodeCommentsByReview(ctx context.Context, issue *Issue, currentUser *u
|
||||
}
|
||||
|
||||
func findCodeComments(ctx context.Context, opts FindCommentsOptions, issue *Issue, currentUser *user_model.User, review *Review) ([]*Comment, error) {
|
||||
var comments []*Comment
|
||||
var comments CommentList
|
||||
if review == nil {
|
||||
review = &Review{ID: 0}
|
||||
}
|
||||
@@ -68,7 +68,7 @@ func findCodeComments(ctx context.Context, opts FindCommentsOptions, issue *Issu
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := CommentList(comments).LoadPosters(ctx); err != nil {
|
||||
if err := comments.LoadPosters(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
||||
@@ -124,7 +124,7 @@ type Issue struct {
|
||||
ClosedUnix timeutil.TimeStamp `xorm:"INDEX"`
|
||||
|
||||
Attachments []*repo_model.Attachment `xorm:"-"`
|
||||
Comments []*Comment `xorm:"-"`
|
||||
Comments CommentList `xorm:"-"`
|
||||
Reactions ReactionList `xorm:"-"`
|
||||
TotalTrackedTime int64 `xorm:"-"`
|
||||
Assignees []*user_model.User `xorm:"-"`
|
||||
@@ -353,7 +353,7 @@ func (issue *Issue) LoadAttributes(ctx context.Context) (err error) {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = CommentList(issue.Comments).loadAttributes(ctx); err != nil {
|
||||
if err = issue.Comments.loadAttributes(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
if issue.IsTimetrackerEnabled(ctx) {
|
||||
|
||||
@@ -141,7 +141,7 @@ func getIssueStatsChunk(opts *IssuesOptions, issueIDs []int64) (*IssueStats, err
|
||||
if opts.AssigneeID > 0 {
|
||||
applyAssigneeCondition(sess, opts.AssigneeID)
|
||||
} else if opts.AssigneeID == db.NoConditionID {
|
||||
sess.Where("id NOT IN (SELECT issue_id FROM issue_assignees)")
|
||||
sess.Where("issue.id NOT IN (SELECT issue_id FROM issue_assignees)")
|
||||
}
|
||||
|
||||
if opts.PosterID > 0 {
|
||||
|
||||
+11
-24
@@ -224,40 +224,27 @@ func DeletePullsByBaseRepoID(ctx context.Context, repoID int64) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// ColorFormat writes a colored string to identify this struct
|
||||
func (pr *PullRequest) ColorFormat(s fmt.State) {
|
||||
func (pr *PullRequest) String() string {
|
||||
if pr == nil {
|
||||
log.ColorFprintf(s, "PR[%d]%s#%d[%s...%s:%s]",
|
||||
log.NewColoredIDValue(0),
|
||||
log.NewColoredValue("<nil>/<nil>"),
|
||||
log.NewColoredIDValue(0),
|
||||
log.NewColoredValue("<nil>"),
|
||||
log.NewColoredValue("<nil>/<nil>"),
|
||||
log.NewColoredValue("<nil>"),
|
||||
)
|
||||
return
|
||||
return "<PullRequest nil>"
|
||||
}
|
||||
|
||||
log.ColorFprintf(s, "PR[%d]", log.NewColoredIDValue(pr.ID))
|
||||
s := new(strings.Builder)
|
||||
fmt.Fprintf(s, "<PullRequest [%d]", pr.ID)
|
||||
if pr.BaseRepo != nil {
|
||||
log.ColorFprintf(s, "%s#%d[%s...", log.NewColoredValue(pr.BaseRepo.FullName()),
|
||||
log.NewColoredIDValue(pr.Index), log.NewColoredValue(pr.BaseBranch))
|
||||
fmt.Fprintf(s, "%s#%d[%s...", pr.BaseRepo.FullName(), pr.Index, pr.BaseBranch)
|
||||
} else {
|
||||
log.ColorFprintf(s, "Repo[%d]#%d[%s...", log.NewColoredIDValue(pr.BaseRepoID),
|
||||
log.NewColoredIDValue(pr.Index), log.NewColoredValue(pr.BaseBranch))
|
||||
fmt.Fprintf(s, "Repo[%d]#%d[%s...", pr.BaseRepoID, pr.Index, pr.BaseBranch)
|
||||
}
|
||||
if pr.HeadRepoID == pr.BaseRepoID {
|
||||
log.ColorFprintf(s, "%s]", log.NewColoredValue(pr.HeadBranch))
|
||||
fmt.Fprintf(s, "%s]", pr.HeadBranch)
|
||||
} else if pr.HeadRepo != nil {
|
||||
log.ColorFprintf(s, "%s:%s]", log.NewColoredValue(pr.HeadRepo.FullName()), log.NewColoredValue(pr.HeadBranch))
|
||||
fmt.Fprintf(s, "%s:%s]", pr.HeadRepo.FullName(), pr.HeadBranch)
|
||||
} else {
|
||||
log.ColorFprintf(s, "Repo[%d]:%s]", log.NewColoredIDValue(pr.HeadRepoID), log.NewColoredValue(pr.HeadBranch))
|
||||
fmt.Fprintf(s, "Repo[%d]:%s]", pr.HeadRepoID, pr.HeadBranch)
|
||||
}
|
||||
}
|
||||
|
||||
// String represents the pr as a simple string
|
||||
func (pr *PullRequest) String() string {
|
||||
return log.ColorFormatAsString(pr)
|
||||
s.WriteByte('>')
|
||||
return s.String()
|
||||
}
|
||||
|
||||
// MustHeadUserName returns the HeadRepo's username if failed return blank
|
||||
|
||||
@@ -24,6 +24,8 @@ import (
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
// FIXME: this file shouldn't be in a normal package, it should only be compiled for tests
|
||||
|
||||
// PrepareTestEnv prepares the test environment and reset the database. The skip parameter should usually be 0.
|
||||
// Provide models to be sync'd with the database - in particular any models you expect fixtures to be loaded from.
|
||||
//
|
||||
@@ -110,7 +112,7 @@ func PrepareTestEnv(t *testing.T, skip int, syncModels ...interface{}) (*xorm.En
|
||||
}
|
||||
|
||||
func MainTest(m *testing.M) {
|
||||
log.Register("test", testlogger.NewTestLogger)
|
||||
log.RegisterEventWriter("test", testlogger.NewTestLoggerWriter)
|
||||
|
||||
giteaRoot := base.SetupGiteaRoot()
|
||||
if giteaRoot == "" {
|
||||
@@ -154,7 +156,7 @@ func MainTest(m *testing.M) {
|
||||
os.Exit(1)
|
||||
}
|
||||
setting.LoadDBSetting()
|
||||
setting.InitLogs(true)
|
||||
setting.InitLoggersForTest()
|
||||
|
||||
exitStatus := m.Run()
|
||||
|
||||
|
||||
@@ -94,21 +94,11 @@ func init() {
|
||||
db.RegisterModel(new(TeamInvite))
|
||||
}
|
||||
|
||||
// ColorFormat provides a basic color format for a Team
|
||||
func (t *Team) ColorFormat(s fmt.State) {
|
||||
func (t *Team) LogString() string {
|
||||
if t == nil {
|
||||
log.ColorFprintf(s, "%d:%s (OrgID: %d) %-v",
|
||||
log.NewColoredIDValue(0),
|
||||
"<nil>",
|
||||
log.NewColoredIDValue(0),
|
||||
0)
|
||||
return
|
||||
return "<Team nil>"
|
||||
}
|
||||
log.ColorFprintf(s, "%d:%s (OrgID: %d) %-v",
|
||||
log.NewColoredIDValue(t.ID),
|
||||
t.Name,
|
||||
log.NewColoredIDValue(t.OrgID),
|
||||
t.AccessMode)
|
||||
return fmt.Sprintf("<Team %d:%s OrgID=%d AccessMode=%s>", t.ID, t.Name, t.OrgID, t.AccessMode.LogString())
|
||||
}
|
||||
|
||||
// LoadUnits load a list of available units for a team
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
// Copyright 2023 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package cran
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/models/packages"
|
||||
cran_module "code.gitea.io/gitea/modules/packages/cran"
|
||||
|
||||
"xorm.io/builder"
|
||||
)
|
||||
|
||||
type SearchOptions struct {
|
||||
OwnerID int64
|
||||
FileType string
|
||||
Platform string
|
||||
RVersion string
|
||||
Filename string
|
||||
}
|
||||
|
||||
func (opts *SearchOptions) toConds() builder.Cond {
|
||||
var cond builder.Cond = builder.Eq{
|
||||
"package.type": packages.TypeCran,
|
||||
"package.owner_id": opts.OwnerID,
|
||||
"package_version.is_internal": false,
|
||||
}
|
||||
|
||||
if opts.Filename != "" {
|
||||
cond = cond.And(builder.Eq{"package_file.lower_name": strings.ToLower(opts.Filename)})
|
||||
}
|
||||
|
||||
var propsCond builder.Cond = builder.Eq{
|
||||
"package_property.ref_type": packages.PropertyTypeFile,
|
||||
}
|
||||
propsCond = propsCond.And(builder.Expr("package_property.ref_id = package_file.id"))
|
||||
|
||||
count := 1
|
||||
propsCondBlock := builder.Eq{"package_property.name": cran_module.PropertyType}.And(builder.Eq{"package_property.value": opts.FileType})
|
||||
|
||||
if opts.Platform != "" {
|
||||
count += 2
|
||||
propsCondBlock = propsCondBlock.
|
||||
Or(builder.Eq{"package_property.name": cran_module.PropertyPlatform}.And(builder.Eq{"package_property.value": opts.Platform})).
|
||||
Or(builder.Eq{"package_property.name": cran_module.PropertyRVersion}.And(builder.Eq{"package_property.value": opts.RVersion}))
|
||||
}
|
||||
|
||||
propsCond = propsCond.And(propsCondBlock)
|
||||
|
||||
cond = cond.And(builder.Eq{
|
||||
strconv.Itoa(count): builder.Select("COUNT(*)").Where(propsCond).From("package_property"),
|
||||
})
|
||||
|
||||
return cond
|
||||
}
|
||||
|
||||
func SearchLatestVersions(ctx context.Context, opts *SearchOptions) ([]*packages.PackageVersion, error) {
|
||||
sess := db.GetEngine(ctx).
|
||||
Table("package_version").
|
||||
Select("package_version.*").
|
||||
Join("LEFT", "package_version pv2", builder.Expr("package_version.package_id = pv2.package_id AND pv2.is_internal = ? AND (package_version.created_unix < pv2.created_unix OR (package_version.created_unix = pv2.created_unix AND package_version.id < pv2.id))", false)).
|
||||
Join("INNER", "package", "package.id = package_version.package_id").
|
||||
Join("INNER", "package_file", "package_file.version_id = package_version.id").
|
||||
Where(opts.toConds().And(builder.Expr("pv2.id IS NULL"))).
|
||||
Asc("package.name")
|
||||
|
||||
pvs := make([]*packages.PackageVersion, 0, 10)
|
||||
return pvs, sess.Find(&pvs)
|
||||
}
|
||||
|
||||
func SearchFile(ctx context.Context, opts *SearchOptions) (*packages.PackageFile, error) {
|
||||
sess := db.GetEngine(ctx).
|
||||
Table("package_version").
|
||||
Select("package_file.*").
|
||||
Join("INNER", "package", "package.id = package_version.package_id").
|
||||
Join("INNER", "package_file", "package_file.version_id = package_version.id").
|
||||
Where(opts.toConds())
|
||||
|
||||
pf := &packages.PackageFile{}
|
||||
if has, err := sess.Get(pf); err != nil {
|
||||
return nil, err
|
||||
} else if !has {
|
||||
return nil, packages.ErrPackageFileNotExist
|
||||
}
|
||||
return pf, nil
|
||||
}
|
||||
@@ -19,6 +19,7 @@ import (
|
||||
"code.gitea.io/gitea/modules/packages/conan"
|
||||
"code.gitea.io/gitea/modules/packages/conda"
|
||||
"code.gitea.io/gitea/modules/packages/container"
|
||||
"code.gitea.io/gitea/modules/packages/cran"
|
||||
"code.gitea.io/gitea/modules/packages/debian"
|
||||
"code.gitea.io/gitea/modules/packages/helm"
|
||||
"code.gitea.io/gitea/modules/packages/maven"
|
||||
@@ -151,6 +152,8 @@ func GetPackageDescriptor(ctx context.Context, pv *PackageVersion) (*PackageDesc
|
||||
metadata = &conda.VersionMetadata{}
|
||||
case TypeContainer:
|
||||
metadata = &container.Metadata{}
|
||||
case TypeCran:
|
||||
metadata = &cran.Metadata{}
|
||||
case TypeDebian:
|
||||
metadata = &debian.Metadata{}
|
||||
case TypeGeneric:
|
||||
|
||||
@@ -37,6 +37,7 @@ const (
|
||||
TypeConan Type = "conan"
|
||||
TypeConda Type = "conda"
|
||||
TypeContainer Type = "container"
|
||||
TypeCran Type = "cran"
|
||||
TypeDebian Type = "debian"
|
||||
TypeGeneric Type = "generic"
|
||||
TypeGo Type = "go"
|
||||
@@ -60,6 +61,7 @@ var TypeList = []Type{
|
||||
TypeConan,
|
||||
TypeConda,
|
||||
TypeContainer,
|
||||
TypeCran,
|
||||
TypeDebian,
|
||||
TypeGeneric,
|
||||
TypeGo,
|
||||
@@ -92,6 +94,8 @@ func (pt Type) Name() string {
|
||||
return "Conda"
|
||||
case TypeContainer:
|
||||
return "Container"
|
||||
case TypeCran:
|
||||
return "CRAN"
|
||||
case TypeDebian:
|
||||
return "Debian"
|
||||
case TypeGeneric:
|
||||
@@ -139,6 +143,8 @@ func (pt Type) SVGName() string {
|
||||
return "gitea-conda"
|
||||
case TypeContainer:
|
||||
return "octicon-container"
|
||||
case TypeCran:
|
||||
return "gitea-cran"
|
||||
case TypeDebian:
|
||||
return "gitea-debian"
|
||||
case TypeGeneric:
|
||||
|
||||
@@ -102,45 +102,28 @@ func (p *Permission) CanWriteIssuesOrPulls(isPull bool) bool {
|
||||
return p.CanWrite(unit.TypeIssues)
|
||||
}
|
||||
|
||||
// ColorFormat writes a colored string for these Permissions
|
||||
func (p *Permission) ColorFormat(s fmt.State) {
|
||||
noColor := log.ColorBytes(log.Reset)
|
||||
func (p *Permission) LogString() string {
|
||||
format := "<Permission AccessMode=%s, %d Units, %d UnitsMode(s): [ "
|
||||
args := []any{p.AccessMode.String(), len(p.Units), len(p.UnitsMode)}
|
||||
|
||||
format := "perm_model.AccessMode: %-v, %d Units, %d UnitsMode(s): [ "
|
||||
args := []interface{}{
|
||||
p.AccessMode,
|
||||
log.NewColoredValueBytes(len(p.Units), &noColor),
|
||||
log.NewColoredValueBytes(len(p.UnitsMode), &noColor),
|
||||
}
|
||||
if s.Flag('+') {
|
||||
for i, unit := range p.Units {
|
||||
config := ""
|
||||
if unit.Config != nil {
|
||||
configBytes, err := unit.Config.ToDB()
|
||||
config = string(configBytes)
|
||||
if err != nil {
|
||||
config = err.Error()
|
||||
}
|
||||
for i, unit := range p.Units {
|
||||
config := ""
|
||||
if unit.Config != nil {
|
||||
configBytes, err := unit.Config.ToDB()
|
||||
config = string(configBytes)
|
||||
if err != nil {
|
||||
config = err.Error()
|
||||
}
|
||||
format += "\nUnits[%d]: ID: %d RepoID: %d Type: %-v Config: %s"
|
||||
args = append(args,
|
||||
log.NewColoredValueBytes(i, &noColor),
|
||||
log.NewColoredIDValue(unit.ID),
|
||||
log.NewColoredIDValue(unit.RepoID),
|
||||
unit.Type,
|
||||
config)
|
||||
}
|
||||
for key, value := range p.UnitsMode {
|
||||
format += "\nUnitMode[%-v]: %-v"
|
||||
args = append(args,
|
||||
key,
|
||||
value)
|
||||
}
|
||||
} else {
|
||||
format += "..."
|
||||
format += "\nUnits[%d]: ID: %d RepoID: %d Type: %s Config: %s"
|
||||
args = append(args, i, unit.ID, unit.RepoID, unit.Type.LogString(), config)
|
||||
}
|
||||
format += " ]"
|
||||
log.ColorFprintf(s, format, args...)
|
||||
for key, value := range p.UnitsMode {
|
||||
format += "\nUnitMode[%-v]: %-v"
|
||||
args = append(args, key.LogString(), value.LogString())
|
||||
}
|
||||
format += " ]>"
|
||||
return fmt.Sprintf(format, args...)
|
||||
}
|
||||
|
||||
// GetUserRepoPermission returns the user permissions to the repository
|
||||
|
||||
@@ -5,8 +5,6 @@ package perm
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
)
|
||||
|
||||
// AccessMode specifies the users access mode
|
||||
@@ -40,11 +38,8 @@ func (mode AccessMode) String() string {
|
||||
}
|
||||
}
|
||||
|
||||
// ColorFormat provides a ColorFormatted version of this AccessMode
|
||||
func (mode AccessMode) ColorFormat(s fmt.State) {
|
||||
log.ColorFprintf(s, "%d:%s",
|
||||
log.NewColoredIDValue(mode),
|
||||
mode)
|
||||
func (mode AccessMode) LogString() string {
|
||||
return fmt.Sprintf("<AccessMode:%d:%s>", mode, mode.String())
|
||||
}
|
||||
|
||||
// ParseAccessMode returns corresponding access mode to given permission string.
|
||||
|
||||
+11
-11
@@ -198,19 +198,11 @@ func (repo *Repository) SanitizedOriginalURL() string {
|
||||
return u.String()
|
||||
}
|
||||
|
||||
// ColorFormat returns a colored string to represent this repo
|
||||
func (repo *Repository) ColorFormat(s fmt.State) {
|
||||
func (repo *Repository) LogString() string {
|
||||
if repo == nil {
|
||||
log.ColorFprintf(s, "%d:%s/%s",
|
||||
log.NewColoredIDValue(0),
|
||||
"<nil>",
|
||||
"<nil>")
|
||||
return
|
||||
return "<Repository nil>"
|
||||
}
|
||||
log.ColorFprintf(s, "%d:%s/%s",
|
||||
log.NewColoredIDValue(repo.ID),
|
||||
repo.OwnerName,
|
||||
repo.Name)
|
||||
return fmt.Sprintf("<Repository %d:%s/%s>", repo.ID, repo.OwnerName, repo.Name)
|
||||
}
|
||||
|
||||
// IsBeingMigrated indicates that repository is being migrated
|
||||
@@ -881,3 +873,11 @@ func FixNullArchivedRepository(ctx context.Context) (int64, error) {
|
||||
IsArchived: false,
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateRepositoryOwnerName updates the owner name of all repositories owned by the user
|
||||
func UpdateRepositoryOwnerName(ctx context.Context, oldUserName, newUserName string) error {
|
||||
if _, err := db.GetEngine(ctx).Exec("UPDATE `repository` SET owner_name=? WHERE owner_name=?", newUserName, oldUserName); err != nil {
|
||||
return fmt.Errorf("change repo owner name: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
+25
-20
@@ -253,16 +253,7 @@ func AddTopic(repoID int64, topicName string) (*Topic, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
topicNames := make([]string, 0, 25)
|
||||
if err := sess.Select("name").Table("topic").
|
||||
Join("INNER", "repo_topic", "repo_topic.topic_id = topic.id").
|
||||
Where("repo_topic.repo_id = ?", repoID).Desc("topic.repo_count").Find(&topicNames); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if _, err := sess.ID(repoID).Cols("topics").Update(&Repository{
|
||||
Topics: topicNames,
|
||||
}); err != nil {
|
||||
if err = syncTopicsInRepository(sess, repoID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -281,6 +272,11 @@ func DeleteTopic(repoID int64, topicName string) (*Topic, error) {
|
||||
}
|
||||
|
||||
err = removeTopicFromRepo(db.DefaultContext, repoID, topic)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = syncTopicsInRepository(db.GetEngine(db.DefaultContext), repoID)
|
||||
|
||||
return topic, err
|
||||
}
|
||||
@@ -347,16 +343,7 @@ func SaveTopics(repoID int64, topicNames ...string) error {
|
||||
}
|
||||
}
|
||||
|
||||
topicNames = make([]string, 0, 25)
|
||||
if err := sess.Table("topic").Cols("name").
|
||||
Join("INNER", "repo_topic", "repo_topic.topic_id = topic.id").
|
||||
Where("repo_topic.repo_id = ?", repoID).Desc("topic.repo_count").Find(&topicNames); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := sess.ID(repoID).Cols("topics").Update(&Repository{
|
||||
Topics: topicNames,
|
||||
}); err != nil {
|
||||
if err := syncTopicsInRepository(sess, repoID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -370,5 +357,23 @@ func GenerateTopics(ctx context.Context, templateRepo, generateRepo *Repository)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return syncTopicsInRepository(db.GetEngine(ctx), generateRepo.ID)
|
||||
}
|
||||
|
||||
// syncTopicsInRepository makes sure topics in the topics table are copied into the topics field of the repository
|
||||
func syncTopicsInRepository(sess db.Engine, repoID int64) error {
|
||||
topicNames := make([]string, 0, 25)
|
||||
if err := sess.Table("topic").Cols("name").
|
||||
Join("INNER", "repo_topic", "repo_topic.topic_id = topic.id").
|
||||
Where("repo_topic.repo_id = ?", repoID).Desc("topic.repo_count").Find(&topicNames); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := sess.ID(repoID).Cols("topics").Update(&Repository{
|
||||
Topics: topicNames,
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
+2
-5
@@ -62,11 +62,8 @@ func (u Type) String() string {
|
||||
return fmt.Sprintf("Unknown Type %d", u)
|
||||
}
|
||||
|
||||
// ColorFormat provides a ColorFormatted version of this Type
|
||||
func (u Type) ColorFormat(s fmt.State) {
|
||||
log.ColorFprintf(s, "%d:%s",
|
||||
log.NewColoredIDValue(u),
|
||||
u)
|
||||
func (u Type) LogString() string {
|
||||
return fmt.Sprintf("<UnitType:%d:%s>", u, u.String())
|
||||
}
|
||||
|
||||
var (
|
||||
|
||||
+31
-7
@@ -9,13 +9,6 @@ import (
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
)
|
||||
|
||||
// ____ ___
|
||||
// | | \______ ___________
|
||||
// | | / ___// __ \_ __ \
|
||||
// | | /\___ \\ ___/| | \/
|
||||
// |______//____ >\___ >__|
|
||||
// \/ \/
|
||||
|
||||
// ErrUserAlreadyExist represents a "user already exists" error.
|
||||
type ErrUserAlreadyExist struct {
|
||||
Name string
|
||||
@@ -99,3 +92,34 @@ func (err ErrUserInactive) Error() string {
|
||||
func (err ErrUserInactive) Unwrap() error {
|
||||
return util.ErrPermissionDenied
|
||||
}
|
||||
|
||||
// ErrUserIsNotLocal represents a "ErrUserIsNotLocal" kind of error.
|
||||
type ErrUserIsNotLocal struct {
|
||||
UID int64
|
||||
Name string
|
||||
}
|
||||
|
||||
func (err ErrUserIsNotLocal) Error() string {
|
||||
return fmt.Sprintf("user is not local type [uid: %d, name: %s]", err.UID, err.Name)
|
||||
}
|
||||
|
||||
// IsErrUserIsNotLocal
|
||||
func IsErrUserIsNotLocal(err error) bool {
|
||||
_, ok := err.(ErrUserIsNotLocal)
|
||||
return ok
|
||||
}
|
||||
|
||||
type ErrUsernameNotChanged struct {
|
||||
UID int64
|
||||
Name string
|
||||
}
|
||||
|
||||
func (err ErrUsernameNotChanged) Error() string {
|
||||
return fmt.Sprintf("username hasn't been changed[uid: %d, name: %s]", err.UID, err.Name)
|
||||
}
|
||||
|
||||
// IsErrUsernameNotChanged
|
||||
func IsErrUsernameNotChanged(err error) bool {
|
||||
_, ok := err.(ErrUsernameNotChanged)
|
||||
return ok
|
||||
}
|
||||
|
||||
+3
-54
@@ -9,7 +9,6 @@ import (
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -152,17 +151,11 @@ type SearchOrganizationsOptions struct {
|
||||
All bool
|
||||
}
|
||||
|
||||
// ColorFormat writes a colored string to identify this struct
|
||||
func (u *User) ColorFormat(s fmt.State) {
|
||||
func (u *User) LogString() string {
|
||||
if u == nil {
|
||||
log.ColorFprintf(s, "%d:%s",
|
||||
log.NewColoredIDValue(0),
|
||||
log.NewColoredValue("<nil>"))
|
||||
return
|
||||
return "<User nil>"
|
||||
}
|
||||
log.ColorFprintf(s, "%d:%s",
|
||||
log.NewColoredIDValue(u.ID),
|
||||
log.NewColoredValue(u.Name))
|
||||
return fmt.Sprintf("<User %d:%s>", u.ID, u.Name)
|
||||
}
|
||||
|
||||
// BeforeUpdate is invoked from XORM before updating this object.
|
||||
@@ -756,50 +749,6 @@ func VerifyUserActiveCode(code string) (user *User) {
|
||||
return nil
|
||||
}
|
||||
|
||||
// ChangeUserName changes all corresponding setting from old user name to new one.
|
||||
func ChangeUserName(ctx context.Context, u *User, newUserName string) (err error) {
|
||||
oldUserName := u.Name
|
||||
if err = IsUsableUsername(newUserName); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ctx, committer, err := db.TxContext(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer committer.Close()
|
||||
|
||||
isExist, err := IsUserExist(ctx, 0, newUserName)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if isExist {
|
||||
return ErrUserAlreadyExist{newUserName}
|
||||
}
|
||||
|
||||
if _, err = db.GetEngine(ctx).Exec("UPDATE `repository` SET owner_name=? WHERE owner_name=?", newUserName, oldUserName); err != nil {
|
||||
return fmt.Errorf("Change repo owner name: %w", err)
|
||||
}
|
||||
|
||||
// Do not fail if directory does not exist
|
||||
if err = util.Rename(UserPath(oldUserName), UserPath(newUserName)); err != nil && !os.IsNotExist(err) {
|
||||
return fmt.Errorf("Rename user directory: %w", err)
|
||||
}
|
||||
|
||||
if err = NewUserRedirect(ctx, u.ID, oldUserName, newUserName); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = committer.Commit(); err != nil {
|
||||
if err2 := util.Rename(UserPath(newUserName), UserPath(oldUserName)); err2 != nil && !os.IsNotExist(err2) {
|
||||
log.Critical("Unable to rollback directory change during failed username change from: %s to: %s. DB Error: %v. Filesystem Error: %v", oldUserName, newUserName, err, err2)
|
||||
return fmt.Errorf("failed to rollback directory change during failed username change from: %s to: %s. DB Error: %w. Filesystem Error: %v", oldUserName, newUserName, err, err2)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// checkDupEmail checks whether there are the same email with the user
|
||||
func checkDupEmail(ctx context.Context, u *User) error {
|
||||
u.Email = strings.ToLower(u.Email)
|
||||
|
||||
Reference in New Issue
Block a user