mirror of
https://github.com/go-gitea/gitea.git
synced 2026-08-11 15:58:30 +00:00
chore: enable forcetypeassert linter, fix issues (#38804)
Enable [`forcetypeassert`](https://github.com/gostaticanalysis/forcetypeassert) linter to prevent unchecked type assertions. ~650 issues fixed, most fixes were clean, some use `setting.PanicInDevOrTesting`. The only behaviour changes are where code would previously send a 500 error or panic, a 4xx error is now emitted. Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
@@ -20,6 +20,7 @@ import (
|
||||
"gitea.dev/modules/util"
|
||||
|
||||
"golang.org/x/crypto/ssh"
|
||||
"xorm.io/builder"
|
||||
)
|
||||
|
||||
// AuthorizedStringCommentPrefix is a magic tag
|
||||
@@ -162,8 +163,8 @@ func appendAuthorizedKeysToFile(keys ...*PublicKey) error {
|
||||
|
||||
// RegeneratePublicKeys regenerates the authorized_keys file
|
||||
func RegeneratePublicKeys(ctx context.Context, t io.Writer) error {
|
||||
if err := db.GetEngine(ctx).Where("type != ?", KeyTypePrincipal).Iterate(new(PublicKey), func(idx int, bean any) (err error) {
|
||||
return WriteAuthorizedStringForValidKey(bean.(*PublicKey), t)
|
||||
if err := db.Iterate(ctx, builder.Neq{"type": KeyTypePrincipal}, func(ctx context.Context, key *PublicKey) error {
|
||||
return WriteAuthorizedStringForValidKey(key, t)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
+16
-20
@@ -98,20 +98,12 @@ type RegisterableSource interface {
|
||||
|
||||
var registeredConfigs = map[Type]func() Config{}
|
||||
|
||||
// RegisterTypeConfig register a config for a provided type
|
||||
func RegisterTypeConfig(typ Type, exemplar Config) {
|
||||
if reflect.TypeOf(exemplar).Kind() == reflect.Pointer {
|
||||
// Pointer:
|
||||
registeredConfigs[typ] = func() Config {
|
||||
return reflect.New(reflect.ValueOf(exemplar).Elem().Type()).Interface().(Config)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Not a Pointer
|
||||
registeredConfigs[typ] = func() Config {
|
||||
return reflect.New(reflect.TypeOf(exemplar)).Elem().Interface().(Config)
|
||||
}
|
||||
// RegisterTypeConfig register a config for a provided type, the exemplar argument only serves type inference
|
||||
func RegisterTypeConfig[T interface {
|
||||
*E
|
||||
Config
|
||||
}, E any](typ Type, _ T) {
|
||||
registeredConfigs[typ] = func() Config { return T(new(E)) }
|
||||
}
|
||||
|
||||
// Source represents an external way for authorizing users.
|
||||
@@ -188,6 +180,16 @@ func (source *Source) IsSSPI() bool {
|
||||
return source.Type == SSPI
|
||||
}
|
||||
|
||||
// MustSourceCfg returns the source's config as T. The registry populates Cfg from the
|
||||
// source type, so a mismatch is a programming error the caller can't recover from.
|
||||
func MustSourceCfg[T Config](source *Source) T {
|
||||
cfg, ok := source.Cfg.(T)
|
||||
if !ok {
|
||||
panic(fmt.Errorf("auth source %q (id=%d, type=%s) has config %T, expected %s", source.Name, source.ID, source.Type, source.Cfg, reflect.TypeFor[T]()))
|
||||
}
|
||||
return cfg
|
||||
}
|
||||
|
||||
// HasTLS returns true of this source supports TLS.
|
||||
func (source *Source) HasTLS() bool {
|
||||
hasTLSer, ok := source.Cfg.(HasTLSer)
|
||||
@@ -371,12 +373,6 @@ type ErrSourceAlreadyExist struct {
|
||||
Name string
|
||||
}
|
||||
|
||||
// IsErrSourceAlreadyExist checks if an error is a ErrSourceAlreadyExist.
|
||||
func IsErrSourceAlreadyExist(err error) bool {
|
||||
_, ok := err.(ErrSourceAlreadyExist)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err ErrSourceAlreadyExist) Error() string {
|
||||
return fmt.Sprintf("login source already exists [name: %s]", err.Name)
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"gitea.dev/models/unittest"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestInTransaction(t *testing.T) {
|
||||
@@ -107,7 +108,8 @@ func TestContextSafety(t *testing.T) {
|
||||
_ = db.GetEngine(ctx).Iterate(&TestModel1{}, func(i int, bean any) error {
|
||||
// here: db.GetEngine(ctx) is always the unclosed "Iterate" *Session with autoResetStatement=false,
|
||||
// and the internal states (including "cond" and others) are always there and not be reset in this callback.
|
||||
m1 := bean.(*TestModel1)
|
||||
m1, ok := bean.(*TestModel1)
|
||||
require.True(t, ok)
|
||||
assert.EqualValues(t, i+1, m1.ID)
|
||||
|
||||
// here: XORM bug, it fails because the SQL becomes "WHERE id=-1", "WHERE id=-1 AND id=-2", "WHERE id=-1 AND id=-2 AND id=-3" ...
|
||||
|
||||
@@ -14,12 +14,6 @@ type ErrCancelled struct {
|
||||
Message string
|
||||
}
|
||||
|
||||
// IsErrCancelled checks if an error is a ErrCancelled.
|
||||
func IsErrCancelled(err error) bool {
|
||||
_, ok := err.(ErrCancelled)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err ErrCancelled) Error() string {
|
||||
return "Cancelled: " + err.Message
|
||||
}
|
||||
|
||||
@@ -239,6 +239,15 @@ func GetPackageDescriptorWithCache(ctx context.Context, pv *PackageVersion, c *c
|
||||
}, nil
|
||||
}
|
||||
|
||||
// DescriptorMetadata returns the descriptor's metadata, which getPackageDescriptor has created from the package type
|
||||
func DescriptorMetadata[T interface{ *E }, E any](pd *PackageDescriptor) T {
|
||||
metadata, ok := pd.Metadata.(T)
|
||||
if !ok {
|
||||
panic(fmt.Errorf("package %s of type %s has metadata type %T instead of %T", pd.Package.Name, pd.Package.Type, pd.Metadata, metadata))
|
||||
}
|
||||
return metadata
|
||||
}
|
||||
|
||||
// GetPackageFileDescriptor gets a package file descriptor for a package file
|
||||
func GetPackageFileDescriptor(ctx context.Context, pf *PackageFile) (*PackageFileDescriptor, error) {
|
||||
return getPackageFileDescriptor(ctx, pf, cache.NewEphemeralCache())
|
||||
|
||||
@@ -5,6 +5,7 @@ package repo
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"gitea.dev/models/db"
|
||||
"gitea.dev/models/perm"
|
||||
@@ -295,44 +296,56 @@ func (r *RepoUnit) Unit() unit.Unit {
|
||||
return unit.Units[r.Type]
|
||||
}
|
||||
|
||||
// unitConfig returns the unit's config, which BeforeSet has created from the unit type
|
||||
func unitConfig[T interface {
|
||||
*E
|
||||
convert.Conversion
|
||||
}, E any](r *RepoUnit) T {
|
||||
config, ok := r.Config.(T)
|
||||
if !ok {
|
||||
panic(fmt.Errorf("repo unit %d of type %s has config type %T instead of %T", r.ID, r.Type.LogString(), r.Config, config))
|
||||
}
|
||||
return config
|
||||
}
|
||||
|
||||
// CodeConfig returns config for unit.TypeCode
|
||||
func (r *RepoUnit) CodeConfig() *UnitConfig {
|
||||
return r.Config.(*UnitConfig)
|
||||
return unitConfig[*UnitConfig](r)
|
||||
}
|
||||
|
||||
// PullRequestsConfig returns config for unit.TypePullRequests
|
||||
func (r *RepoUnit) PullRequestsConfig() *PullRequestsConfig {
|
||||
return r.Config.(*PullRequestsConfig)
|
||||
return unitConfig[*PullRequestsConfig](r)
|
||||
}
|
||||
|
||||
// ReleasesConfig returns config for unit.TypeReleases
|
||||
func (r *RepoUnit) ReleasesConfig() *UnitConfig {
|
||||
return r.Config.(*UnitConfig)
|
||||
return unitConfig[*UnitConfig](r)
|
||||
}
|
||||
|
||||
// ExternalWikiConfig returns config for unit.TypeExternalWiki
|
||||
func (r *RepoUnit) ExternalWikiConfig() *ExternalWikiConfig {
|
||||
return r.Config.(*ExternalWikiConfig)
|
||||
return unitConfig[*ExternalWikiConfig](r)
|
||||
}
|
||||
|
||||
// IssuesConfig returns config for unit.TypeIssues
|
||||
func (r *RepoUnit) IssuesConfig() *IssuesConfig {
|
||||
return r.Config.(*IssuesConfig)
|
||||
return unitConfig[*IssuesConfig](r)
|
||||
}
|
||||
|
||||
// ExternalTrackerConfig returns config for unit.TypeExternalTracker
|
||||
func (r *RepoUnit) ExternalTrackerConfig() *ExternalTrackerConfig {
|
||||
return r.Config.(*ExternalTrackerConfig)
|
||||
return unitConfig[*ExternalTrackerConfig](r)
|
||||
}
|
||||
|
||||
// ActionsConfig returns config for unit.ActionsConfig
|
||||
func (r *RepoUnit) ActionsConfig() *ActionsConfig {
|
||||
return r.Config.(*ActionsConfig)
|
||||
return unitConfig[*ActionsConfig](r)
|
||||
}
|
||||
|
||||
// ProjectsConfig returns config for unit.ProjectsConfig
|
||||
func (r *RepoUnit) ProjectsConfig() *ProjectsConfig {
|
||||
return r.Config.(*ProjectsConfig)
|
||||
return unitConfig[*ProjectsConfig](r)
|
||||
}
|
||||
|
||||
func getUnitsByRepoID(ctx context.Context, repoID int64) (units []*RepoUnit, err error) {
|
||||
|
||||
@@ -34,7 +34,8 @@ type FixtureItem struct {
|
||||
|
||||
type fixturesLoaderInternal struct {
|
||||
xormEngine *xorm.Engine
|
||||
tableSyncMap sync.Map
|
||||
tableSyncMu sync.Mutex
|
||||
tableSynced map[string]bool
|
||||
db *sql.DB
|
||||
dbType schemas.DBType
|
||||
fixtures map[string]*FixtureItem
|
||||
@@ -152,32 +153,35 @@ func (f *fixturesLoaderInternal) Load() error {
|
||||
|
||||
ctx := context.WithValue(context.Background(), db.ContextKeyTestFixtures, true)
|
||||
|
||||
f.tableSyncMu.Lock()
|
||||
defer f.tableSyncMu.Unlock()
|
||||
|
||||
for _, fixture := range f.fixtures {
|
||||
synced, existing := f.tableSyncMap.Load(fixture.tableName)
|
||||
if synced == true || !existing {
|
||||
synced, existing := f.tableSynced[fixture.tableName]
|
||||
if synced || !existing {
|
||||
continue
|
||||
}
|
||||
if err := f.loadFixtures(tx, fixture); err != nil {
|
||||
return fmt.Errorf("failed to load fixtures from %s: %w", fixture.fileFullPath, err)
|
||||
}
|
||||
f.tableSyncMap.Store(fixture.tableName, true)
|
||||
f.tableSynced[fixture.tableName] = true
|
||||
}
|
||||
if err = tx.Commit(); err != nil {
|
||||
return err
|
||||
}
|
||||
f.tableSyncMap.Range(func(k, v any) bool {
|
||||
tableName, synced := k.(string), v.(bool)
|
||||
for tableName, synced := range f.tableSynced {
|
||||
if !synced && f.fixtures[tableName] == nil {
|
||||
_, _ = f.xormEngine.Context(ctx).Exec("DELETE FROM `" + tableName + "`")
|
||||
}
|
||||
f.tableSyncMap.Store(tableName, true)
|
||||
return true
|
||||
})
|
||||
f.tableSynced[tableName] = true
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *fixturesLoaderInternal) MarkTableChanged(tableName string) {
|
||||
f.tableSyncMap.Store(tableName, false)
|
||||
f.tableSyncMu.Lock()
|
||||
defer f.tableSyncMu.Unlock()
|
||||
f.tableSynced[tableName] = false
|
||||
}
|
||||
|
||||
func FixturesFileFullPaths(dir string, files []string) (map[string]*FixtureItem, error) {
|
||||
@@ -212,7 +216,7 @@ func NewFixturesLoader(x *xorm.Engine, opts FixturesOptions) (FixturesLoader, er
|
||||
return nil, fmt.Errorf("failed to get fixtures files: %w", err)
|
||||
}
|
||||
|
||||
f := &fixturesLoaderInternal{xormEngine: x, db: x.DB().DB, dbType: x.Dialect().URI().DBType, fixtures: fixtureItems}
|
||||
f := &fixturesLoaderInternal{xormEngine: x, db: x.DB().DB, dbType: x.Dialect().URI().DBType, fixtures: fixtureItems, tableSynced: map[string]bool{}}
|
||||
switch f.dbType {
|
||||
case schemas.SQLITE:
|
||||
f.quoteObject = func(s string) string { return fmt.Sprintf(`"%s"`, s) }
|
||||
@@ -233,7 +237,7 @@ func NewFixturesLoader(x *xorm.Engine, opts FixturesOptions) (FixturesLoader, er
|
||||
xormBeans, _ := db.NamesToBean()
|
||||
for _, bean := range xormBeans {
|
||||
beanTableName := x.TableName(bean)
|
||||
f.tableSyncMap.Store(trimTableNameQuotes(beanTableName), false)
|
||||
f.tableSynced[trimTableNameQuotes(beanTableName)] = false
|
||||
}
|
||||
return f, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user