mirror of
				https://github.com/go-gitea/gitea
				synced 2025-11-04 05:18:25 +00:00 
			
		
		
		
	Merge branch 'main' into feature/bots
This commit is contained in:
		@@ -141,7 +141,7 @@ func CountNotifications(ctx context.Context, opts *FindNotificationOptions) (int
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// CreateRepoTransferNotification creates  notification for the user a repository was transferred to
 | 
					// CreateRepoTransferNotification creates  notification for the user a repository was transferred to
 | 
				
			||||||
func CreateRepoTransferNotification(ctx context.Context, doer, newOwner *user_model.User, repo *repo_model.Repository) error {
 | 
					func CreateRepoTransferNotification(ctx context.Context, doer, newOwner *user_model.User, repo *repo_model.Repository) error {
 | 
				
			||||||
	return db.AutoTx(ctx, func(ctx context.Context) error {
 | 
						return db.WithTx(ctx, func(ctx context.Context) error {
 | 
				
			||||||
		var notify []*Notification
 | 
							var notify []*Notification
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if newOwner.IsOrganization() {
 | 
							if newOwner.IsOrganization() {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -71,6 +71,14 @@ type Engined interface {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// GetEngine will get a db Engine from this context or return an Engine restricted to this context
 | 
					// GetEngine will get a db Engine from this context or return an Engine restricted to this context
 | 
				
			||||||
func GetEngine(ctx context.Context) Engine {
 | 
					func GetEngine(ctx context.Context) Engine {
 | 
				
			||||||
 | 
						if e := getEngine(ctx); e != nil {
 | 
				
			||||||
 | 
							return e
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return x.Context(ctx)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// getEngine will get a db Engine from this context or return nil
 | 
				
			||||||
 | 
					func getEngine(ctx context.Context) Engine {
 | 
				
			||||||
	if engined, ok := ctx.(Engined); ok {
 | 
						if engined, ok := ctx.(Engined); ok {
 | 
				
			||||||
		return engined.Engine()
 | 
							return engined.Engine()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -78,7 +86,7 @@ func GetEngine(ctx context.Context) Engine {
 | 
				
			|||||||
	if enginedInterface != nil {
 | 
						if enginedInterface != nil {
 | 
				
			||||||
		return enginedInterface.(Engined).Engine()
 | 
							return enginedInterface.(Engined).Engine()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return x.Context(ctx)
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Committer represents an interface to Commit or Close the Context
 | 
					// Committer represents an interface to Commit or Close the Context
 | 
				
			||||||
@@ -87,10 +95,22 @@ type Committer interface {
 | 
				
			|||||||
	Close() error
 | 
						Close() error
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// TxContext represents a transaction Context
 | 
					// halfCommitter is a wrapper of Committer.
 | 
				
			||||||
 | 
					// It can be closed early, but can't be committed early, it is useful for reusing a transaction.
 | 
				
			||||||
 | 
					type halfCommitter struct {
 | 
				
			||||||
 | 
						Committer
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (*halfCommitter) Commit() error {
 | 
				
			||||||
 | 
						// do nothing
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// TxContext represents a transaction Context,
 | 
				
			||||||
 | 
					// it will reuse the existing transaction in the parent context or create a new one.
 | 
				
			||||||
func TxContext(parentCtx context.Context) (*Context, Committer, error) {
 | 
					func TxContext(parentCtx context.Context) (*Context, Committer, error) {
 | 
				
			||||||
	if InTransaction(parentCtx) {
 | 
						if sess, ok := inTransaction(parentCtx); ok {
 | 
				
			||||||
		return nil, nil, ErrAlreadyInTransaction
 | 
							return newContext(parentCtx, sess, true), &halfCommitter{Committer: sess}, nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sess := x.NewSession()
 | 
						sess := x.NewSession()
 | 
				
			||||||
@@ -102,20 +122,11 @@ func TxContext(parentCtx context.Context) (*Context, Committer, error) {
 | 
				
			|||||||
	return newContext(DefaultContext, sess, true), sess, nil
 | 
						return newContext(DefaultContext, sess, true), sess, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// WithTx represents executing database operations on a transaction
 | 
					// WithTx represents executing database operations on a transaction, if the transaction exist,
 | 
				
			||||||
// This function will always open a new transaction, if a transaction exist in parentCtx return an error.
 | 
					 | 
				
			||||||
func WithTx(parentCtx context.Context, f func(ctx context.Context) error) error {
 | 
					 | 
				
			||||||
	if InTransaction(parentCtx) {
 | 
					 | 
				
			||||||
		return ErrAlreadyInTransaction
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return txWithNoCheck(parentCtx, f)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// AutoTx represents executing database operations on a transaction, if the transaction exist,
 | 
					 | 
				
			||||||
// this function will reuse it otherwise will create a new one and close it when finished.
 | 
					// this function will reuse it otherwise will create a new one and close it when finished.
 | 
				
			||||||
func AutoTx(parentCtx context.Context, f func(ctx context.Context) error) error {
 | 
					func WithTx(parentCtx context.Context, f func(ctx context.Context) error) error {
 | 
				
			||||||
	if InTransaction(parentCtx) {
 | 
						if sess, ok := inTransaction(parentCtx); ok {
 | 
				
			||||||
		return f(newContext(parentCtx, GetEngine(parentCtx), true))
 | 
							return f(newContext(parentCtx, sess, true))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return txWithNoCheck(parentCtx, f)
 | 
						return txWithNoCheck(parentCtx, f)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -202,25 +213,25 @@ func EstimateCount(ctx context.Context, bean interface{}) (int64, error) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// InTransaction returns true if the engine is in a transaction otherwise return false
 | 
					// InTransaction returns true if the engine is in a transaction otherwise return false
 | 
				
			||||||
func InTransaction(ctx context.Context) bool {
 | 
					func InTransaction(ctx context.Context) bool {
 | 
				
			||||||
	var e Engine
 | 
						_, ok := inTransaction(ctx)
 | 
				
			||||||
	if engined, ok := ctx.(Engined); ok {
 | 
						return ok
 | 
				
			||||||
		e = engined.Engine()
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		enginedInterface := ctx.Value(enginedContextKey)
 | 
					 | 
				
			||||||
		if enginedInterface != nil {
 | 
					 | 
				
			||||||
			e = enginedInterface.(Engined).Engine()
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func inTransaction(ctx context.Context) (*xorm.Session, bool) {
 | 
				
			||||||
 | 
						e := getEngine(ctx)
 | 
				
			||||||
	if e == nil {
 | 
						if e == nil {
 | 
				
			||||||
		return false
 | 
							return nil, false
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch t := e.(type) {
 | 
						switch t := e.(type) {
 | 
				
			||||||
	case *xorm.Engine:
 | 
						case *xorm.Engine:
 | 
				
			||||||
		return false
 | 
							return nil, false
 | 
				
			||||||
	case *xorm.Session:
 | 
						case *xorm.Session:
 | 
				
			||||||
		return t.IsInTx()
 | 
							if t.IsInTx() {
 | 
				
			||||||
 | 
								return t, true
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return nil, false
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		return false
 | 
							return nil, false
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -25,8 +25,62 @@ func TestInTransaction(t *testing.T) {
 | 
				
			|||||||
	assert.NoError(t, err)
 | 
						assert.NoError(t, err)
 | 
				
			||||||
	defer committer.Close()
 | 
						defer committer.Close()
 | 
				
			||||||
	assert.True(t, db.InTransaction(ctx))
 | 
						assert.True(t, db.InTransaction(ctx))
 | 
				
			||||||
	assert.Error(t, db.WithTx(ctx, func(ctx context.Context) error {
 | 
						assert.NoError(t, db.WithTx(ctx, func(ctx context.Context) error {
 | 
				
			||||||
		assert.True(t, db.InTransaction(ctx))
 | 
							assert.True(t, db.InTransaction(ctx))
 | 
				
			||||||
		return nil
 | 
							return nil
 | 
				
			||||||
	}))
 | 
						}))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestTxContext(t *testing.T) {
 | 
				
			||||||
 | 
						assert.NoError(t, unittest.PrepareTestDatabase())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						{ // create new transaction
 | 
				
			||||||
 | 
							ctx, committer, err := db.TxContext(db.DefaultContext)
 | 
				
			||||||
 | 
							assert.NoError(t, err)
 | 
				
			||||||
 | 
							assert.True(t, db.InTransaction(ctx))
 | 
				
			||||||
 | 
							assert.NoError(t, committer.Commit())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						{ // reuse the transaction created by TxContext and commit it
 | 
				
			||||||
 | 
							ctx, committer, err := db.TxContext(db.DefaultContext)
 | 
				
			||||||
 | 
							engine := db.GetEngine(ctx)
 | 
				
			||||||
 | 
							assert.NoError(t, err)
 | 
				
			||||||
 | 
							assert.True(t, db.InTransaction(ctx))
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								ctx, committer, err := db.TxContext(ctx)
 | 
				
			||||||
 | 
								assert.NoError(t, err)
 | 
				
			||||||
 | 
								assert.True(t, db.InTransaction(ctx))
 | 
				
			||||||
 | 
								assert.Equal(t, engine, db.GetEngine(ctx))
 | 
				
			||||||
 | 
								assert.NoError(t, committer.Commit())
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							assert.NoError(t, committer.Commit())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						{ // reuse the transaction created by TxContext and close it
 | 
				
			||||||
 | 
							ctx, committer, err := db.TxContext(db.DefaultContext)
 | 
				
			||||||
 | 
							engine := db.GetEngine(ctx)
 | 
				
			||||||
 | 
							assert.NoError(t, err)
 | 
				
			||||||
 | 
							assert.True(t, db.InTransaction(ctx))
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								ctx, committer, err := db.TxContext(ctx)
 | 
				
			||||||
 | 
								assert.NoError(t, err)
 | 
				
			||||||
 | 
								assert.True(t, db.InTransaction(ctx))
 | 
				
			||||||
 | 
								assert.Equal(t, engine, db.GetEngine(ctx))
 | 
				
			||||||
 | 
								assert.NoError(t, committer.Close())
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							assert.NoError(t, committer.Close())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						{ // reuse the transaction created by WithTx
 | 
				
			||||||
 | 
							assert.NoError(t, db.WithTx(db.DefaultContext, func(ctx context.Context) error {
 | 
				
			||||||
 | 
								assert.True(t, db.InTransaction(ctx))
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									ctx, committer, err := db.TxContext(ctx)
 | 
				
			||||||
 | 
									assert.NoError(t, err)
 | 
				
			||||||
 | 
									assert.True(t, db.InTransaction(ctx))
 | 
				
			||||||
 | 
									assert.NoError(t, committer.Commit())
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								return nil
 | 
				
			||||||
 | 
							}))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,14 +4,11 @@
 | 
				
			|||||||
package db
 | 
					package db
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"errors"
 | 
					 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"code.gitea.io/gitea/modules/util"
 | 
						"code.gitea.io/gitea/modules/util"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var ErrAlreadyInTransaction = errors.New("database connection has already been in a transaction")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// ErrCancelled represents an error due to context cancellation
 | 
					// ErrCancelled represents an error due to context cancellation
 | 
				
			||||||
type ErrCancelled struct {
 | 
					type ErrCancelled struct {
 | 
				
			||||||
	Message string
 | 
						Message string
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2365,7 +2365,7 @@ func CountOrphanedIssues(ctx context.Context) (int64, error) {
 | 
				
			|||||||
// DeleteOrphanedIssues delete issues without a repo
 | 
					// DeleteOrphanedIssues delete issues without a repo
 | 
				
			||||||
func DeleteOrphanedIssues(ctx context.Context) error {
 | 
					func DeleteOrphanedIssues(ctx context.Context) error {
 | 
				
			||||||
	var attachmentPaths []string
 | 
						var attachmentPaths []string
 | 
				
			||||||
	err := db.AutoTx(ctx, func(ctx context.Context) error {
 | 
						err := db.WithTx(ctx, func(ctx context.Context) error {
 | 
				
			||||||
		var ids []int64
 | 
							var ids []int64
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if err := db.GetEngine(ctx).Table("issue").Distinct("issue.repo_id").
 | 
							if err := db.GetEngine(ctx).Table("issue").Distinct("issue.repo_id").
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -300,7 +300,7 @@ func changeProjectStatus(ctx context.Context, p *Project, isClosed bool) error {
 | 
				
			|||||||
// DeleteProjectByID deletes a project from a repository. if it's not in a database
 | 
					// DeleteProjectByID deletes a project from a repository. if it's not in a database
 | 
				
			||||||
// transaction, it will start a new database transaction
 | 
					// transaction, it will start a new database transaction
 | 
				
			||||||
func DeleteProjectByID(ctx context.Context, id int64) error {
 | 
					func DeleteProjectByID(ctx context.Context, id int64) error {
 | 
				
			||||||
	return db.AutoTx(ctx, func(ctx context.Context) error {
 | 
						return db.WithTx(ctx, func(ctx context.Context) error {
 | 
				
			||||||
		p, err := GetProjectByID(ctx, id)
 | 
							p, err := GetProjectByID(ctx, id)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			if IsErrProjectNotExist(err) {
 | 
								if IsErrProjectNotExist(err) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -105,7 +105,7 @@ func ChangeCollaborationAccessMode(ctx context.Context, repo *Repository, uid in
 | 
				
			|||||||
		return nil
 | 
							return nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return db.AutoTx(ctx, func(ctx context.Context) error {
 | 
						return db.WithTx(ctx, func(ctx context.Context) error {
 | 
				
			||||||
		e := db.GetEngine(ctx)
 | 
							e := db.GetEngine(ctx)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		collaboration := &Collaboration{
 | 
							collaboration := &Collaboration{
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -155,7 +155,7 @@ func TestRepositoryReadyForTransfer(status repo_model.RepositoryStatus) error {
 | 
				
			|||||||
// CreatePendingRepositoryTransfer transfer a repo from one owner to a new one.
 | 
					// CreatePendingRepositoryTransfer transfer a repo from one owner to a new one.
 | 
				
			||||||
// it marks the repository transfer as "pending"
 | 
					// it marks the repository transfer as "pending"
 | 
				
			||||||
func CreatePendingRepositoryTransfer(ctx context.Context, doer, newOwner *user_model.User, repoID int64, teams []*organization.Team) error {
 | 
					func CreatePendingRepositoryTransfer(ctx context.Context, doer, newOwner *user_model.User, repoID int64, teams []*organization.Team) error {
 | 
				
			||||||
	return db.AutoTx(ctx, func(ctx context.Context) error {
 | 
						return db.WithTx(ctx, func(ctx context.Context) error {
 | 
				
			||||||
		repo, err := repo_model.GetRepositoryByID(ctx, repoID)
 | 
							repo, err := repo_model.GetRepositoryByID(ctx, repoID)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			return err
 | 
								return err
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,7 +12,7 @@ import (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	"code.gitea.io/gitea/models/db"
 | 
						"code.gitea.io/gitea/models/db"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/cache"
 | 
						"code.gitea.io/gitea/modules/cache"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/setting"
 | 
						setting_module "code.gitea.io/gitea/modules/setting"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/timeutil"
 | 
						"code.gitea.io/gitea/modules/timeutil"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"strk.kbt.io/projects/go/libravatar"
 | 
						"strk.kbt.io/projects/go/libravatar"
 | 
				
			||||||
@@ -88,7 +88,7 @@ func GetSettingNoCache(key string) (*Setting, error) {
 | 
				
			|||||||
	if len(v) == 0 {
 | 
						if len(v) == 0 {
 | 
				
			||||||
		return nil, ErrSettingIsNotExist{key}
 | 
							return nil, ErrSettingIsNotExist{key}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return v[key], nil
 | 
						return v[strings.ToLower(key)], nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetSetting returns the setting value via the key
 | 
					// GetSetting returns the setting value via the key
 | 
				
			||||||
@@ -131,7 +131,7 @@ func GetSettings(keys []string) (map[string]*Setting, error) {
 | 
				
			|||||||
type AllSettings map[string]*Setting
 | 
					type AllSettings map[string]*Setting
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (settings AllSettings) Get(key string) Setting {
 | 
					func (settings AllSettings) Get(key string) Setting {
 | 
				
			||||||
	if v, ok := settings[key]; ok {
 | 
						if v, ok := settings[strings.ToLower(key)]; ok {
 | 
				
			||||||
		return *v
 | 
							return *v
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return Setting{}
 | 
						return Setting{}
 | 
				
			||||||
@@ -184,14 +184,17 @@ func SetSettingNoVersion(key, value string) error {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// SetSetting updates a users' setting for a specific key
 | 
					// SetSetting updates a users' setting for a specific key
 | 
				
			||||||
func SetSetting(setting *Setting) error {
 | 
					func SetSetting(setting *Setting) error {
 | 
				
			||||||
	_, err := cache.GetString(genSettingCacheKey(setting.SettingKey), func() (string, error) {
 | 
						if err := upsertSettingValue(strings.ToLower(setting.SettingKey), setting.SettingValue, setting.Version); err != nil {
 | 
				
			||||||
		return setting.SettingValue, upsertSettingValue(strings.ToLower(setting.SettingKey), setting.SettingValue, setting.Version)
 | 
					 | 
				
			||||||
	})
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	setting.Version++
 | 
						setting.Version++
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cc := cache.GetCache()
 | 
				
			||||||
 | 
						if cc != nil {
 | 
				
			||||||
 | 
							return cc.Put(genSettingCacheKey(setting.SettingKey), setting.SettingValue, setting_module.CacheService.TTLSeconds())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -243,7 +246,7 @@ func Init() error {
 | 
				
			|||||||
	var disableGravatar bool
 | 
						var disableGravatar bool
 | 
				
			||||||
	disableGravatarSetting, err := GetSettingNoCache(KeyPictureDisableGravatar)
 | 
						disableGravatarSetting, err := GetSettingNoCache(KeyPictureDisableGravatar)
 | 
				
			||||||
	if IsErrSettingIsNotExist(err) {
 | 
						if IsErrSettingIsNotExist(err) {
 | 
				
			||||||
		disableGravatar = setting.GetDefaultDisableGravatar()
 | 
							disableGravatar = setting_module.GetDefaultDisableGravatar()
 | 
				
			||||||
		disableGravatarSetting = &Setting{SettingValue: strconv.FormatBool(disableGravatar)}
 | 
							disableGravatarSetting = &Setting{SettingValue: strconv.FormatBool(disableGravatar)}
 | 
				
			||||||
	} else if err != nil {
 | 
						} else if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
@@ -254,7 +257,7 @@ func Init() error {
 | 
				
			|||||||
	var enableFederatedAvatar bool
 | 
						var enableFederatedAvatar bool
 | 
				
			||||||
	enableFederatedAvatarSetting, err := GetSettingNoCache(KeyPictureEnableFederatedAvatar)
 | 
						enableFederatedAvatarSetting, err := GetSettingNoCache(KeyPictureEnableFederatedAvatar)
 | 
				
			||||||
	if IsErrSettingIsNotExist(err) {
 | 
						if IsErrSettingIsNotExist(err) {
 | 
				
			||||||
		enableFederatedAvatar = setting.GetDefaultEnableFederatedAvatar(disableGravatar)
 | 
							enableFederatedAvatar = setting_module.GetDefaultEnableFederatedAvatar(disableGravatar)
 | 
				
			||||||
		enableFederatedAvatarSetting = &Setting{SettingValue: strconv.FormatBool(enableFederatedAvatar)}
 | 
							enableFederatedAvatarSetting = &Setting{SettingValue: strconv.FormatBool(enableFederatedAvatar)}
 | 
				
			||||||
	} else if err != nil {
 | 
						} else if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
@@ -262,16 +265,16 @@ func Init() error {
 | 
				
			|||||||
		enableFederatedAvatar = disableGravatarSetting.GetValueBool()
 | 
							enableFederatedAvatar = disableGravatarSetting.GetValueBool()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if setting.OfflineMode {
 | 
						if setting_module.OfflineMode {
 | 
				
			||||||
		disableGravatar = true
 | 
							disableGravatar = true
 | 
				
			||||||
		enableFederatedAvatar = false
 | 
							enableFederatedAvatar = false
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if enableFederatedAvatar || !disableGravatar {
 | 
						if enableFederatedAvatar || !disableGravatar {
 | 
				
			||||||
		var err error
 | 
							var err error
 | 
				
			||||||
		GravatarSourceURL, err = url.Parse(setting.GravatarSource)
 | 
							GravatarSourceURL, err = url.Parse(setting_module.GravatarSource)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			return fmt.Errorf("Failed to parse Gravatar URL(%s): %w", setting.GravatarSource, err)
 | 
								return fmt.Errorf("Failed to parse Gravatar URL(%s): %w", setting_module.GravatarSource, err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -33,10 +33,14 @@ func TestSettings(t *testing.T) {
 | 
				
			|||||||
	assert.EqualValues(t, newSetting.SettingValue, settings[strings.ToLower(keyName)].SettingValue)
 | 
						assert.EqualValues(t, newSetting.SettingValue, settings[strings.ToLower(keyName)].SettingValue)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// updated setting
 | 
						// updated setting
 | 
				
			||||||
	updatedSetting := &system.Setting{SettingKey: keyName, SettingValue: "100", Version: newSetting.Version}
 | 
						updatedSetting := &system.Setting{SettingKey: keyName, SettingValue: "100", Version: settings[strings.ToLower(keyName)].Version}
 | 
				
			||||||
	err = system.SetSetting(updatedSetting)
 | 
						err = system.SetSetting(updatedSetting)
 | 
				
			||||||
	assert.NoError(t, err)
 | 
						assert.NoError(t, err)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						value, err := system.GetSetting(keyName)
 | 
				
			||||||
 | 
						assert.NoError(t, err)
 | 
				
			||||||
 | 
						assert.EqualValues(t, updatedSetting.SettingValue, value)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// get all settings
 | 
						// get all settings
 | 
				
			||||||
	settings, err = system.GetAllSettings()
 | 
						settings, err = system.GetAllSettings()
 | 
				
			||||||
	assert.NoError(t, err)
 | 
						assert.NoError(t, err)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -243,7 +243,7 @@ func (ns *notificationService) NotifyPullReviewRequest(ctx context.Context, doer
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (ns *notificationService) NotifyRepoPendingTransfer(ctx context.Context, doer, newOwner *user_model.User, repo *repo_model.Repository) {
 | 
					func (ns *notificationService) NotifyRepoPendingTransfer(ctx context.Context, doer, newOwner *user_model.User, repo *repo_model.Repository) {
 | 
				
			||||||
	err := db.AutoTx(ctx, func(ctx context.Context) error {
 | 
						err := db.WithTx(ctx, func(ctx context.Context) error {
 | 
				
			||||||
		return activities_model.CreateRepoTransferNotification(ctx, doer, newOwner, repo)
 | 
							return activities_model.CreateRepoTransferNotification(ctx, doer, newOwner, repo)
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,7 +14,7 @@ import (
 | 
				
			|||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func AddCollaborator(ctx context.Context, repo *repo_model.Repository, u *user_model.User) error {
 | 
					func AddCollaborator(ctx context.Context, repo *repo_model.Repository, u *user_model.User) error {
 | 
				
			||||||
	return db.AutoTx(ctx, func(ctx context.Context) error {
 | 
						return db.WithTx(ctx, func(ctx context.Context) error {
 | 
				
			||||||
		collaboration := &repo_model.Collaboration{
 | 
							collaboration := &repo_model.Collaboration{
 | 
				
			||||||
			RepoID: repo.ID,
 | 
								RepoID: repo.ID,
 | 
				
			||||||
			UserID: u.ID,
 | 
								UserID: u.ID,
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										24
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										24
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							@@ -5916,9 +5916,9 @@
 | 
				
			|||||||
      "dev": true
 | 
					      "dev": true
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "node_modules/json5": {
 | 
					    "node_modules/json5": {
 | 
				
			||||||
      "version": "2.2.2",
 | 
					      "version": "2.2.3",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.2.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
 | 
				
			||||||
      "integrity": "sha512-46Tk9JiOL2z7ytNQWFLpj99RZkVgeHf87yGQKsIkaPz1qSH9UczKH1rO7K3wgRselo0tYMUNfecYpm/p1vC7tQ==",
 | 
					      "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
 | 
				
			||||||
      "bin": {
 | 
					      "bin": {
 | 
				
			||||||
        "json5": "lib/cli.js"
 | 
					        "json5": "lib/cli.js"
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
@@ -8960,9 +8960,9 @@
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "node_modules/tsconfig-paths/node_modules/json5": {
 | 
					    "node_modules/tsconfig-paths/node_modules/json5": {
 | 
				
			||||||
      "version": "1.0.1",
 | 
					      "version": "1.0.2",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
 | 
				
			||||||
      "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
 | 
					      "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
 | 
				
			||||||
      "dev": true,
 | 
					      "dev": true,
 | 
				
			||||||
      "dependencies": {
 | 
					      "dependencies": {
 | 
				
			||||||
        "minimist": "^1.2.0"
 | 
					        "minimist": "^1.2.0"
 | 
				
			||||||
@@ -14248,9 +14248,9 @@
 | 
				
			|||||||
      "dev": true
 | 
					      "dev": true
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "json5": {
 | 
					    "json5": {
 | 
				
			||||||
      "version": "2.2.2",
 | 
					      "version": "2.2.3",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.2.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
 | 
				
			||||||
      "integrity": "sha512-46Tk9JiOL2z7ytNQWFLpj99RZkVgeHf87yGQKsIkaPz1qSH9UczKH1rO7K3wgRselo0tYMUNfecYpm/p1vC7tQ=="
 | 
					      "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg=="
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "jsonc-parser": {
 | 
					    "jsonc-parser": {
 | 
				
			||||||
      "version": "2.2.1",
 | 
					      "version": "2.2.1",
 | 
				
			||||||
@@ -16540,9 +16540,9 @@
 | 
				
			|||||||
      },
 | 
					      },
 | 
				
			||||||
      "dependencies": {
 | 
					      "dependencies": {
 | 
				
			||||||
        "json5": {
 | 
					        "json5": {
 | 
				
			||||||
          "version": "1.0.1",
 | 
					          "version": "1.0.2",
 | 
				
			||||||
          "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
 | 
					          "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
 | 
				
			||||||
          "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
 | 
					          "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
 | 
				
			||||||
          "dev": true,
 | 
					          "dev": true,
 | 
				
			||||||
          "requires": {
 | 
					          "requires": {
 | 
				
			||||||
            "minimist": "^1.2.0"
 | 
					            "minimist": "^1.2.0"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -123,7 +123,7 @@ func UpdateComment(ctx context.Context, c *issues_model.Comment, doer *user_mode
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// DeleteComment deletes the comment
 | 
					// DeleteComment deletes the comment
 | 
				
			||||||
func DeleteComment(ctx context.Context, doer *user_model.User, comment *issues_model.Comment) error {
 | 
					func DeleteComment(ctx context.Context, doer *user_model.User, comment *issues_model.Comment) error {
 | 
				
			||||||
	err := db.AutoTx(ctx, func(ctx context.Context) error {
 | 
						err := db.WithTx(ctx, func(ctx context.Context) error {
 | 
				
			||||||
		return issues_model.DeleteComment(ctx, comment)
 | 
							return issues_model.DeleteComment(ctx, comment)
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user