fix(theme): #66 fail-closed theme-state errors at mkFlake/read

Missing, empty, or non-object theme-state.json now throws a short
message pointing at the template and `nomarchy-theme-sync validate`
instead of a raw readFile/fromJSON stack. Shared reader:
modules/theme-state-read.nix — wired in theme.nix, plymouth/timezone/
hardware, and lib.mkFlake (seq-forced early gate). Field-level schema
in theme.nix kept; unknown border roles still fail there; resolveColor
no longer falls through on missing palette keys. Defaults added for
settings.displayProfile / displayProfileAuto.

Verified: V0 nix flake check --no-build; negative evals (missing,
empty, [], bad border role); good-path template mode + displayProfile
defaults.
This commit is contained in:
Bernardo Magri
2026-07-10 09:38:15 +01:00
parent bd6d94f973
commit a640de4fd4
7 changed files with 138 additions and 15 deletions

26
lib.nix
View File

@@ -5,7 +5,16 @@
# in flake.nix remain the escape hatch for power users.
{ nixpkgs, home-manager, nixos-hardware, nomarchy }:
let
inherit (nixpkgs) lib;
# Shared pure reader (modules/theme-state-read.nix) — re-exported so
# power users composing without mkFlake can call it too.
readThemeState = import ./modules/theme-state-read.nix { inherit lib; };
in
{
inherit readThemeState;
mkFlake =
{ src # the downstream flake directory (./.)
, username # login name; also the homeConfigurations attr
@@ -13,8 +22,6 @@
, system ? "x86_64-linux"
}:
let
inherit (nixpkgs) lib;
# One profile or several (the installer's autodetection emits a few
# common-* modules alongside the model-specific one).
profileNames =
@@ -51,8 +58,17 @@
# and the standalone HM desktop see the same package set.
config.allowUnfree = true;
};
# Early fail-closed gate: missing/empty/non-object theme-state.json
# throws here with a template + validate pointer, before module
# evaluation buries a raw readFile/fromJSON stack. Field-level
# schema still runs in modules/home/theme.nix after defaults merge.
# Forced via seq on the whole return set — attrNames alone must not
# skip the check (Nix is lazy on unused let bindings and attr values).
statePath = src + "/theme-state.json";
_themeState = readThemeState statePath;
in
{
builtins.seq _themeState {
# System layer — rebuilt rarely:
# sudo nixos-rebuild switch --flake .#default
nixosConfigurations.default = nixpkgs.lib.nixosSystem {
@@ -67,7 +83,7 @@
{ environment.systemPackages = [ home-manager.packages.${system}.home-manager ]; }
# System-side theme consumers (Plymouth splash background)
# read the same JSON the desktop does.
{ nomarchy.system.stateFile = src + "/theme-state.json"; }
{ nomarchy.system.stateFile = statePath; }
]
++ hardwareModules
++ [
@@ -87,7 +103,7 @@
{
# Written by nomarchy-theme-sync; reading it is pure — the
# file is part of the downstream flake's source.
nomarchy.stateFile = src + "/theme-state.json";
nomarchy.stateFile = statePath;
home = {
inherit username;
homeDirectory = "/home/${username}";