@@ -88,42 +88,7 @@ impl ConfigManager {
8888 /// Load configuration from environment variables
8989 pub fn load_from_env ( ) -> Self {
9090 let mut config = Config :: default ( ) ;
91-
92- // Override with environment variables if present
93- if let Ok ( log_level) = std:: env:: var ( "GPUKILL_LOG_LEVEL" ) {
94- config. log_level = log_level;
95- }
96-
97- if let Ok ( output_format) = std:: env:: var ( "GPUKILL_OUTPUT_FORMAT" ) {
98- config. output_format = output_format;
99- }
100-
101- if let Ok ( timeout) = std:: env:: var ( "GPUKILL_DEFAULT_TIMEOUT" ) {
102- if let Ok ( timeout_secs) = timeout. parse :: < u16 > ( ) {
103- config. default_timeout_secs = timeout_secs;
104- }
105- }
106-
107- if let Ok ( show_details) = std:: env:: var ( "GPUKILL_SHOW_DETAILS" ) {
108- config. show_details = show_details. parse ( ) . unwrap_or ( false ) ;
109- }
110-
111- if let Ok ( watch_interval) = std:: env:: var ( "GPUKILL_WATCH_INTERVAL" ) {
112- if let Ok ( interval_secs) = watch_interval. parse :: < u64 > ( ) {
113- config. watch_interval_secs = interval_secs;
114- }
115- }
116-
117- if let Ok ( table_width) = std:: env:: var ( "GPUKILL_TABLE_WIDTH" ) {
118- if let Ok ( width) = table_width. parse :: < usize > ( ) {
119- config. table_width = width;
120- }
121- }
122-
123- if let Ok ( use_colors) = std:: env:: var ( "GPUKILL_USE_COLORS" ) {
124- config. use_colors = use_colors. parse ( ) . unwrap_or ( true ) ;
125- }
126-
91+ apply_env_overrides ( & mut config) ;
12792 Self { config }
12893 }
12994
@@ -181,20 +146,55 @@ impl ConfigManager {
181146 }
182147}
183148
184- /// Get configuration with fallback chain
185- pub fn get_config ( config_path : Option < String > ) -> Result < ConfigManager > {
186- // 1. Try to load from specified path
187- if let Some ( path) = config_path {
188- return ConfigManager :: load_from_file ( path) ;
149+ fn apply_env_overrides ( config : & mut Config ) {
150+ // Override with environment variables if present
151+ if let Ok ( log_level) = std:: env:: var ( "GPUKILL_LOG_LEVEL" ) {
152+ config. log_level = log_level;
153+ }
154+
155+ if let Ok ( output_format) = std:: env:: var ( "GPUKILL_OUTPUT_FORMAT" ) {
156+ config. output_format = output_format;
157+ }
158+
159+ if let Ok ( timeout) = std:: env:: var ( "GPUKILL_DEFAULT_TIMEOUT" ) {
160+ if let Ok ( timeout_secs) = timeout. parse :: < u16 > ( ) {
161+ config. default_timeout_secs = timeout_secs;
162+ }
189163 }
190164
191- // 2. Try to load from default location
192- if let Ok ( config_manager) = ConfigManager :: load_default ( ) {
193- return Ok ( config_manager) ;
165+ if let Ok ( show_details) = std:: env:: var ( "GPUKILL_SHOW_DETAILS" ) {
166+ config. show_details = show_details. parse ( ) . unwrap_or ( false ) ;
194167 }
195168
196- // 3. Load from environment variables
197- Ok ( ConfigManager :: load_from_env ( ) )
169+ if let Ok ( watch_interval) = std:: env:: var ( "GPUKILL_WATCH_INTERVAL" ) {
170+ if let Ok ( interval_secs) = watch_interval. parse :: < u64 > ( ) {
171+ config. watch_interval_secs = interval_secs;
172+ }
173+ }
174+
175+ if let Ok ( table_width) = std:: env:: var ( "GPUKILL_TABLE_WIDTH" ) {
176+ if let Ok ( width) = table_width. parse :: < usize > ( ) {
177+ config. table_width = width;
178+ }
179+ }
180+
181+ if let Ok ( use_colors) = std:: env:: var ( "GPUKILL_USE_COLORS" ) {
182+ config. use_colors = use_colors. parse ( ) . unwrap_or ( true ) ;
183+ }
184+ }
185+
186+ /// Get configuration with fallback chain
187+ pub fn get_config ( config_path : Option < String > ) -> Result < ConfigManager > {
188+ let mut config = if let Some ( path) = config_path {
189+ ConfigManager :: load_from_file ( path) ?. config
190+ } else if let Ok ( config_manager) = ConfigManager :: load_default ( ) {
191+ config_manager. config
192+ } else {
193+ Config :: default ( )
194+ } ;
195+
196+ apply_env_overrides ( & mut config) ;
197+ Ok ( ConfigManager { config } )
198198}
199199
200200#[ cfg( test) ]
@@ -239,4 +239,25 @@ mod tests {
239239 let manager = ConfigManager :: new ( ) ;
240240 assert_eq ! ( manager. config( ) . log_level, "info" ) ;
241241 }
242+
243+ #[ test]
244+ fn test_env_overrides_config_file ( ) {
245+ let mut config = Config :: default ( ) ;
246+ config. log_level = "warn" . to_string ( ) ;
247+ config. watch_interval_secs = 2 ;
248+ let toml_str = toml:: to_string_pretty ( & config) . unwrap ( ) ;
249+
250+ let temp_file = NamedTempFile :: new ( ) . unwrap ( ) ;
251+ std:: fs:: write ( temp_file. path ( ) , toml_str) . unwrap ( ) ;
252+
253+ std:: env:: set_var ( "GPUKILL_LOG_LEVEL" , "debug" ) ;
254+ std:: env:: set_var ( "GPUKILL_WATCH_INTERVAL" , "10" ) ;
255+
256+ let loaded = get_config ( Some ( temp_file. path ( ) . to_string_lossy ( ) . to_string ( ) ) ) . unwrap ( ) ;
257+ assert_eq ! ( loaded. config( ) . log_level, "debug" ) ;
258+ assert_eq ! ( loaded. config( ) . watch_interval_secs, 10 ) ;
259+
260+ std:: env:: remove_var ( "GPUKILL_LOG_LEVEL" ) ;
261+ std:: env:: remove_var ( "GPUKILL_WATCH_INTERVAL" ) ;
262+ }
242263}
0 commit comments