[feature] update config types to use bytesize.Size (#828)

* update config size types to use bytesize.Size

* submit unchecked-out file ... 🤦

* fix bytesize config var decoding

* bump bytesize version

* update kim's libraries in readme

* update envparse.sh to output more useful errors

* improve envparse.sh

* remove reliance on jq

* instead, use uint64 for bytesize flag types

* remove redundant type

* fix viper unmarshaling

* Update envparsing.sh

* fix envparsing test

Signed-off-by: kim <grufwub@gmail.com>
Co-authored-by: tobi <31960611+tsmethurst@users.noreply.github.com>
This commit is contained in:
kim 2022-09-29 21:50:43 +01:00 committed by GitHub
commit 1d999712e6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
30 changed files with 223 additions and 169 deletions

View file

@ -21,6 +21,7 @@ package config
import (
"reflect"
"codeberg.org/gruf/go-bytesize"
"github.com/mitchellh/mapstructure"
)
@ -76,13 +77,13 @@ type Configuration struct {
AccountsReasonRequired bool `name:"accounts-reason-required" usage:"Do new account signups require a reason to be submitted on registration?"`
AccountsAllowCustomCSS bool `name:"accounts-allow-custom-css" usage:"Allow accounts to enable custom CSS for their profile pages and statuses."`
MediaImageMaxSize int `name:"media-image-max-size" usage:"Max size of accepted images in bytes"`
MediaVideoMaxSize int `name:"media-video-max-size" usage:"Max size of accepted videos in bytes"`
MediaDescriptionMinChars int `name:"media-description-min-chars" usage:"Min required chars for an image description"`
MediaDescriptionMaxChars int `name:"media-description-max-chars" usage:"Max permitted chars for an image description"`
MediaRemoteCacheDays int `name:"media-remote-cache-days" usage:"Number of days to locally cache media from remote instances. If set to 0, remote media will be kept indefinitely."`
MediaEmojiLocalMaxSize int `name:"media-emoji-local-max-size" usage:"Max size in bytes of emojis uploaded to this instance via the admin API."`
MediaEmojiRemoteMaxSize int `name:"media-emoji-remote-max-size" usage:"Max size in bytes of emojis to download from other instances."`
MediaImageMaxSize bytesize.Size `name:"media-image-max-size" usage:"Max size of accepted images in bytes"`
MediaVideoMaxSize bytesize.Size `name:"media-video-max-size" usage:"Max size of accepted videos in bytes"`
MediaDescriptionMinChars int `name:"media-description-min-chars" usage:"Min required chars for an image description"`
MediaDescriptionMaxChars int `name:"media-description-max-chars" usage:"Max permitted chars for an image description"`
MediaRemoteCacheDays int `name:"media-remote-cache-days" usage:"Number of days to locally cache media from remote instances. If set to 0, remote media will be kept indefinitely."`
MediaEmojiLocalMaxSize bytesize.Size `name:"media-emoji-local-max-size" usage:"Max size in bytes of emojis uploaded to this instance via the admin API."`
MediaEmojiRemoteMaxSize bytesize.Size `name:"media-emoji-remote-max-size" usage:"Max size in bytes of emojis to download from other instances."`
StorageBackend string `name:"storage-backend" usage:"Storage backend to use for media attachments"`
StorageLocalBasePath string `name:"storage-local-base-path" usage:"Full path to an already-created directory where gts should store/retrieve media files. Subfolders will be created within this dir."`

View file

@ -72,13 +72,13 @@ func AddServerFlags(cmd *cobra.Command) {
cmd.Flags().Bool(AccountsAllowCustomCSSFlag(), cfg.AccountsAllowCustomCSS, fieldtag("AccountsAllowCustomCSS", "usage"))
// Media
cmd.Flags().Int(MediaImageMaxSizeFlag(), cfg.MediaImageMaxSize, fieldtag("MediaImageMaxSize", "usage"))
cmd.Flags().Int(MediaVideoMaxSizeFlag(), cfg.MediaVideoMaxSize, fieldtag("MediaVideoMaxSize", "usage"))
cmd.Flags().Uint64(MediaImageMaxSizeFlag(), uint64(cfg.MediaImageMaxSize), fieldtag("MediaImageMaxSize", "usage"))
cmd.Flags().Uint64(MediaVideoMaxSizeFlag(), uint64(cfg.MediaVideoMaxSize), fieldtag("MediaVideoMaxSize", "usage"))
cmd.Flags().Int(MediaDescriptionMinCharsFlag(), cfg.MediaDescriptionMinChars, fieldtag("MediaDescriptionMinChars", "usage"))
cmd.Flags().Int(MediaDescriptionMaxCharsFlag(), cfg.MediaDescriptionMaxChars, fieldtag("MediaDescriptionMaxChars", "usage"))
cmd.Flags().Int(MediaRemoteCacheDaysFlag(), cfg.MediaRemoteCacheDays, fieldtag("MediaRemoteCacheDays", "usage"))
cmd.Flags().Int(MediaEmojiLocalMaxSizeFlag(), cfg.MediaEmojiLocalMaxSize, fieldtag("MediaEmojiLocalMaxSize", "usage"))
cmd.Flags().Int(MediaEmojiRemoteMaxSizeFlag(), cfg.MediaEmojiRemoteMaxSize, fieldtag("MediaEmojiRemoteMaxSize", "usage"))
cmd.Flags().Uint64(MediaEmojiLocalMaxSizeFlag(), uint64(cfg.MediaEmojiLocalMaxSize), fieldtag("MediaEmojiLocalMaxSize", "usage"))
cmd.Flags().Uint64(MediaEmojiRemoteMaxSizeFlag(), uint64(cfg.MediaEmojiRemoteMaxSize), fieldtag("MediaEmojiRemoteMaxSize", "usage"))
// Storage
cmd.Flags().String(StorageBackendFlag(), cfg.StorageBackend, fieldtag("StorageBackend", "usage"))

View file

@ -100,7 +100,7 @@ func main() {
fmt.Fprintf(output, "func Set%[1]s(v %[2]s) { global.Set%[1]s(v) }\n\n", field.Name, field.Type.String())
}
_ = output.Close()
_ = exec.Command("gofmt", "-w", out).Run()
_ = exec.Command("gofumports", "-w", out).Run()
// The plain here is that eventually we might be able
// to generate an example configuration from struct tags

View file

@ -18,7 +18,9 @@
package config
import "github.com/spf13/cobra"
import (
"github.com/spf13/cobra"
)
var global *ConfigState

View file

@ -18,6 +18,8 @@
*/
package config
import "codeberg.org/gruf/go-bytesize"
// GetLogLevel safely fetches the Configuration value for state's 'LogLevel' field
func (st *ConfigState) GetLogLevel() (v string) {
st.mutex.Lock()
@ -719,7 +721,7 @@ func GetAccountsAllowCustomCSS() bool { return global.GetAccountsAllowCustomCSS(
func SetAccountsAllowCustomCSS(v bool) { global.SetAccountsAllowCustomCSS(v) }
// GetMediaImageMaxSize safely fetches the Configuration value for state's 'MediaImageMaxSize' field
func (st *ConfigState) GetMediaImageMaxSize() (v int) {
func (st *ConfigState) GetMediaImageMaxSize() (v bytesize.Size) {
st.mutex.Lock()
v = st.config.MediaImageMaxSize
st.mutex.Unlock()
@ -727,7 +729,7 @@ func (st *ConfigState) GetMediaImageMaxSize() (v int) {
}
// SetMediaImageMaxSize safely sets the Configuration value for state's 'MediaImageMaxSize' field
func (st *ConfigState) SetMediaImageMaxSize(v int) {
func (st *ConfigState) SetMediaImageMaxSize(v bytesize.Size) {
st.mutex.Lock()
defer st.mutex.Unlock()
st.config.MediaImageMaxSize = v
@ -738,13 +740,13 @@ func (st *ConfigState) SetMediaImageMaxSize(v int) {
func MediaImageMaxSizeFlag() string { return "media-image-max-size" }
// GetMediaImageMaxSize safely fetches the value for global configuration 'MediaImageMaxSize' field
func GetMediaImageMaxSize() int { return global.GetMediaImageMaxSize() }
func GetMediaImageMaxSize() bytesize.Size { return global.GetMediaImageMaxSize() }
// SetMediaImageMaxSize safely sets the value for global configuration 'MediaImageMaxSize' field
func SetMediaImageMaxSize(v int) { global.SetMediaImageMaxSize(v) }
func SetMediaImageMaxSize(v bytesize.Size) { global.SetMediaImageMaxSize(v) }
// GetMediaVideoMaxSize safely fetches the Configuration value for state's 'MediaVideoMaxSize' field
func (st *ConfigState) GetMediaVideoMaxSize() (v int) {
func (st *ConfigState) GetMediaVideoMaxSize() (v bytesize.Size) {
st.mutex.Lock()
v = st.config.MediaVideoMaxSize
st.mutex.Unlock()
@ -752,7 +754,7 @@ func (st *ConfigState) GetMediaVideoMaxSize() (v int) {
}
// SetMediaVideoMaxSize safely sets the Configuration value for state's 'MediaVideoMaxSize' field
func (st *ConfigState) SetMediaVideoMaxSize(v int) {
func (st *ConfigState) SetMediaVideoMaxSize(v bytesize.Size) {
st.mutex.Lock()
defer st.mutex.Unlock()
st.config.MediaVideoMaxSize = v
@ -763,10 +765,10 @@ func (st *ConfigState) SetMediaVideoMaxSize(v int) {
func MediaVideoMaxSizeFlag() string { return "media-video-max-size" }
// GetMediaVideoMaxSize safely fetches the value for global configuration 'MediaVideoMaxSize' field
func GetMediaVideoMaxSize() int { return global.GetMediaVideoMaxSize() }
func GetMediaVideoMaxSize() bytesize.Size { return global.GetMediaVideoMaxSize() }
// SetMediaVideoMaxSize safely sets the value for global configuration 'MediaVideoMaxSize' field
func SetMediaVideoMaxSize(v int) { global.SetMediaVideoMaxSize(v) }
func SetMediaVideoMaxSize(v bytesize.Size) { global.SetMediaVideoMaxSize(v) }
// GetMediaDescriptionMinChars safely fetches the Configuration value for state's 'MediaDescriptionMinChars' field
func (st *ConfigState) GetMediaDescriptionMinChars() (v int) {
@ -844,7 +846,7 @@ func GetMediaRemoteCacheDays() int { return global.GetMediaRemoteCacheDays() }
func SetMediaRemoteCacheDays(v int) { global.SetMediaRemoteCacheDays(v) }
// GetMediaEmojiLocalMaxSize safely fetches the Configuration value for state's 'MediaEmojiLocalMaxSize' field
func (st *ConfigState) GetMediaEmojiLocalMaxSize() (v int) {
func (st *ConfigState) GetMediaEmojiLocalMaxSize() (v bytesize.Size) {
st.mutex.Lock()
v = st.config.MediaEmojiLocalMaxSize
st.mutex.Unlock()
@ -852,7 +854,7 @@ func (st *ConfigState) GetMediaEmojiLocalMaxSize() (v int) {
}
// SetMediaEmojiLocalMaxSize safely sets the Configuration value for state's 'MediaEmojiLocalMaxSize' field
func (st *ConfigState) SetMediaEmojiLocalMaxSize(v int) {
func (st *ConfigState) SetMediaEmojiLocalMaxSize(v bytesize.Size) {
st.mutex.Lock()
defer st.mutex.Unlock()
st.config.MediaEmojiLocalMaxSize = v
@ -863,13 +865,13 @@ func (st *ConfigState) SetMediaEmojiLocalMaxSize(v int) {
func MediaEmojiLocalMaxSizeFlag() string { return "media-emoji-local-max-size" }
// GetMediaEmojiLocalMaxSize safely fetches the value for global configuration 'MediaEmojiLocalMaxSize' field
func GetMediaEmojiLocalMaxSize() int { return global.GetMediaEmojiLocalMaxSize() }
func GetMediaEmojiLocalMaxSize() bytesize.Size { return global.GetMediaEmojiLocalMaxSize() }
// SetMediaEmojiLocalMaxSize safely sets the value for global configuration 'MediaEmojiLocalMaxSize' field
func SetMediaEmojiLocalMaxSize(v int) { global.SetMediaEmojiLocalMaxSize(v) }
func SetMediaEmojiLocalMaxSize(v bytesize.Size) { global.SetMediaEmojiLocalMaxSize(v) }
// GetMediaEmojiRemoteMaxSize safely fetches the Configuration value for state's 'MediaEmojiRemoteMaxSize' field
func (st *ConfigState) GetMediaEmojiRemoteMaxSize() (v int) {
func (st *ConfigState) GetMediaEmojiRemoteMaxSize() (v bytesize.Size) {
st.mutex.Lock()
v = st.config.MediaEmojiRemoteMaxSize
st.mutex.Unlock()
@ -877,7 +879,7 @@ func (st *ConfigState) GetMediaEmojiRemoteMaxSize() (v int) {
}
// SetMediaEmojiRemoteMaxSize safely sets the Configuration value for state's 'MediaEmojiRemoteMaxSize' field
func (st *ConfigState) SetMediaEmojiRemoteMaxSize(v int) {
func (st *ConfigState) SetMediaEmojiRemoteMaxSize(v bytesize.Size) {
st.mutex.Lock()
defer st.mutex.Unlock()
st.config.MediaEmojiRemoteMaxSize = v
@ -888,10 +890,10 @@ func (st *ConfigState) SetMediaEmojiRemoteMaxSize(v int) {
func MediaEmojiRemoteMaxSizeFlag() string { return "media-emoji-remote-max-size" }
// GetMediaEmojiRemoteMaxSize safely fetches the value for global configuration 'MediaEmojiRemoteMaxSize' field
func GetMediaEmojiRemoteMaxSize() int { return global.GetMediaEmojiRemoteMaxSize() }
func GetMediaEmojiRemoteMaxSize() bytesize.Size { return global.GetMediaEmojiRemoteMaxSize() }
// SetMediaEmojiRemoteMaxSize safely sets the value for global configuration 'MediaEmojiRemoteMaxSize' field
func SetMediaEmojiRemoteMaxSize(v int) { global.SetMediaEmojiRemoteMaxSize(v) }
func SetMediaEmojiRemoteMaxSize(v bytesize.Size) { global.SetMediaEmojiRemoteMaxSize(v) }
// GetStorageBackend safely fetches the Configuration value for state's 'StorageBackend' field
func (st *ConfigState) GetStorageBackend() (v string) {

View file

@ -133,6 +133,12 @@ func (st *ConfigState) reloadFromViper() {
if err := st.viper.Unmarshal(&st.config, func(c *mapstructure.DecoderConfig) {
c.TagName = "name"
c.ZeroFields = true // empty the config struct before we marshal values into it
oldhook := c.DecodeHook
c.DecodeHook = mapstructure.ComposeDecodeHookFunc(
mapstructure.TextUnmarshallerHookFunc(),
oldhook,
)
}); err != nil {
panic(err)
}

View file

@ -67,14 +67,6 @@ func Validate() error {
errs = append(errs, fmt.Errorf("%s must be set", WebAssetBaseDirFlag()))
}
if m := GetMediaEmojiLocalMaxSize(); m < 0 {
errs = append(errs, fmt.Errorf("%s must not be less than 0", MediaEmojiLocalMaxSizeFlag()))
}
if m := GetMediaEmojiRemoteMaxSize(); m < 0 {
errs = append(errs, fmt.Errorf("%s must not be less than 0", MediaEmojiRemoteMaxSizeFlag()))
}
if len(errs) > 0 {
errStrings := []string{}
for _, err := range errs {

View file

@ -141,16 +141,6 @@ func (suite *ConfigValidateTestSuite) TestValidateConfigBadProtocolNoHost() {
suite.EqualError(err, "host must be set; protocol must be set to either http or https, provided value was foo")
}
func (suite *ConfigValidateTestSuite) TestValidateConfigBadEmojiSizes() {
testrig.InitTestConfig()
config.SetMediaEmojiLocalMaxSize(-10)
config.SetMediaEmojiRemoteMaxSize(-50)
err := config.Validate()
suite.EqualError(err, "media-emoji-local-max-size must not be less than 0; media-emoji-remote-max-size must not be less than 0")
}
func TestConfigValidateTestSuite(t *testing.T) {
suite.Run(t, &ConfigValidateTestSuite{})
}