mirror of
https://github.com/openSUSE/osc.git
synced 2024-12-25 01:16:14 +01:00
Merge pull request #1438 from dmach/conf-allow-undefined-fields
Allow undefined fields in Options and HostOptions
This commit is contained in:
commit
62349a39f1
46
osc/conf.py
46
osc/conf.py
@ -124,6 +124,10 @@ HttpHeader = NewType("HttpHeader", Tuple[str, str])
|
||||
|
||||
|
||||
class OscOptions(BaseModel):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.extra_fields = {}
|
||||
|
||||
# compat function with the config dict
|
||||
def _get_field_name(self, name):
|
||||
if name in self.__fields__:
|
||||
@ -139,8 +143,10 @@ class OscOptions(BaseModel):
|
||||
# compat function with the config dict
|
||||
def __getitem__(self, name):
|
||||
field_name = self._get_field_name(name)
|
||||
|
||||
if field_name is None:
|
||||
field_name = name
|
||||
return self.extra_fields[name]
|
||||
|
||||
try:
|
||||
return getattr(self, field_name)
|
||||
except AttributeError:
|
||||
@ -149,8 +155,11 @@ class OscOptions(BaseModel):
|
||||
# compat function with the config dict
|
||||
def __setitem__(self, name, value):
|
||||
field_name = self._get_field_name(name)
|
||||
|
||||
if field_name is None:
|
||||
field_name = name
|
||||
self.extra_fields[name] = value
|
||||
return
|
||||
|
||||
setattr(self, field_name, value)
|
||||
|
||||
# compat function with the config dict
|
||||
@ -1836,6 +1845,17 @@ def get_config(override_conffile=None,
|
||||
config = Options()
|
||||
config.conffile = conffile
|
||||
|
||||
# read 'debug' value before it gets properly stored into Options for early debug messages
|
||||
if override_debug:
|
||||
debug_str = str(override_debug)
|
||||
elif "OSC_DEBUG" in os.environ:
|
||||
debug_str = os.environ["OSC_DEBUG"]
|
||||
elif "debug" in cp["general"]:
|
||||
debug_str = cp["general"]["debug"]
|
||||
else:
|
||||
debug_str = "0"
|
||||
debug = True if debug_str.strip().lower() in ("1", "yes", "true", "on") else False
|
||||
|
||||
# read host options first in order to populate apiurl aliases
|
||||
urls = [i for i in cp.sections() if i != "general"]
|
||||
for url in urls:
|
||||
@ -1845,8 +1865,10 @@ def get_config(override_conffile=None,
|
||||
raise oscerr.ConfigMissingCredentialsError(f"No user found in section {url}", conffile, url)
|
||||
|
||||
host_options = HostOptions(apiurl=apiurl, username=username, _parent=config)
|
||||
known_ini_keys = set()
|
||||
for name, field in host_options.__fields__.items():
|
||||
ini_key = field.extra.get("ini_key", name)
|
||||
known_ini_keys.add(ini_key)
|
||||
|
||||
if name == "password":
|
||||
# we need to handle the password first because it may be stored in a keyring instead of a config file
|
||||
@ -1862,6 +1884,15 @@ def get_config(override_conffile=None,
|
||||
|
||||
host_options.set_value_from_string(name, value)
|
||||
|
||||
for key, value in cp[url].items():
|
||||
if key.startswith("_"):
|
||||
continue
|
||||
if key in known_ini_keys:
|
||||
continue
|
||||
if debug:
|
||||
print(f"DEBUG: Config option '[{url}]/{key}' doesn't map to any HostOptions field", file=sys.stderr)
|
||||
host_options[key] = value
|
||||
|
||||
scheme = urlsplit(apiurl)[0]
|
||||
if scheme == "http" and not host_options.allow_http:
|
||||
msg = "The apiurl '{apiurl}' uses HTTP protocol without any encryption.\n"
|
||||
@ -1872,8 +1903,10 @@ def get_config(override_conffile=None,
|
||||
config.api_host_options[apiurl] = host_options
|
||||
|
||||
# read the main options
|
||||
known_ini_keys = set()
|
||||
for name, field in config.__fields__.items():
|
||||
ini_key = field.extra.get("ini_key", name)
|
||||
known_ini_keys.add(ini_key)
|
||||
env_key = f"OSC_{name.upper()}"
|
||||
|
||||
# priority: env, overrides, config
|
||||
@ -1900,6 +1933,15 @@ def get_config(override_conffile=None,
|
||||
|
||||
config.set_value_from_string(name, value)
|
||||
|
||||
for key, value in cp["general"].items():
|
||||
if key.startswith("_"):
|
||||
continue
|
||||
if key in known_ini_keys:
|
||||
continue
|
||||
if debug:
|
||||
print(f"DEBUG: Config option '[general]/{key}' doesn't map to any Options field", file=sys.stderr)
|
||||
config[key] = value
|
||||
|
||||
if overrides:
|
||||
unused_overrides_str = ", ".join((f"'{i}'" for i in overrides))
|
||||
raise oscerr.ConfigError(f"Unknown config options: {unused_overrides_str}", "<command-line>")
|
||||
|
@ -78,6 +78,7 @@ maintained_update_project_attribute = OBS:UpdateProject
|
||||
show_download_progress = 0
|
||||
vc-cmd = /usr/lib/build/vc
|
||||
status_mtime_heuristic = 0
|
||||
plugin-option = plugin-general-option
|
||||
|
||||
[https://api.opensuse.org]
|
||||
credentials_mgr_class=osc.credentials.PlaintextConfigFileCredentialsManager
|
||||
@ -97,6 +98,7 @@ trusted_prj = openSUSE:* SUSE:*
|
||||
downloadurl = http://example.com/
|
||||
sshkey = ~/.ssh/id_rsa.pub
|
||||
disable_hdrmd5_check = 0
|
||||
plugin-option = plugin-host-option
|
||||
"""
|
||||
|
||||
|
||||
@ -401,6 +403,22 @@ class TestExampleConfig(unittest.TestCase):
|
||||
host_options = self.config["api_host_options"][self.config["apiurl"]]
|
||||
self.assertEqual(host_options["disable_hdrmd5_check"], False)
|
||||
|
||||
def test_extra_fields(self):
|
||||
self.assertEqual(self.config["plugin-option"], "plugin-general-option")
|
||||
self.assertEqual(self.config.extra_fields, {"plugin-option": "plugin-general-option"})
|
||||
|
||||
self.config["new-option"] = "value"
|
||||
self.assertEqual(self.config["new-option"], "value")
|
||||
self.assertEqual(self.config.extra_fields, {"plugin-option": "plugin-general-option", "new-option": "value"})
|
||||
|
||||
host_options = self.config["api_host_options"][self.config["apiurl"]]
|
||||
self.assertEqual(host_options["plugin-option"], "plugin-host-option")
|
||||
self.assertEqual(host_options.extra_fields, {"plugin-option": "plugin-host-option"})
|
||||
|
||||
host_options["new-option"] = "value"
|
||||
self.assertEqual(host_options["new-option"], "value")
|
||||
self.assertEqual(host_options.extra_fields, {"plugin-option": "plugin-host-option", "new-option": "value"})
|
||||
|
||||
|
||||
class TestFromParent(unittest.TestCase):
|
||||
def setUp(self):
|
||||
|
Loading…
Reference in New Issue
Block a user