@@ -77,6 +77,7 @@ class ConfigReader(ConfigFileReader):
77
77
config_name = "standard"
78
78
config_searchpath = list (_CFG_SEARCH_PATHS )
79
79
config_section_schemas = [ConfigSchema .Default , ConfigSchema .Profile ]
80
+ config_warning_issued = False
80
81
81
82
@classmethod
82
83
def select_config_schema_for (cls , section_name ):
@@ -148,7 +149,20 @@ def has_default_file(cls):
148
149
return False
149
150
150
151
@classmethod
151
- def load_config (cls , opts , path = None , profile = None ):
152
+ def config_already_warned (cls ):
153
+ """
154
+ Check if a configuration file warning has been issued.
155
+ This is required as configs are gathered at the root of the
156
+ command chain as well as for command verbs
157
+ """
158
+ if cls .config_warning_issued :
159
+ return True
160
+
161
+ cls .config_warning_issued = True
162
+ return False
163
+
164
+ @classmethod
165
+ def load_config (cls , opts , path = None , profile = None , no_warn = False ):
152
166
"""Load a configuration file into an options object."""
153
167
if path and os .path .exists (path ):
154
168
if os .path .isdir (path ):
@@ -160,9 +174,36 @@ def load_config(cls, opts, path=None, profile=None):
160
174
values = config .get ("default" , {})
161
175
cls ._load_values_into_opts (opts , values )
162
176
163
- if profile and profile != "default" :
164
- values = config .get ("profile:%s" % profile , {})
165
- cls ._load_values_into_opts (opts , values )
177
+ warn = not no_warn and not cls .config_already_warned ()
178
+
179
+ if profile and profile != "default" and warn :
180
+ try :
181
+ values = config ["profile:%s" % profile ]
182
+ cls ._load_values_into_opts (opts , values )
183
+ except KeyError :
184
+ if warn :
185
+ click .secho (
186
+ f"Warning: profile { profile } not found in config files { cls .config_files } " ,
187
+ fg = "yellow" ,
188
+ )
189
+
190
+ existing_config_paths = {
191
+ path : os .path .exists (path ) for path in cls .config_files
192
+ }
193
+ if not any (existing_config_paths .values ()) and warn :
194
+ click .secho (
195
+ "Warning: No config files found in search paths. Tried the following:" ,
196
+ fg = "yellow" ,
197
+ )
198
+ for tested_path , exists in existing_config_paths .items ():
199
+ if exists :
200
+ click .secho (f"{ tested_path } - file exists" , fg = "green" )
201
+ else :
202
+ click .secho (f"{ tested_path } - file does not exist" , fg = "yellow" )
203
+ click .secho (
204
+ "You may need to run `cloudsmith login` to authenticate and create a config file." ,
205
+ fg = "yellow" ,
206
+ )
166
207
167
208
return values
168
209
@@ -206,7 +247,31 @@ class CredentialsReader(ConfigReader):
206
247
config_searchpath = list (_CFG_SEARCH_PATHS )
207
248
config_section_schemas = [CredentialsSchema .Default , CredentialsSchema .Profile ]
208
249
250
+ @classmethod
251
+ def load_config (cls , opts , path = None , profile = None , no_warn = False ):
252
+ """
253
+ Load a credentials configuration file into an options object.
254
+ We overload the load_config command in CredentialsReader as
255
+ credentials files have their own specific default functionality.
256
+ """
257
+ if path and os .path .exists (path ):
258
+ if os .path .isdir (path ):
259
+ cls .config_searchpath .insert (0 , path )
260
+ else :
261
+ cls .config_files .insert (0 , path )
262
+
263
+ config = cls .read_config ()
264
+ values = config .get ("default" , {})
265
+ cls ._load_values_into_opts (opts , values )
266
+
267
+ if profile and profile != "default" :
268
+ values = config .get ("profile:%s" % profile , {})
269
+ cls ._load_values_into_opts (opts , values )
270
+
271
+ return values
272
+
209
273
274
+ # pylint: disable=too-many-public-methods
210
275
class Options :
211
276
"""Options object that holds config for the application."""
212
277
@@ -227,15 +292,15 @@ def get_creds_reader():
227
292
"""Get the credentials config reader class."""
228
293
return CredentialsReader
229
294
230
- def load_config_file (self , path , profile = None ):
295
+ def load_config_file (self , path , profile = None , no_warn = False ):
231
296
"""Load the standard config file."""
232
297
config_cls = self .get_config_reader ()
233
- return config_cls .load_config (self , path , profile = profile )
298
+ return config_cls .load_config (self , path , profile = profile , no_warn = no_warn )
234
299
235
- def load_creds_file (self , path , profile = None ):
300
+ def load_creds_file (self , path , profile = None , no_warn = False ):
236
301
"""Load the credentials config file."""
237
302
config_cls = self .get_creds_reader ()
238
- return config_cls .load_config (self , path , profile = profile )
303
+ return config_cls .load_config (self , path , profile = profile , no_warn = no_warn )
239
304
240
305
@property
241
306
def api_config (self ):
@@ -268,6 +333,16 @@ def api_host(self, value):
268
333
"""Set value for API host."""
269
334
self ._set_option ("api_host" , value )
270
335
336
+ @property
337
+ def no_warn (self ):
338
+ """Get value for API host."""
339
+ return self ._get_option ("no_warn" )
340
+
341
+ @no_warn .setter
342
+ def no_warn (self , value ):
343
+ """Set value for API host."""
344
+ self ._set_option ("no_warn" , value )
345
+
271
346
@property
272
347
def api_key (self ):
273
348
"""Get value for API key."""
0 commit comments