diff --git a/AGENTS.md b/AGENTS.md index 00f373c..2a04a27 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -110,6 +110,8 @@ Use `git -C ` 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. diff --git a/src/dotfiles/registry.nix b/src/dotfiles/registry.nix index 1bee98b..673f72d 100644 --- a/src/dotfiles/registry.nix +++ b/src/dotfiles/registry.nix @@ -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 + ); + }; } diff --git a/src/dotfiles/registry/validation.nix b/src/dotfiles/registry/validation.nix index 41704a3..b6b7295 100644 --- a/src/dotfiles/registry/validation.nix +++ b/src/dotfiles/registry/validation.nix @@ -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 +)