Another bulk of refaktoring cleanup

This commit is contained in:
2025-07-11 18:57:40 +02:00
parent 168c5c0da6
commit 33276263b0
12 changed files with 210 additions and 56 deletions

View File

@@ -2,29 +2,18 @@ import os
import yaml
from typing import Dict, List, Optional
def get_invokable_paths(
roles_file: Optional[str] = None,
suffix: Optional[str] = None
) -> List[str]:
"""
Load nested roles YAML from the given file (or default at project root) and return
dash-joined paths where 'invokable' is True. Appends suffix if provided.
:param roles_file: Optional path to YAML file. Defaults to '<project_root>/roles/categories.yml'.
:param suffix: Optional suffix to append to each invokable path.
:return: List of invokable paths.
:raises FileNotFoundError: If the YAML file cannot be found.
:raises yaml.YAMLError: If the YAML file cannot be parsed.
:raises ValueError: If the root of the YAML is not a dictionary.
Load nested roles YAML and return dash-joined paths where 'invokable' is True. Appends suffix if provided.
"""
# Determine default roles_file if not provided
if not roles_file:
script_dir = os.path.dirname(os.path.abspath(__file__))
project_root = os.path.dirname(script_dir)
roles_file = os.path.join(project_root, 'roles', 'categories.yml')
# Load and validate YAML
try:
with open(roles_file, 'r') as f:
data = yaml.safe_load(f) or {}
@@ -36,7 +25,6 @@ def get_invokable_paths(
if not isinstance(data, dict):
raise ValueError("YAML root is not a dictionary")
# Unwrap if single 'roles' key
roles = data
if 'roles' in roles and isinstance(roles['roles'], dict) and len(roles) == 1:
roles = roles['roles']
@@ -54,7 +42,6 @@ def get_invokable_paths(
p += suffix
found.append(p)
# Recurse into non-metadata child dicts
children = {
ck: cv for ck, cv in cfg.items()
if ck not in METADATA and isinstance(cv, dict)
@@ -66,6 +53,61 @@ def get_invokable_paths(
return _recurse(roles)
def get_non_invokable_paths(
roles_file: Optional[str] = None,
suffix: Optional[str] = None
) -> List[str]:
"""
Load nested roles YAML and return dash-joined paths where 'invokable' is False or missing.
Appends suffix if provided.
"""
if not roles_file:
script_dir = os.path.dirname(os.path.abspath(__file__))
project_root = os.path.dirname(script_dir)
roles_file = os.path.join(project_root, 'roles', 'categories.yml')
try:
with open(roles_file, 'r') as f:
data = yaml.safe_load(f) or {}
except FileNotFoundError:
raise FileNotFoundError(f"Roles file not found: {roles_file}")
except yaml.YAMLError as e:
raise yaml.YAMLError(f"Error parsing YAML {roles_file}: {e}")
if not isinstance(data, dict):
raise ValueError("YAML root is not a dictionary")
roles = data
if 'roles' in roles and isinstance(roles['roles'], dict) and len(roles) == 1:
roles = roles['roles']
def _recurse_non(subroles: Dict[str, dict], parent: List[str] = None) -> List[str]:
parent = parent or []
found: List[str] = []
METADATA = {'title', 'description', 'icon', 'invokable'}
for key, cfg in subroles.items():
path = parent + [key]
p = '-'.join(path)
inv = cfg.get('invokable', False)
if not inv:
entry = p + (suffix or "")
found.append(entry)
children = {
ck: cv for ck, cv in cfg.items()
if ck not in METADATA and isinstance(cv, dict)
}
if children:
found.extend(_recurse_non(children, path))
return found
return _recurse_non(roles)
class FilterModule:
def filters(self):
return {'invokable_paths': get_invokable_paths}
return {
'invokable_paths': get_invokable_paths,
'non_invokable_paths': get_non_invokable_paths
}