Move ParseBool to optional (#33979)

(cherry picked from commit 25b6f388651c893ecafce918f27bef7e4ae9a967)
This commit is contained in:
Lunny Xiao 2025-03-23 20:53:30 -07:00 committed by Gusted
parent 9018e5bc19
commit f68d49cb9e
No known key found for this signature in database
GPG key ID: FD821B732837125F
6 changed files with 31 additions and 33 deletions

View file

@ -3,6 +3,8 @@
package optional package optional
import "strconv"
type Option[T any] []T type Option[T any] []T
func None[T any]() Option[T] { func None[T any]() Option[T] {
@ -43,3 +45,12 @@ func (o Option[T]) ValueOrDefault(v T) T {
} }
return v return v
} }
// ParseBool get the corresponding optional.Option[bool] of a string using strconv.ParseBool
func ParseBool(s string) Option[bool] {
v, e := strconv.ParseBool(s)
if e != nil {
return None[bool]()
}
return Some(v)
}

View file

@ -57,3 +57,16 @@ func TestOption(t *testing.T) {
assert.True(t, opt3.Has()) assert.True(t, opt3.Has())
assert.Equal(t, int(1), opt3.Value()) assert.Equal(t, int(1), opt3.Value())
} }
func Test_ParseBool(t *testing.T) {
assert.Equal(t, optional.None[bool](), optional.ParseBool(""))
assert.Equal(t, optional.None[bool](), optional.ParseBool("x"))
assert.Equal(t, optional.Some(false), optional.ParseBool("0"))
assert.Equal(t, optional.Some(false), optional.ParseBool("f"))
assert.Equal(t, optional.Some(false), optional.ParseBool("False"))
assert.Equal(t, optional.Some(true), optional.ParseBool("1"))
assert.Equal(t, optional.Some(true), optional.ParseBool("t"))
assert.Equal(t, optional.Some(true), optional.ParseBool("True"))
}

View file

@ -12,8 +12,8 @@ import (
"time" "time"
"forgejo.org/modules/log" "forgejo.org/modules/log"
"forgejo.org/modules/optional"
"forgejo.org/modules/user" "forgejo.org/modules/user"
"forgejo.org/modules/util"
) )
var ForgejoVersion = "1.0.0" var ForgejoVersion = "1.0.0"
@ -162,7 +162,7 @@ func loadRunModeFrom(rootCfg ConfigProvider) {
// The following is a purposefully undocumented option. Please do not run Forgejo as root. It will only cause future headaches. // The following is a purposefully undocumented option. Please do not run Forgejo as root. It will only cause future headaches.
// Please don't use root as a bandaid to "fix" something that is broken, instead the broken thing should instead be fixed properly. // Please don't use root as a bandaid to "fix" something that is broken, instead the broken thing should instead be fixed properly.
unsafeAllowRunAsRoot := ConfigSectionKeyBool(rootSec, "I_AM_BEING_UNSAFE_RUNNING_AS_ROOT") unsafeAllowRunAsRoot := ConfigSectionKeyBool(rootSec, "I_AM_BEING_UNSAFE_RUNNING_AS_ROOT")
unsafeAllowRunAsRoot = unsafeAllowRunAsRoot || util.OptionalBoolParse(os.Getenv("GITEA_I_AM_BEING_UNSAFE_RUNNING_AS_ROOT")).Value() unsafeAllowRunAsRoot = unsafeAllowRunAsRoot || optional.ParseBool(os.Getenv("GITEA_I_AM_BEING_UNSAFE_RUNNING_AS_ROOT")).Value()
RunMode = os.Getenv("GITEA_RUN_MODE") RunMode = os.Getenv("GITEA_RUN_MODE")
if RunMode == "" { if RunMode == "" {
RunMode = rootSec.Key("RUN_MODE").MustString("prod") RunMode = rootSec.Key("RUN_MODE").MustString("prod")

View file

@ -14,22 +14,11 @@ import (
"strconv" "strconv"
"strings" "strings"
"forgejo.org/modules/optional"
"golang.org/x/crypto/ssh" "golang.org/x/crypto/ssh"
"golang.org/x/text/cases" "golang.org/x/text/cases"
"golang.org/x/text/language" "golang.org/x/text/language"
) )
// OptionalBoolParse get the corresponding optional.Option[bool] of a string using strconv.ParseBool
func OptionalBoolParse(s string) optional.Option[bool] {
v, e := strconv.ParseBool(s)
if e != nil {
return optional.None[bool]()
}
return optional.Some(v)
}
// IsEmptyString checks if the provided string is empty // IsEmptyString checks if the provided string is empty
func IsEmptyString(s string) bool { func IsEmptyString(s string) bool {
return len(strings.TrimSpace(s)) == 0 return len(strings.TrimSpace(s)) == 0

View file

@ -11,7 +11,6 @@ import (
"strings" "strings"
"testing" "testing"
"forgejo.org/modules/optional"
"forgejo.org/modules/test" "forgejo.org/modules/test"
"forgejo.org/modules/util" "forgejo.org/modules/util"
@ -181,19 +180,6 @@ func Test_RandomBytes(t *testing.T) {
assert.NotEqual(t, bytes3, bytes4) assert.NotEqual(t, bytes3, bytes4)
} }
func TestOptionalBoolParse(t *testing.T) {
assert.Equal(t, optional.None[bool](), util.OptionalBoolParse(""))
assert.Equal(t, optional.None[bool](), util.OptionalBoolParse("x"))
assert.Equal(t, optional.Some(false), util.OptionalBoolParse("0"))
assert.Equal(t, optional.Some(false), util.OptionalBoolParse("f"))
assert.Equal(t, optional.Some(false), util.OptionalBoolParse("False"))
assert.Equal(t, optional.Some(true), util.OptionalBoolParse("1"))
assert.Equal(t, optional.Some(true), util.OptionalBoolParse("t"))
assert.Equal(t, optional.Some(true), util.OptionalBoolParse("True"))
}
// Test case for any function which accepts and returns a single string. // Test case for any function which accepts and returns a single string.
type StringTest struct { type StringTest struct {
in, out string in, out string

View file

@ -22,7 +22,6 @@ import (
"forgejo.org/modules/log" "forgejo.org/modules/log"
"forgejo.org/modules/optional" "forgejo.org/modules/optional"
"forgejo.org/modules/setting" "forgejo.org/modules/setting"
"forgejo.org/modules/util"
"forgejo.org/modules/validation" "forgejo.org/modules/validation"
"forgejo.org/modules/web" "forgejo.org/modules/web"
"forgejo.org/routers/web/explore" "forgejo.org/routers/web/explore"
@ -77,11 +76,11 @@ func Users(ctx *context.Context) {
PageSize: setting.UI.Admin.UserPagingNum, PageSize: setting.UI.Admin.UserPagingNum,
}, },
SearchByEmail: true, SearchByEmail: true,
IsActive: util.OptionalBoolParse(statusFilterMap["is_active"]), IsActive: optional.ParseBool(statusFilterMap["is_active"]),
IsAdmin: util.OptionalBoolParse(statusFilterMap["is_admin"]), IsAdmin: optional.ParseBool(statusFilterMap["is_admin"]),
IsRestricted: util.OptionalBoolParse(statusFilterMap["is_restricted"]), IsRestricted: optional.ParseBool(statusFilterMap["is_restricted"]),
IsTwoFactorEnabled: util.OptionalBoolParse(statusFilterMap["is_2fa_enabled"]), IsTwoFactorEnabled: optional.ParseBool(statusFilterMap["is_2fa_enabled"]),
IsProhibitLogin: util.OptionalBoolParse(statusFilterMap["is_prohibit_login"]), IsProhibitLogin: optional.ParseBool(statusFilterMap["is_prohibit_login"]),
IncludeReserved: true, // administrator needs to list all accounts include reserved, bot, remote ones IncludeReserved: true, // administrator needs to list all accounts include reserved, bot, remote ones
Load2FAStatus: true, Load2FAStatus: true,
ExtraParamStrings: extraParamStrings, ExtraParamStrings: extraParamStrings,