@@ -53,13 +53,16 @@ class SnowSQLConfigFile(ValueSource):
5353 Later files override earlier files for the same keys.
5454 Returns configuration for ALL connections.
5555
56- Config files searched (in order):
56+ Config files searched (in order, when not in test mode ):
5757 1. Bundled default config (if in package)
5858 2. /etc/snowsql.cnf (system-wide)
5959 3. /etc/snowflake/snowsql.cnf (alternative system)
6060 4. /usr/local/etc/snowsql.cnf (local system)
6161 5. ~/.snowsql.cnf (legacy user config)
6262 6. ~/.snowsql/config (current user config)
63+
64+ In test mode (when config_file_override is set), SnowSQL config files are skipped
65+ to ensure test isolation.
6366 """
6467
6568 # SnowSQL uses different key names - map them to CLI standard names
@@ -87,13 +90,31 @@ class SnowSQLConfigFile(ValueSource):
8790
8891 def __init__ (self ):
8992 """Initialize SnowSQL config file source."""
90- self ._config_files = [
91- Path ("/etc/snowsql.cnf" ),
92- Path ("/etc/snowflake/snowsql.cnf" ),
93- Path ("/usr/local/etc/snowsql.cnf" ),
94- Path .home () / ".snowsql.cnf" ,
95- Path .home () / ".snowsql" / "config" ,
96- ]
93+ # Use SNOWFLAKE_HOME if set and directory exists, otherwise use standard paths
94+ snowflake_home = os .environ .get ("SNOWFLAKE_HOME" )
95+ if snowflake_home :
96+ snowflake_home_path = Path (snowflake_home ).expanduser ()
97+ if snowflake_home_path .exists ():
98+ # Use only the SnowSQL config file within SNOWFLAKE_HOME
99+ self ._config_files = [snowflake_home_path / "config" ]
100+ else :
101+ # SNOWFLAKE_HOME set but doesn't exist, use standard paths
102+ self ._config_files = [
103+ Path ("/etc/snowsql.cnf" ),
104+ Path ("/etc/snowflake/snowsql.cnf" ),
105+ Path ("/usr/local/etc/snowsql.cnf" ),
106+ Path .home () / ".snowsql.cnf" ,
107+ Path .home () / ".snowsql" / "config" ,
108+ ]
109+ else :
110+ # Standard paths when SNOWFLAKE_HOME not set
111+ self ._config_files = [
112+ Path ("/etc/snowsql.cnf" ),
113+ Path ("/etc/snowflake/snowsql.cnf" ),
114+ Path ("/usr/local/etc/snowsql.cnf" ),
115+ Path .home () / ".snowsql.cnf" ,
116+ Path .home () / ".snowsql" / "config" ,
117+ ]
97118
98119 @property
99120 def source_name (self ) -> str :
@@ -162,17 +183,46 @@ class CliConfigFile(ValueSource):
162183 Does NOT merge multiple files - first found wins.
163184 Returns configuration for ALL connections.
164185
165- Search order:
186+ Search order (when no override is set) :
166187 1. ./config.toml (current directory)
167188 2. ~/.snowflake/config.toml (user config)
189+
190+ When config_file_override is set (e.g., in tests), only that file is used.
168191 """
169192
170193 def __init__ (self ):
171194 """Initialize CLI config file source."""
172- self ._search_paths = [
173- Path .cwd () / "config.toml" ,
174- Path .home () / ".snowflake" / "config.toml" ,
175- ]
195+ # Check for config file override from CLI context first
196+ try :
197+ from snowflake .cli .api .cli_global_context import get_cli_context
198+
199+ cli_context = get_cli_context ()
200+ config_override = cli_context .config_file_override
201+ if config_override :
202+ self ._search_paths = [Path (config_override )]
203+ return
204+ except Exception :
205+ pass
206+
207+ # Use SNOWFLAKE_HOME if set and directory exists, otherwise use standard paths
208+ snowflake_home = os .environ .get ("SNOWFLAKE_HOME" )
209+ if snowflake_home :
210+ snowflake_home_path = Path (snowflake_home ).expanduser ()
211+ if snowflake_home_path .exists ():
212+ # Use only config.toml within SNOWFLAKE_HOME
213+ self ._search_paths = [snowflake_home_path / "config.toml" ]
214+ else :
215+ # SNOWFLAKE_HOME set but doesn't exist, use standard paths
216+ self ._search_paths = [
217+ Path .cwd () / "config.toml" ,
218+ Path .home () / ".snowflake" / "config.toml" ,
219+ ]
220+ else :
221+ # Standard paths when SNOWFLAKE_HOME not set
222+ self ._search_paths = [
223+ Path .cwd () / "config.toml" ,
224+ Path .home () / ".snowflake" / "config.toml" ,
225+ ]
176226
177227 @property
178228 def source_name (self ) -> str :
@@ -234,7 +284,16 @@ class ConnectionsConfigFile(ValueSource):
234284
235285 def __init__ (self ):
236286 """Initialize connections.toml source."""
237- self ._file_path = Path .home () / ".snowflake" / "connections.toml"
287+ # Use SNOWFLAKE_HOME if set and directory exists, otherwise use standard path
288+ snowflake_home = os .environ .get ("SNOWFLAKE_HOME" )
289+ if snowflake_home :
290+ snowflake_home_path = Path (snowflake_home ).expanduser ()
291+ if snowflake_home_path .exists ():
292+ self ._file_path = snowflake_home_path / "connections.toml"
293+ else :
294+ self ._file_path = Path .home () / ".snowflake" / "connections.toml"
295+ else :
296+ self ._file_path = Path .home () / ".snowflake" / "connections.toml"
238297
239298 @property
240299 def source_name (self ) -> str :
@@ -244,6 +303,15 @@ def discover(self, key: Optional[str] = None) -> Dict[str, ConfigValue]:
244303 """
245304 Read connections.toml if it exists.
246305 Returns keys in format: connections.{name}.{param} for ALL connections.
306+
307+ Supports both legacy formats:
308+ 1. Direct connection sections (legacy):
309+ [default]
310+ database = "value"
311+
312+ 2. Nested under [connections] section:
313+ [connections.default]
314+ database = "value"
247315 """
248316 if not self ._file_path .exists ():
249317 return {}
@@ -253,12 +321,13 @@ def discover(self, key: Optional[str] = None) -> Dict[str, ConfigValue]:
253321 data = tomllib .load (f )
254322
255323 result = {}
256- connections = data .get ("connections" , {})
257324
258- for conn_name , conn_data in connections .items ():
259- if isinstance (conn_data , dict ):
260- for param_key , param_value in conn_data .items ():
261- full_key = f"connections.{ conn_name } .{ param_key } "
325+ # Check for direct connection sections (legacy format)
326+ for section_name , section_data in data .items ():
327+ if isinstance (section_data , dict ) and section_name != "connections" :
328+ # This is a direct connection section like [default]
329+ for param_key , param_value in section_data .items ():
330+ full_key = f"connections.{ section_name } .{ param_key } "
262331 if key is None or full_key == key :
263332 result [full_key ] = ConfigValue (
264333 key = full_key ,
@@ -267,6 +336,21 @@ def discover(self, key: Optional[str] = None) -> Dict[str, ConfigValue]:
267336 raw_value = param_value ,
268337 )
269338
339+ # Check for nested [connections] section format
340+ connections_section = data .get ("connections" , {})
341+ if isinstance (connections_section , dict ):
342+ for conn_name , conn_data in connections_section .items ():
343+ if isinstance (conn_data , dict ):
344+ for param_key , param_value in conn_data .items ():
345+ full_key = f"connections.{ conn_name } .{ param_key } "
346+ if key is None or full_key == key :
347+ result [full_key ] = ConfigValue (
348+ key = full_key ,
349+ value = param_value ,
350+ source_name = self .source_name ,
351+ raw_value = param_value ,
352+ )
353+
270354 return result
271355
272356 except Exception as e :
0 commit comments