dotcli: Implement dot kde apply for schema-backed settings

Pushes every manifest entry's declared value onto the live system via
kwriteconfig6, idempotently. Non-schema (shortcuts/freeform) entries are
rejected as not-yet-supported, deferred to later tasks.
This commit is contained in:
2026-07-05 19:56:32 -04:00
parent c28029681d
commit f7b9f1b251
5 changed files with 137 additions and 5 deletions

View File

@@ -2,6 +2,7 @@ function _dot_kde_usage
echo "usage: dot kde <command>
Commands:
apply push manifest entries onto the live system
save write live KDE settings into the manifest
help show this message
@@ -17,6 +18,9 @@ function _dot_kde
set -l helper_dir (status dirname)
switch "$argv[1]"
case apply
python3 $helper_dir/kde.py apply $argv[2..-1]
return $status
case save
python3 $helper_dir/kde.py save $argv[2..-1]
return $status

View File

@@ -21,6 +21,11 @@ SAVE_USAGE = """usage: dot kde save [identifier]
(no args) refresh every already-declared manifest entry from the live system
help show this message"""
APPLY_USAGE = """usage: dot kde apply
Pushes every manifest entry's declared value onto the live system.
help show this message"""
Setting = namedtuple("Setting", ["file", "group", "key"])
@@ -138,6 +143,22 @@ def read_live_value(setting, default):
return result.stdout.rstrip("\n")
def write_live_value(setting, value):
cmd = [
"kwriteconfig6",
"--file", setting.file,
"--group", setting.group,
"--key", setting.key,
"--",
value,
]
result = subprocess.run(cmd, capture_output=True, text=True)
if result.returncode != 0:
raise RuntimeError(
f"kwriteconfig6 failed for {setting.file}/{setting.group}/{setting.key}: {result.stderr.strip()}"
)
def save_one(identifier, kcfg_map):
setting = parse_identifier(identifier)
mechanism, default = resolve_mechanism(setting, kcfg_map)
@@ -146,6 +167,14 @@ def save_one(identifier, kcfg_map):
return read_live_value(setting, default)
def apply_one(identifier, value, kcfg_map):
setting = parse_identifier(identifier)
mechanism, _default = resolve_mechanism(setting, kcfg_map)
if mechanism != "schema":
raise RuntimeError(f"{identifier}: {mechanism} settings are not yet supported")
write_live_value(setting, value)
def cmd_save(args, manifest_path, schema_dir):
if args and args[0] == "help":
print(SAVE_USAGE)
@@ -172,6 +201,28 @@ def cmd_save(args, manifest_path, schema_dir):
return 0
def cmd_apply(args, manifest_path, schema_dir):
if args and args[0] == "help":
print(APPLY_USAGE)
return 0
if args:
print("dot kde apply: too many arguments", file=sys.stderr)
return 1
kcfg_map = build_kcfg_map(schema_dir)
manifest = load_manifest(manifest_path)
try:
for identifier, value in manifest.items():
apply_one(identifier, value, kcfg_map)
except (ValueError, RuntimeError) as e:
print(f"dot kde apply: {e}", file=sys.stderr)
return 1
return 0
def cmd_complete(schema_dir):
kcfg_map = build_kcfg_map(schema_dir)
for identifier in sorted(set(iter_schema_identifiers(kcfg_map))):
@@ -191,6 +242,9 @@ def main(argv):
if command == "save":
return cmd_save(rest, manifest_path, schema_dir)
if command == "apply":
return cmd_apply(rest, manifest_path, schema_dir)
# Internal, not a user-facing `dot kde` subcommand -- called directly by
# completions/dot.fish to source candidates from the live schema, never
# dispatched to via kde.fish.