@@ -118,6 +118,10 @@ func (c *Config) Get(ctx context.Context, pattern string, def ...any) (*gvar.Var
118118// It returns the default value `def` if none of them exists.
119119//
120120// Fetching Rules: Environment arguments are in uppercase format, eg: GF_PACKAGE_VARIABLE.
121+ //
122+ // Note: This method uses configuration file as the primary source, with environment variable
123+ // as fallback only when config value is not found. If you need standard priority where
124+ // environment variables can override config file values, use GetEffective instead.
121125func (c * Config ) GetWithEnv (ctx context.Context , pattern string , def ... any ) (* gvar.Var , error ) {
122126 value , err := c .Get (ctx , pattern )
123127 if err != nil && gerror .Code (err ) != gcode .CodeNotFound {
@@ -140,6 +144,10 @@ func (c *Config) GetWithEnv(ctx context.Context, pattern string, def ...any) (*g
140144// It returns the default value `def` if none of them exists.
141145//
142146// Fetching Rules: Command line arguments are in lowercase format, eg: gf.package.variable.
147+ //
148+ // Note: This method uses configuration file as the primary source, with command line argument
149+ // as fallback only when config value is not found. If you need standard priority where
150+ // command line arguments can override config file values, use GetEffective instead.
143151func (c * Config ) GetWithCmd (ctx context.Context , pattern string , def ... any ) (* gvar.Var , error ) {
144152 value , err := c .Get (ctx , pattern )
145153 if err != nil && gerror .Code (err ) != gcode .CodeNotFound {
@@ -157,6 +165,48 @@ func (c *Config) GetWithCmd(ctx context.Context, pattern string, def ...any) (*g
157165 return value , nil
158166}
159167
168+ // GetEffective returns the configuration value with standard priority (highest to lowest):
169+ //
170+ // Command line arguments > Environment variables > Configuration file > Default value
171+ //
172+ // This follows the 12-Factor App methodology where higher priority sources can override
173+ // lower priority ones, allowing runtime configuration without modifying config files.
174+ //
175+ // Key format conversion:
176+ // - Command line: lowercase with dots, eg: gf.package.variable (--gf.package.variable=value)
177+ // - Environment: uppercase with underscores, eg: GF_PACKAGE_VARIABLE
178+ //
179+ // Unlike GetWithEnv/GetWithCmd which use config file as primary source, this method
180+ // treats command line and environment variables as overrides, which is the standard
181+ // behavior in frameworks like Spring Boot and Viper.
182+ func (c * Config ) GetEffective (ctx context.Context , pattern string , def ... any ) (* gvar.Var , error ) {
183+ // 1. Command line arguments (highest priority)
184+ cmdKey := utils .FormatCmdKey (pattern )
185+ if command .ContainsOpt (cmdKey ) {
186+ return gvar .New (command .GetOpt (cmdKey )), nil
187+ }
188+
189+ // 2. Environment variables
190+ if v := genv .Get (utils .FormatEnvKey (pattern )); v != nil {
191+ return v , nil
192+ }
193+
194+ // 3. Configuration file
195+ value , err := c .Get (ctx , pattern )
196+ if err != nil && gerror .Code (err ) != gcode .CodeNotFound {
197+ return nil , err
198+ }
199+ if value != nil {
200+ return value , nil
201+ }
202+
203+ // 4. Default value
204+ if len (def ) > 0 {
205+ return gvar .New (def [0 ]), nil
206+ }
207+ return nil , nil
208+ }
209+
160210// Data retrieves and returns all configuration data as map type.
161211func (c * Config ) Data (ctx context.Context ) (data map [string ]any , err error ) {
162212 return c .adapter .Data (ctx )
@@ -192,6 +242,15 @@ func (c *Config) MustGetWithCmd(ctx context.Context, pattern string, def ...any)
192242 return v
193243}
194244
245+ // MustGetEffective acts as function GetEffective, but it panics if error occurs.
246+ func (c * Config ) MustGetEffective (ctx context.Context , pattern string , def ... any ) * gvar.Var {
247+ v , err := c .GetEffective (ctx , pattern , def ... )
248+ if err != nil {
249+ panic (err )
250+ }
251+ return v
252+ }
253+
195254// MustData acts as function Data, but it panics if error occurs.
196255func (c * Config ) MustData (ctx context.Context ) map [string ]any {
197256 v , err := c .Data (ctx )
0 commit comments