chore: ruff format
All checks were successful
Build ISO / build-iso (push) Successful in 18m3s
CI / lint (push) Successful in 27s
CI / test (push) Successful in 1m22s
CI / validate-json (push) Successful in 25s
CI / markdown-links (push) Successful in 13s
Release / release (push) Successful in 12m13s

Whitespace-only — `ruff check` was green when 26.17-alpha shipped but
I forgot to run `ruff format`, so the CI format-check job went red on
the release commit. Runtime artifacts are unaffected (release.yml
doesn't gate on lint); this just re-greens the main baseline going
forward.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Daniel Maksymilian Syrnicki 2026-05-11 20:10:04 +02:00
parent 8e1f817d85
commit b725bf1773
12 changed files with 25 additions and 72 deletions

View file

@ -945,10 +945,7 @@ def _do_remove(name):
dependents = deps.dependents_of(name)
if dependents:
return 409, {
"error": (
f"{name!r} is required by: {', '.join(dependents)}. "
"Remove those first."
),
"error": (f"{name!r} is required by: {', '.join(dependents)}. Remove those first."),
"dependents": list(dependents),
}
compose_warning = None

View file

@ -128,8 +128,7 @@ def _cmd_app_remove(args: argparse.Namespace) -> int:
dependents = deps.dependents_of(args.name)
if dependents:
print(
f"error: {args.name!r} is required by: {', '.join(dependents)}. "
"Remove those first.",
f"error: {args.name!r} is required by: {', '.join(dependents)}. Remove those first.",
file=sys.stderr,
)
return 2

View file

@ -90,8 +90,7 @@ def plan_install(name: str) -> DepPlan:
m = _load_any(start)
if m is None:
raise DependencyError(
f"required app {start!r} not found in installed apps, "
"catalog, or bundled apps"
f"required app {start!r} not found in installed apps, catalog, or bundled apps"
)
# Sort requires alphabetically for deterministic install order.
children = iter(sorted(r.app for r in m.requires))

View file

@ -137,8 +137,7 @@ def compose_exec_script(
if proc.returncode != 0:
err = (proc.stderr or proc.stdout or b"").decode("utf-8", "replace").strip()
raise DockerError(
f"compose exec {service} hook {script_path.name} exited "
f"{proc.returncode}: {err}"
f"compose exec {service} hook {script_path.name} exited {proc.returncode}: {err}"
)
return proc.stdout.decode("utf-8", "replace")

View file

@ -152,9 +152,7 @@ def _parse_hook_output(text: str) -> dict[str, str]:
out: dict[str, str] = {}
# First pass: skip FURTKA_JSON lines for KEY=VALUE extraction.
kv_lines = [
line for line in text.splitlines() if not _FURTKA_JSON_RE.match(line.strip())
]
kv_lines = [line for line in text.splitlines() if not _FURTKA_JSON_RE.match(line.strip())]
kv = installer.parse_env_text("\n".join(kv_lines))
for key, value in kv.items():
if not SETTING_NAME_RE.match(key):
@ -172,22 +170,16 @@ def _parse_hook_output(text: str) -> dict[str, str]:
try:
payload = json.loads(m.group(1))
except json.JSONDecodeError as e:
raise InstallRunnerError(
f"hook returned invalid FURTKA_JSON payload: {e}"
) from e
raise InstallRunnerError(f"hook returned invalid FURTKA_JSON payload: {e}") from e
if not isinstance(payload, dict):
raise InstallRunnerError(
"hook FURTKA_JSON payload must be an object of KEY=VALUE strings"
)
for key, value in payload.items():
if not isinstance(key, str) or not SETTING_NAME_RE.match(key):
raise InstallRunnerError(
f"hook FURTKA_JSON key {key!r} must be UPPER_SNAKE_CASE"
)
raise InstallRunnerError(f"hook FURTKA_JSON key {key!r} must be UPPER_SNAKE_CASE")
if not isinstance(value, str):
raise InstallRunnerError(
f"hook FURTKA_JSON value for {key!r} must be a string"
)
raise InstallRunnerError(f"hook FURTKA_JSON value for {key!r} must be a string")
out[key] = value
return out
@ -228,9 +220,7 @@ def _fire_install_hooks(consumer: Manifest, consumer_dir: Path) -> None:
provider_dir = apps_dir() / req.app
provider_manifest_path = provider_dir / "manifest.json"
if not provider_manifest_path.is_file():
raise InstallRunnerError(
f"{consumer.name}: required app {req.app!r} is not installed"
)
raise InstallRunnerError(f"{consumer.name}: required app {req.app!r} is not installed")
# Validate provider manifest loads (matches the contract the rest of
# the system relies on — never trust a provider folder with a busted
# manifest).
@ -238,8 +228,7 @@ def _fire_install_hooks(consumer: Manifest, consumer_dir: Path) -> None:
hook_abs = provider_dir / req.on_install
if not hook_abs.is_file():
raise InstallRunnerError(
f"{consumer.name}: on_install hook "
f"{req.on_install!r} missing in provider {req.app}"
f"{consumer.name}: on_install hook {req.on_install!r} missing in provider {req.app}"
)
service = deps.provider_exec_service(provider_dir, req.app)
stdout = dockerops.compose_exec_script(

View file

@ -125,9 +125,7 @@ def _validate_hook_path(value: object, manifest_path: Path, where: str) -> str |
return value
def _parse_requires(
raw: object, manifest_path: Path, self_name: str
) -> tuple[Requirement, ...]:
def _parse_requires(raw: object, manifest_path: Path, self_name: str) -> tuple[Requirement, ...]:
if raw is None:
return ()
if not isinstance(raw, list):
@ -143,9 +141,7 @@ def _parse_requires(
f"{manifest_path}: requires[{i}].app must be a non-empty lowercase app name"
)
if app == self_name:
raise ManifestError(
f"{manifest_path}: requires[{i}].app {app!r} is a self-reference"
)
raise ManifestError(f"{manifest_path}: requires[{i}].app {app!r} is a self-reference")
if app in seen:
raise ManifestError(f"{manifest_path}: requires has duplicate app {app!r}")
seen.add(app)

View file

@ -63,9 +63,7 @@ def reconcile(apps_root: Path, dry_run: bool = False) -> list[Action]:
OSError,
ManifestError,
) as e:
actions.append(
Action("error", m.name, f"on_start({req.app}): {e}")
)
actions.append(Action("error", m.name, f"on_start({req.app}): {e}"))
hook_failed = True
break
if hook_failed:
@ -95,17 +93,13 @@ def _fire_on_start_hook(consumer, req, apps_root: Path) -> None:
provider_dir = apps_root / req.app
provider_manifest_path = provider_dir / "manifest.json"
if not provider_manifest_path.is_file():
raise FileNotFoundError(
f"required app {req.app!r} is not installed"
)
raise FileNotFoundError(f"required app {req.app!r} is not installed")
# Validate provider manifest loads (otherwise scanner would have skipped
# it and we'd still try to exec — fail loud here instead).
load_manifest(provider_manifest_path, expected_name=req.app)
hook_abs = provider_dir / req.on_start
if not hook_abs.is_file():
raise FileNotFoundError(
f"on_start hook {req.on_start!r} missing in provider {req.app}"
)
raise FileNotFoundError(f"on_start hook {req.on_start!r} missing in provider {req.app}")
service = deps.provider_exec_service(provider_dir, req.app)
dockerops.compose_exec_script(
provider_dir,

View file

@ -311,9 +311,7 @@ def test_install_endpoint_without_confirm_returns_409_for_transitive(fake_dirs):
manifest=dict(VALID_MANIFEST, name="mosquitto"),
env_example="A=real",
)
consumer = dict(
VALID_MANIFEST, name="zigbee2mqtt", requires=[{"app": "mosquitto"}]
)
consumer = dict(VALID_MANIFEST, name="zigbee2mqtt", requires=[{"app": "mosquitto"}])
_write_bundled(bundled, "zigbee2mqtt", manifest=consumer, env_example="A=real")
status, body = api._do_install("zigbee2mqtt")
assert status == 409
@ -329,9 +327,7 @@ def test_install_endpoint_with_confirm_dispatches_plan(fake_dirs, no_docker, no_
manifest=dict(VALID_MANIFEST, name="mosquitto"),
env_example="A=real",
)
consumer = dict(
VALID_MANIFEST, name="zigbee2mqtt", requires=[{"app": "mosquitto"}]
)
consumer = dict(VALID_MANIFEST, name="zigbee2mqtt", requires=[{"app": "mosquitto"}])
_write_bundled(bundled, "zigbee2mqtt", manifest=consumer, env_example="A=real")
status, body = api._do_install("zigbee2mqtt", confirm_dependencies=True)
assert status == 202
@ -362,9 +358,7 @@ def test_remove_blocked_when_other_app_depends(fake_dirs, no_docker, no_systemd_
manifest=dict(VALID_MANIFEST, name="mosquitto"),
env_example="A=real",
)
consumer = dict(
VALID_MANIFEST, name="zigbee2mqtt", requires=[{"app": "mosquitto"}]
)
consumer = dict(VALID_MANIFEST, name="zigbee2mqtt", requires=[{"app": "mosquitto"}])
_write_bundled(bundled, "zigbee2mqtt", manifest=consumer, env_example="A=real")
api._do_install("zigbee2mqtt", confirm_dependencies=True)
status, body = api._do_remove("mosquitto")
@ -383,9 +377,7 @@ def test_remove_succeeds_when_dependent_first_removed(fake_dirs, no_docker, no_s
manifest=dict(VALID_MANIFEST, name="mosquitto"),
env_example="A=real",
)
consumer = dict(
VALID_MANIFEST, name="zigbee2mqtt", requires=[{"app": "mosquitto"}]
)
consumer = dict(VALID_MANIFEST, name="zigbee2mqtt", requires=[{"app": "mosquitto"}])
_write_bundled(bundled, "zigbee2mqtt", manifest=consumer, env_example="A=real")
api._do_install("zigbee2mqtt", confirm_dependencies=True)
# Remove consumer first — should succeed.

View file

@ -61,9 +61,7 @@ def test_plan_install_diamond(apps_root):
_write_manifest(apps_root["catalog"], "d")
_write_manifest(apps_root["catalog"], "b", requires=[{"app": "d"}])
_write_manifest(apps_root["catalog"], "c", requires=[{"app": "d"}])
_write_manifest(
apps_root["catalog"], "a", requires=[{"app": "b"}, {"app": "c"}]
)
_write_manifest(apps_root["catalog"], "a", requires=[{"app": "b"}, {"app": "c"}])
plan = deps.plan_install("a")
order = plan.install_order
# D first, A last, B and C in between (deterministically alphabetical).

View file

@ -44,9 +44,7 @@ def test_compose_exec_propagates_env(tmp_path, monkeypatch):
return FakeProc()
monkeypatch.setattr(subprocess, "run", fake_run)
dockerops.compose_exec(
tmp_path, "p", "s", ["true"], env={"A": "1", "B": "two"}
)
dockerops.compose_exec(tmp_path, "p", "s", ["true"], env={"A": "1", "B": "two"})
cmd = recorded["cmd"]
# `--env A=1 --env B=two` should appear before the service name.
s_idx = cmd.index("s")

View file

@ -342,9 +342,7 @@ def test_run_install_hook_rejects_bad_key_name(runner, monkeypatch):
calls: list = []
_stub_docker_ops(monkeypatch, calls)
monkeypatch.setattr(dockerops, "compose_image_tags", lambda a, p: {"mosquitto": "img"})
monkeypatch.setattr(
dockerops, "compose_exec_script", lambda *a, **k: "lowercase_key=oops\n"
)
monkeypatch.setattr(dockerops, "compose_exec_script", lambda *a, **k: "lowercase_key=oops\n")
with pytest.raises(runner.InstallRunnerError, match="UPPER_SNAKE_CASE"):
runner.run_install("z2m")
@ -373,9 +371,7 @@ def test_run_install_hook_rejects_placeholder_value(runner, monkeypatch):
calls: list = []
_stub_docker_ops(monkeypatch, calls)
monkeypatch.setattr(dockerops, "compose_image_tags", lambda a, p: {"mosquitto": "img"})
monkeypatch.setattr(
dockerops, "compose_exec_script", lambda *a, **k: "MQTT_PASS=changeme\n"
)
monkeypatch.setattr(dockerops, "compose_exec_script", lambda *a, **k: "MQTT_PASS=changeme\n")
with pytest.raises(runner.InstallRunnerError, match="placeholder"):
runner.run_install("z2m")
@ -465,9 +461,7 @@ def test_parse_hook_output_rejects_lowercase_key(runner):
def test_parse_hook_output_furtka_json(runner):
out = runner._parse_hook_output(
'FURTKA_JSON: {"FOO": "bar", "BAZ": "qux"}\n'
)
out = runner._parse_hook_output('FURTKA_JSON: {"FOO": "bar", "BAZ": "qux"}\n')
assert out == {"FOO": "bar", "BAZ": "qux"}

View file

@ -232,9 +232,7 @@ def test_reconcile_dry_run_emits_hook_action_without_executing(tmp_path, fake_do
_make_app(tmp_path, "zigbee2mqtt", CONSUMER_MANIFEST)
called = []
monkeypatch.setattr(
dockerops, "compose_exec_script", lambda *a, **k: called.append(1) or ""
)
monkeypatch.setattr(dockerops, "compose_exec_script", lambda *a, **k: called.append(1) or "")
actions = reconciler.reconcile(tmp_path, dry_run=True)
assert called == []
hook_actions = [a for a in actions if a.kind == "hook"]