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:
silverwind
2026-08-09 12:25:06 +02:00
committed by GitHub
parent fac8bf2eca
commit 76a81b24f9
248 changed files with 1110 additions and 995 deletions
+8 -3
View File
@@ -8,6 +8,7 @@ import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestErrorTranslatable(t *testing.T) {
@@ -16,8 +17,10 @@ func TestErrorTranslatable(t *testing.T) {
err = ErrorWrapTranslatable(io.EOF, "key", 1)
assert.ErrorIs(t, err, io.EOF)
assert.Equal(t, "EOF", err.Error())
assert.Equal(t, "key", err.(*errorTranslatableWrapper).trKey)
assert.Equal(t, []any{1}, err.(*errorTranslatableWrapper).trArgs)
wrapped, ok := err.(*errorTranslatableWrapper)
require.True(t, ok)
assert.Equal(t, "key", wrapped.trKey)
assert.Equal(t, []any{1}, wrapped.trArgs)
err = ErrorWrap(err, "new msg %d", 100)
assert.ErrorIs(t, err, io.EOF)
@@ -25,5 +28,7 @@ func TestErrorTranslatable(t *testing.T) {
errTr := ErrorAsTranslatable(err)
assert.Equal(t, "EOF", errTr.Error())
assert.Equal(t, "key", errTr.(*errorTranslatableWrapper).trKey)
wrapped, ok = errTr.(*errorTranslatableWrapper)
require.True(t, ok)
assert.Equal(t, "key", wrapped.trKey)
}
+4 -1
View File
@@ -13,6 +13,7 @@ import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestKeygen(t *testing.T) {
@@ -55,6 +56,8 @@ func TestSignUsingKeys(t *testing.T) {
assert.NoError(t, err)
// Verify
err = rsa.VerifyPKCS1v15(pubParsed.(*rsa.PublicKey), crypto.SHA256, d, sig)
pubKey, ok := pubParsed.(*rsa.PublicKey)
require.True(t, ok)
err = rsa.VerifyPKCS1v15(pubKey, crypto.SHA256, d, sig)
assert.NoError(t, err)
}
-13
View File
@@ -1,13 +0,0 @@
// Copyright 2025 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package util
func GetMapValueOrDefault[T any](m map[string]any, key string, defaultValue T) T {
if value, ok := m[key]; ok {
if v, ok := value.(T); ok {
return v
}
}
return defaultValue
}
-26
View File
@@ -1,26 +0,0 @@
// Copyright 2025 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package util
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestGetMapValueOrDefault(t *testing.T) {
testMap := map[string]any{
"key1": "value1",
"key2": 42,
"key3": nil,
}
assert.Equal(t, "value1", GetMapValueOrDefault(testMap, "key1", "default"))
assert.Equal(t, 42, GetMapValueOrDefault(testMap, "key2", 0))
assert.Equal(t, "default", GetMapValueOrDefault(testMap, "key4", "default"))
assert.Equal(t, 100, GetMapValueOrDefault(testMap, "key5", 100))
assert.Equal(t, "default", GetMapValueOrDefault(testMap, "key3", "default"))
}
+7 -14
View File
@@ -3,31 +3,24 @@
package util
import "reflect"
// PaginateSlice cut a slice as per pagination options
// if page = 0 it do not paginate
func PaginateSlice(list any, page, pageSize int) any {
func PaginateSlice[S ~[]E, E any](list S, page, pageSize int) S {
if page <= 0 || pageSize <= 0 {
return list
}
if reflect.TypeOf(list).Kind() != reflect.Slice {
return list
}
listValue := reflect.ValueOf(list)
page--
if page*pageSize >= listValue.Len() {
return listValue.Slice(listValue.Len(), listValue.Len()).Interface()
if page*pageSize >= len(list) {
return list[len(list):]
}
listValue = listValue.Slice(page*pageSize, listValue.Len())
list = list[page*pageSize:]
if listValue.Len() > pageSize {
return listValue.Slice(0, pageSize).Interface()
if len(list) > pageSize {
return list[:pageSize]
}
return listValue.Interface()
return list
}
+7 -14
View File
@@ -11,24 +11,19 @@ import (
func TestPaginateSlice(t *testing.T) {
stringSlice := []string{"a", "b", "c", "d", "e"}
result, ok := PaginateSlice(stringSlice, 1, 2).([]string)
assert.True(t, ok)
result := PaginateSlice(stringSlice, 1, 2)
assert.Equal(t, []string{"a", "b"}, result)
result, ok = PaginateSlice(stringSlice, 100, 2).([]string)
assert.True(t, ok)
result = PaginateSlice(stringSlice, 100, 2)
assert.Equal(t, []string{}, result)
result, ok = PaginateSlice(stringSlice, 3, 2).([]string)
assert.True(t, ok)
result = PaginateSlice(stringSlice, 3, 2)
assert.Equal(t, []string{"e"}, result)
result, ok = PaginateSlice(stringSlice, 1, 0).([]string)
assert.True(t, ok)
result = PaginateSlice(stringSlice, 1, 0)
assert.Equal(t, []string{"a", "b", "c", "d", "e"}, result)
result, ok = PaginateSlice(stringSlice, 1, -1).([]string)
assert.True(t, ok)
result = PaginateSlice(stringSlice, 1, -1)
assert.Equal(t, []string{"a", "b", "c", "d", "e"}, result)
type Test struct {
@@ -36,11 +31,9 @@ func TestPaginateSlice(t *testing.T) {
}
testVar := []*Test{{Val: 2}, {Val: 3}, {Val: 4}}
testVar, ok = PaginateSlice(testVar, 1, 50).([]*Test)
assert.True(t, ok)
testVar = PaginateSlice(testVar, 1, 50)
assert.Equal(t, []*Test{{Val: 2}, {Val: 3}, {Val: 4}}, testVar)
testVar, ok = PaginateSlice(testVar, 2, 2).([]*Test)
assert.True(t, ok)
testVar = PaginateSlice(testVar, 2, 2)
assert.Equal(t, []*Test{{Val: 4}}, testVar)
}
+5 -4
View File
@@ -107,7 +107,7 @@ func FastCryptoRandomBytes(length int) []byte {
// ChaCha8 is about 20x times faster than system's crypto/rand.
// It is suitable for UUIDs, session IDs, etc
pool := chaCha8RandPool()
chaCha8Rand := pool.Get().(*rand2.ChaCha8)
chaCha8Rand := pool.Get().(*rand2.ChaCha8) //nolint:forcetypeassert // the pool's New only ever makes *rand2.ChaCha8
defer pool.Put(chaCha8Rand)
buf := make([]byte, length)
_, _ = chaCha8Rand.Read(buf)
@@ -270,15 +270,16 @@ func OptionalArg[T any](optArg []T, defaultValue ...T) (ret T) {
}
type EnumConst[T comparable] interface {
comparable
EnumValues() []T
}
// EnumValue returns the value if it's in the enum const's values,
// otherwise returns the first item of enums as default value.
func EnumValue[T comparable](val EnumConst[T]) (ret T, valid bool) {
func EnumValue[T EnumConst[T]](val T) (ret T, valid bool) {
enums := val.EnumValues()
if slices.Contains(enums, val.(T)) {
return val.(T), true
if slices.Contains(enums, val) {
return val, true
}
return enums[0], false
}