refactor(dotfiles): clarify registry validation #126

Merged
alexion merged 1 commits from refactor/standalone-registry-validation into main 2026-10-04 22:01:59 -04:00
3 changed files with 44 additions and 48 deletions
Showing only changes of commit 4a8e8920ea - Show all commits

View File

@@ -110,6 +110,8 @@
Use `git -C <repository-root>` or top-anchored pathspecs for repository-wide history searches.
- A `**/*.nix` Git pathspec does not include Nix files directly in its starting directory.
Include both `*.nix` and `**/*.nix`, or use a recursive `*.nix` pathspec, when linting every Nix file.
- Nix `let` bindings are recursive; their source order does not determine binding availability.
Treat Natu `let_order` as a readability rule, not an evaluation dependency.
- Ariadne extraction must preserve the game-root season prefix for archived source.
Different game installs can contain compiled scripts with the same internal path.
- Clew owns Ren'Py extraction, preparation, and compiled-script AST export. Ariadne owns analysis over Clew-produced data.

View File

@@ -19,14 +19,12 @@ let
];
}).config;
data = validate (
lib.mapAttrs (
registryName: _registry:
lib.mapAttrs (hostName: host: host.config.registry.${registryName}.${hostName} or { }) hosts
) definitions
);
validation = import ./registry/validation.nix { inherit data definitions lib; };
validate = import ./registry/validation.nix { inherit definitions lib; };
data = lib.mapAttrs (
registryName: _registry:
lib.mapAttrs (hostName: host: host.config.registry.${registryName}.${hostName} or { }) hosts
) definitions;
in
{
types = lib.mapAttrs (_name: definition: definition.type) definitions;
@@ -45,13 +43,16 @@ in
) definitions;
};
collected = data // {
join =
host: entry:
lib.filterAttrs (_name: value: value != null) (
lib.mapAttrs (
registryName: _registry: (data.${registryName}.${host} or { }).${entry} or null
) definitions
);
};
collected =
assert validation;
data
// {
join =
host: entry:
lib.filterAttrs (_name: value: value != null) (
lib.mapAttrs (
registryName: _registry: (data.${registryName}.${host} or { }).${entry} or null
) definitions
);
};
}

View File

@@ -1,41 +1,34 @@
{
data,
definitions,
lib,
}:
let
validationAssertions =
data:
checkResults = lib.concatLists (
lib.mapAttrsToList (
registryName: definition:
map (check: {
assertion = check.assertion (entriesForRegistry registryName);
inherit (check) message;
}) definition.checks
) definitions
);
entriesForRegistry =
registryName:
lib.concatLists (
lib.mapAttrsToList (
registryName: registry:
let
entries = flattenRegistryEntries registryName data.${registryName};
in
map (check: {
assertion = check.assertion entries;
inherit (check) message;
}) registry.checks
) definitions
lib.mapAttrsToList (host: entries: entriesForHost registryName host entries) data.${registryName}
);
flattenRegistryEntries =
registryName: data:
lib.concatLists (
lib.mapAttrsToList (
host: entries:
lib.mapAttrsToList (entry: value: {
path = "registry.${registryName}.${host}.${entry}";
inherit host entry value;
}) entries
) data
);
entriesForHost =
registryName: host: entries:
lib.mapAttrsToList (entry: value: {
path = "registry.${registryName}.${host}.${entry}";
inherit host entry value;
}) entries;
failures = lib.filter (result: !result.assertion) checkResults;
in
data:
let
assertions = validationAssertions data;
failures = lib.filter (assertion: !assertion.assertion) assertions;
in
assert lib.assertMsg (lib.all (assertion: assertion.assertion) assertions) (
lib.concatMapStringsSep "\n" (assertion: assertion.message) failures
);
data
lib.assertMsg (lib.all (result: result.assertion) checkResults) (
lib.concatMapStringsSep "\n" (result: result.message) failures
)