@@ -5,6 +5,7 @@ package config
55
66import (
77 "context"
8+ "fmt"
89 "sync"
910
1011 "code.gitea.io/gitea/modules/json"
@@ -19,8 +20,8 @@ type CfgSecKey struct {
1920type Value [T any ] struct {
2021 mu sync.RWMutex
2122
22- cfgSecKey CfgSecKey
23- dynKey string
23+ cfgSecKey CfgSecKey
24+ dynKey , selectFromKey string
2425
2526 def , value T
2627 revision int
@@ -35,19 +36,41 @@ func (value *Value[T]) parse(key, valStr string) (v T) {
3536 }
3637 }
3738
39+ return value .invert (v )
40+ }
41+
42+ func (value * Value [T ]) invertBoolStr (val string ) (inverted string ) {
43+ if val == "true" {
44+ return "false"
45+ }
46+
47+ return "true"
48+ }
49+
50+ func (value * Value [T ]) invert (val T ) (v T ) {
51+ v = val
3852 if value .flipBoolean {
53+ fmt .Printf ("Flipping boolean value '%v'...\n " , val )
3954 // if value is of type bool
40- if _ , ok := any (v ).(bool ); ok {
55+ if _ , ok := any (val ).(bool ); ok {
4156 // invert the boolean value upon retrieval
42- v = any (! any (v ).(bool )).(T )
57+ v = any (! any (val ).(bool )).(T )
4358 } else {
44- log .Warn ("Ignoring attempt to invert key '%q' for non boolean type" , key )
59+ log .Warn ("Ignoring attempt to invert key '%q' for non boolean type" , value . selectFromKey )
4560 }
4661 }
4762
4863 return v
4964}
5065
66+ func (value * Value [T ]) getKey () string {
67+ if value .selectFromKey != "" {
68+ return value .selectFromKey
69+ }
70+
71+ return value .dynKey
72+ }
73+
5174func (value * Value [T ]) Value (ctx context.Context ) (v T ) {
5275 dg := GetDynGetter ()
5376 if dg == nil {
@@ -69,7 +92,7 @@ func (value *Value[T]) Value(ctx context.Context) (v T) {
6992
7093 // try to parse the config and cache it
7194 var valStr * string
72- if dynVal , has := dg .GetValue (ctx , value .dynKey ); has {
95+ if dynVal , has := dg .GetValue (ctx , value .getKey () ); has {
7396 valStr = & dynVal
7497 } else if cfgVal , has := GetCfgSecKeyGetter ().GetValue (value .cfgSecKey .Sec , value .cfgSecKey .Key ); has {
7598 valStr = & cfgVal
@@ -91,6 +114,10 @@ func (value *Value[T]) DynKey() string {
91114 return value .dynKey
92115}
93116
117+ func (value * Value [T ]) SelectFromKey () string {
118+ return value .selectFromKey
119+ }
120+
94121func (value * Value [T ]) WithDefault (def T ) * Value [T ] {
95122 value .def = def
96123 return value
@@ -110,6 +137,29 @@ func (value *Value[bool]) Invert() *Value[bool] {
110137 return value
111138}
112139
140+ func (value * Value [any ]) SelectFrom (sectionName string ) * Value [any ] {
141+ value .selectFromKey = sectionName
142+ return value
143+ }
144+
145+ func (value * Value [any ]) SetValue (val string ) error {
146+ ctx := context .Background ()
147+ ds := GetDynSetter ()
148+ if ds == nil {
149+ // this is an edge case: the database is not initialized but the system setting is going to be used
150+ // it should panic to avoid inconsistent config values (from config / system setting) and fix the code
151+ panic ("no config dyn value getter" )
152+ }
153+
154+ fmt .Printf ("Setting value '%s' with old key '%s' using key '%s'\n " , val , value .selectFromKey , value .dynKey )
155+
156+ if value .flipBoolean {
157+ return ds .SetValue (ctx , value .getKey (), value .invertBoolStr (val ))
158+ }
159+
160+ return ds .SetValue (ctx , value .getKey (), val )
161+ }
162+
113163func ValueJSON [T any ](dynKey string ) * Value [T ] {
114164 return & Value [T ]{dynKey : dynKey }
115165}
0 commit comments