55import argparse
66import os
77import sys
8- from typing import Any , Dict , List , Optional
8+ from typing import Any , Dict , List , Optional , Type , TypeVar , cast
99
1010from linodecli .exit_codes import ExitCodes
1111
2727
2828ENV_TOKEN_NAME = "LINODE_CLI_TOKEN"
2929
30+ T = TypeVar ("T" )
31+
3032
3133class CLIConfig :
3234 """
@@ -216,13 +218,8 @@ def plugin_set_value(self, key: str, value: Any):
216218 :param value: The value to set for this key
217219 :type value: any
218220 """
219- if self .running_plugin is None :
220- raise RuntimeError (
221- "No running plugin to retrieve configuration for!"
222- )
223-
224221 username = self .username or self .default_username ()
225- self .config .set (username , f"plugin- { self .running_plugin } - { key } " , value )
222+ self .config .set (username , self ._get_plugin_key ( key ) , value )
226223
227224 def plugin_get_value (self , key : str ) -> Optional [Any ]:
228225 """
@@ -238,15 +235,52 @@ def plugin_get_value(self, key: str) -> Optional[Any]:
238235 :returns: The value for this plugin for this key, or None if not set
239236 :rtype: any
240237 """
238+ username = self .username or self .default_username () or "DEFAULT"
239+ return self .config .get (
240+ username , self ._get_plugin_key (key ), fallback = None
241+ )
242+
243+ def plugin_get_config_value_or_set_default (
244+ self , key : str , default : T , value_type : Type [T ] = str
245+ ) -> T :
246+ """
247+ Retrieves a plugin option value of the given type from the config. If the
248+ value is not set, sets it to the provided default value and returns that.
249+ """
250+ value = self .plugin_get_value (key )
251+
252+ if value is None :
253+ # option not set - set to default and store it in the config file
254+ value_as_str = (
255+ ("yes" if default else "no" )
256+ if value_type is bool
257+ else str (default )
258+ )
259+ self .plugin_set_value (key , value_as_str )
260+ self .write_config ()
261+ return default
262+
263+ if value_type is bool :
264+ return self .parse_boolean (value )
265+
266+ return cast (T , value_type (value ))
267+
268+ def plugin_remove_option (self , key : str ):
269+ """
270+ Removes a plugin configuration option.
271+
272+ :param key: The key of the option to remove
273+ """
274+ username = self .username or self .default_username ()
275+ self .config .remove_option (username , self ._get_plugin_key (key ))
276+
277+ def _get_plugin_key (self , key : str ) -> str :
241278 if self .running_plugin is None :
242279 raise RuntimeError (
243280 "No running plugin to retrieve configuration for!"
244281 )
245282
246- username = self .username or self .default_username () or "DEFAULT"
247- full_key = f"plugin-{ self .running_plugin } -{ key } "
248-
249- return self .config .get (username , full_key , fallback = None )
283+ return f"plugin-{ self .running_plugin } -{ key } "
250284
251285 # TODO: this is more of an argparsing function than it is a config function
252286 # might be better to move this to argparsing during refactor and just have
@@ -654,3 +688,12 @@ def get_custom_aliases(self) -> Dict[str, str]:
654688 if (self .config .has_section ("custom_aliases" ))
655689 else {}
656690 )
691+
692+ def parse_boolean (self , value : str ) -> Optional [bool ]:
693+ """
694+ Parses a string config value into a boolean.
695+
696+ :param value: The string value to parse.
697+ :return: The parsed boolean value.
698+ """
699+ return self .config .BOOLEAN_STATES .get (value .lower (), None )
0 commit comments