Compare commits

..

2 Commits

Author SHA1 Message Date
dw-0
9c7b5fcb10 fix: update scp submodule so duplicate sections are preserved while editing configs (#738)
* fix: improve repository parsing logic to handle empty lines and comments more effectively

* fix: update scp submodule so duplicate sections are preserved while editing configs (#735)

* Squashed 'kiauh/core/submodules/simple_config_parser/' changes from f5eee99..5bc9e0a

5bc9e0a docs: update README
394dd7b refactor!: improve parsing and writing for config (#5)

git-subtree-dir: kiauh/core/submodules/simple_config_parser
git-subtree-split: 5bc9e0a50947f1be2f4877a10ab3a632774f82ea

* fix(logging): change warning to error message for config creation failure

* fix(config): improve readability by using descriptive variable names for options

(cherry picked from commit ae0a6b697e)

* Squashed 'kiauh/core/submodules/simple_config_parser/' changes from 5bc9e0a..eef8861

eef8861 refactor: update type hint for fallback parameter to Any
5d04325 Revert "chore: use Optional instead of | and None instead of _UNSET"

git-subtree-dir: kiauh/core/submodules/simple_config_parser
git-subtree-split: eef8861f126ddf84012ac8bed77b467926016d3e

* Squashed 'kiauh/core/submodules/simple_config_parser/' changes from eef8861..9c89612

9c89612 fix: correct assignment of raw value in option handling

git-subtree-dir: kiauh/core/submodules/simple_config_parser
git-subtree-split: 9c896124cf624e25410714649d306001250482f1

* fix: remove unnecessary whitespace in trusted_clients formatting
2025-10-26 22:03:26 +01:00
dw-0
191bdd4874 Revert "fix: update scp submodule so duplicate sections are preserved… (#737)
Revert "fix: update scp submodule so duplicate sections are preserved while editing configs (#735)"

This reverts commit ae0a6b697e.
2025-10-26 18:58:33 +01:00
3 changed files with 34 additions and 31 deletions

View File

@@ -123,7 +123,7 @@ def create_example_moonraker_conf(
scp = SimpleConfigParser()
scp.read_file(target)
trusted_clients: List[str] = [
f" {'.'.join(ip)}\n",
f"{'.'.join(ip)}",
*scp.getvals("authorization", "trusted_clients"),
]

View File

@@ -254,32 +254,34 @@ class KiauhSettings:
section: str,
option: str,
getter: Callable[[str, str, T | None], T],
fallback: T = None,
fallback: T | None = None,
silent: bool = False,
) -> T:
) -> T | None:
if not self.__check_option_exists(section, option, fallback, silent):
return fallback
return getter(section, option, fallback)
def __set_repo_state(self, section: str, repos: List[str]) -> List[Repository]:
_repos: List[Repository] = []
for repo in repos:
try:
if repo.strip().startswith("#") or repo.strip().startswith(";"):
continue
if "," in repo:
url, branch = repo.strip().split(",")
for raw in repos:
line = raw.strip()
if not branch:
branch = "master"
if not line or line.startswith("#") or line.startswith(";"):
continue
try:
if "," in line:
url_part, branch_part = line.split(",")
url = url_part.strip()
branch = branch_part.strip() or "master"
else:
url = repo.strip()
url = line
branch = "master"
# url must not be empty otherwise it's considered
# as an unrecoverable, invalid configuration
if not url:
raise InvalidValueError(section, "repositories", repo)
raise InvalidValueError(section, "repositories", line)
_repos.append(Repository(url.strip(), branch.strip()))

View File

@@ -12,7 +12,7 @@ import re
from dataclasses import dataclass, field
from enum import Enum
from pathlib import Path
from typing import Any, Callable, Dict, List, Optional, Set, Union
from typing import Any, Callable, Dict, List, Set, Union
# definition of section line:
# - the line MUST start with an opening square bracket - it is the first section marker
@@ -91,6 +91,9 @@ class LineType(Enum):
BLANK = "blank"
_UNSET = object()
class NoSectionError(Exception):
"""Raised when a section is not defined"""
@@ -342,7 +345,7 @@ class SimpleConfigParser:
for line in file:
self._parse_line(line)
def write_file(self, path: Union[str, Path]) -> None:
def write_file(self, path: str | Path) -> None:
"""Write the config to a file"""
if path is None:
raise ValueError("File path cannot be None")
@@ -418,9 +421,7 @@ class SimpleConfigParser:
"""Check if an option exists in a section"""
return self.has_section(section) and option in self.get_options(section)
def set_option(
self, section: str, option: str, value: Union[str, List[str]]
) -> None:
def set_option(self, section: str, option: str, value: str | List[str]) -> None:
"""
Set the value of an option in a section. If the section does not exist,
it is created. If the option does not exist, it is created.
@@ -467,8 +468,8 @@ class SimpleConfigParser:
elif opt and isinstance(opt, Option) and isinstance(value, str):
curr_val = opt.value
new_val = value
opt.value = value
opt.raw.replace(curr_val, new_val)
opt.value = new_val
opt.raw = opt.raw.replace(curr_val, new_val)
elif opt and isinstance(opt, MultiLineOption) and isinstance(value, list):
# note: we completely replace the existing values
@@ -561,7 +562,7 @@ class SimpleConfigParser:
else self._find_option_by_name(option, section=sects[0])
)
def getval(self, section: str, option: str, fallback: Optional[str] = None) -> str:
def getval(self, section: str, option: str, fallback: str | _UNSET = _UNSET) -> str:
"""
Return the value of the given option in the given section
@@ -576,12 +577,12 @@ class SimpleConfigParser:
return opt.value if opt else ""
except (NoSectionError, NoOptionError):
if fallback is None:
if fallback is _UNSET:
raise
return fallback
def getvals(
self, section: str, option: str, fallback: Optional[List[str]] = None
self, section: str, option: str, fallback: List[str] | _UNSET = _UNSET
) -> List[str]:
"""
Return the values of the given multi-line option in the given section
@@ -597,22 +598,22 @@ class SimpleConfigParser:
return [v.value for v in opt.values] if opt else []
except (NoSectionError, NoOptionError):
if fallback is None:
if fallback is _UNSET:
raise
return fallback
def getint(self, section: str, option: str, fallback: Optional[int] = None) -> int:
def getint(self, section: str, option: str, fallback: int | _UNSET = _UNSET) -> int:
"""Return the value of the given option in the given section as an int"""
return self._get_conv(section, option, int, fallback=fallback)
def getfloat(
self, section: str, option: str, fallback: Optional[float] = None
self, section: str, option: str, fallback: float | _UNSET = _UNSET
) -> float:
"""Return the value of the given option in the given section as a float"""
return self._get_conv(section, option, float, fallback=fallback)
def getboolean(
self, section: str, option: str, fallback: Optional[bool] = None
self, section: str, option: str, fallback: bool | _UNSET = _UNSET
) -> bool:
"""Return the value of the given option in the given section as a boolean"""
return self._get_conv(
@@ -631,14 +632,14 @@ class SimpleConfigParser:
self,
section: str,
option: str,
conv: Callable[[str], Union[int, float, bool]],
fallback: Optional[Any] = None,
) -> Union[int, float, bool]:
conv: Callable[[str], int | float | bool],
fallback: Any = _UNSET,
) -> int | float | bool:
"""Return the value of the given option in the given section as a converted value"""
try:
return conv(self.getval(section, option, fallback))
except (ValueError, TypeError, AttributeError) as e:
if fallback is not None:
if fallback is not _UNSET:
return fallback
raise ValueError(
f"Cannot convert {self.getval(section, option)} to {conv.__name__}"