From d891a92357a3c49a751c526e6a390559415c697e Mon Sep 17 00:00:00 2001 From: _cry64 Date: Sat, 14 Mar 2026 22:18:28 +1000 Subject: [PATCH] redesign module hierarchy --- nix/snow/flake/default.nix | 20 +- nix/snow/flake/lib.nix | 49 +++ nix/snow/flake/lib.nix.bak | 318 ------------------ nix/snow/flake/module.nix | 1 + nix/snow/flake/modules/README.md | 3 + nix/snow/flake/modules/apps.nix | 62 ++-- nix/snow/flake/modules/checks.nix | 37 +- nix/snow/flake/modules/debug.nix | 78 ----- nix/snow/flake/modules/default.nix | 15 + nix/snow/flake/modules/devShells.nix | 53 +-- nix/snow/flake/modules/formatter.nix | 62 +--- nix/snow/flake/modules/legacyPackages.nix | 37 +- nix/snow/flake/modules/moduleWithSystem.nix | 32 -- .../flake/modules/nixosConfigurations.nix | 13 +- nix/snow/flake/modules/nixosModules.nix | 19 +- nix/snow/flake/modules/nixpkgs.nix | 26 -- .../flake/modules/{flake.nix => outputs.nix} | 5 +- nix/snow/flake/modules/overlays.nix | 13 +- nix/snow/flake/modules/packages.nix | 40 ++- nix/snow/flake/modules/perSystem.nix | 159 --------- nix/snow/flake/modules/transposition.nix | 132 -------- nix/snow/flake/modules/withSystem.nix | 37 -- 22 files changed, 244 insertions(+), 967 deletions(-) create mode 100644 nix/snow/flake/lib.nix delete mode 100644 nix/snow/flake/lib.nix.bak create mode 100644 nix/snow/flake/modules/README.md delete mode 100644 nix/snow/flake/modules/debug.nix create mode 100644 nix/snow/flake/modules/default.nix delete mode 100644 nix/snow/flake/modules/moduleWithSystem.nix delete mode 100644 nix/snow/flake/modules/nixpkgs.nix rename nix/snow/flake/modules/{flake.nix => outputs.nix} (94%) delete mode 100644 nix/snow/flake/modules/perSystem.nix delete mode 100644 nix/snow/flake/modules/transposition.nix delete mode 100644 nix/snow/flake/modules/withSystem.nix diff --git a/nix/snow/flake/default.nix b/nix/snow/flake/default.nix index b90126b..9c5d1f5 100644 --- a/nix/snow/flake/default.nix +++ b/nix/snow/flake/default.nix @@ -10,7 +10,6 @@ concatStringsSep filter length - removeAttrs warn ; @@ -21,7 +20,7 @@ in { snowflake = lib.evalModules { class = "snowflake"; specialArgs = let - reservedInputs = { + reservedSpecialArgs = { inherit (this) snow; inherit systems root; inputs = flakeInputs; @@ -29,7 +28,7 @@ in { warnIfReserved = let getReservedNames = names: - reservedInputs + reservedSpecialArgs |> attrNames |> filter (name: names?${name}); @@ -40,7 +39,7 @@ in { in (length reservedNames == 0) || warn '' - [snow] Your `flake.nix` declares inputs using reserved names! + [snow] Your `flake.nix` declares inputs with reserved names! [snow] These will be accessible only via `inputs.''${NAME}` [snow] Please rename the following: [snow] ${concatStringsSep reservedNames ", "} @@ -48,21 +47,10 @@ in { true; in assert warnIfReserved; - flakeInputs - // reservedInputs - # XXX: TODO: - # |> (x: builtins.removeAttrs x ["self" "nodes"]); - |> (x: removeAttrs x ["self"]); + flakeInputs // reservedSpecialArgs; modules = [ ./module.nix - ({config, ...}: { - _module.args = { - self = config; - # XXX: TODO: - # nodes = config.nodes.nodes; - }; - }) ]; }; in diff --git a/nix/snow/flake/lib.nix b/nix/snow/flake/lib.nix new file mode 100644 index 0000000..43326c9 --- /dev/null +++ b/nix/snow/flake/lib.nix @@ -0,0 +1,49 @@ +{ + lib, + revInfo ? "", +}: let + inherit + (lib) + mkOption + types + ; + + # A best effort, lenient estimate. Please use a recent nixpkgs lib if you + # override it at all. + minVersion = "23.05pre-git"; + + isNixpkgsValidVersion = + (builtins.compareVersions lib.version minVersion < 0) + # XXX: TODO: make this message snow specific + || abort '' + The nixpkgs-lib dependency of flake-parts was overridden but is too old. + The minimum supported version of nixpkgs-lib is ${minVersion}, + but the actual version is ${lib.version}${revInfo}. + ''; +in + assert isNixpkgsValidVersion; { + # Helper function for defining a per-system option that + # gets transposed by the usual flake system logic to a + # top-level outputs attribute. + mkPerSystemFlakeOutput = { + name, + option, + file, + }: { + _file = file; + + options = { + outputs.${name} = mkOption { + type = types.attrsWith { + elemType = option.type; + lazy = true; + placeholder = "system"; + }; + default = {}; + description = '' + See {option}`perSystem.${name}` for description and examples. + ''; + }; + }; + }; + } diff --git a/nix/snow/flake/lib.nix.bak b/nix/snow/flake/lib.nix.bak deleted file mode 100644 index c8ea2ba..0000000 --- a/nix/snow/flake/lib.nix.bak +++ /dev/null @@ -1,318 +0,0 @@ -{ lib - # Optionally a string with extra version info to be included in the error message - # in case is lib is out of date. Empty or starts with space. -, revInfo ? "" -}: -let - inherit (lib) - mkOption - mkOptionType - defaultFunctor - isAttrs - isFunction - showOption - throwIf - types - warnIf - getAttrFromPath - setAttrByPath - attrByPath - optionalAttrs - ; - inherit (lib.modules) - mkAliasAndWrapDefsWithPriority; - inherit (lib.types) - path - submoduleWith - ; - - # Polyfill isFlake until Nix with https://github.com/NixOS/nix/pull/7207 is common - isFlake = maybeFlake: - if maybeFlake ? _type - then maybeFlake._type == "flake" - else maybeFlake ? inputs && maybeFlake ? outputs && maybeFlake ? sourceInfo; - - /** - Deprecated for any use except type-merging into `perSystem`. - Use `lib.types.deferredModuleWith` instead, and add `apply = m: [ m ];` if needed. - - The deferredModule type was pioneered in flake-parts for the `perSystem` option. - The Nixpkgs version has an improved merge function that returns a single module, - whereas this version returns a list. The flake-parts version was not updated to - match this improvement in Nixpkgs. - - # History - - This predates `lib.types.deferredModuleWith`, added in Nixpkgs 22.11 - (https://github.com/NixOS/nixpkgs/pull/163617). - Documented as deprecated in flake-parts in January 2026. - */ - deferredModuleWith = - attrs@{ staticModules ? [ ] }: mkOptionType { - name = "deferredModule"; - description = "module"; - check = x: isAttrs x || isFunction x || path.check x; - merge = loc: defs: staticModules ++ map (def: lib.setDefaultModuleLocation "${def.file}, via option ${showOption loc}" def.value) defs; - inherit (submoduleWith { modules = staticModules; }) - getSubOptions - getSubModules; - substSubModules = m: deferredModuleWith (attrs // { - staticModules = m; - }); - functor = defaultFunctor "deferredModuleWith" // { - type = deferredModuleWith; - payload = { - inherit staticModules; - }; - binOp = lhs: rhs: { - staticModules = lhs.staticModules ++ rhs.staticModules; - }; - }; - }; - - # Internal: preserves legacy list-merge behavior for perSystem type-merging. - mkLegacyDeferredModuleType = - module: - deferredModuleWith { - staticModules = [ module ]; - }; - - errorExample = '' - For example: - - outputs = inputs@{ flake-parts, ... }: - flake-parts.lib.mkFlake { inherit inputs; } { /* module */ }; - - To avoid an infinite recursion, *DO NOT* pass `self.inputs` and - *DO NOT* pass `inherit (self) inputs`, but pass the output function - arguments as `inputs` like above. - ''; - - flake-parts-lib = rec { - evalFlakeModule = - args@ - { inputs ? self.inputs - , specialArgs ? { } - - # legacy - , self ? inputs.self or (throw '' - When invoking flake-parts, you must pass all the flake output arguments, - and not just `self.inputs`. - - ${errorExample} - '') - , moduleLocation ? "${self.outPath}/flake.nix" - }: - let - inputsPos = builtins.unsafeGetAttrPos "inputs" args; - errorLocation = - # Best case: user makes it explicit - args.moduleLocation or ( - # Slightly worse: Nix does not technically commit to unsafeGetAttrPos semantics - if inputsPos != null - then inputsPos.file - # Slightly worse: self may not be valid when an error occurs - else if args?inputs.self.outPath - then args.inputs.self.outPath + "/flake.nix" - # Fallback - else "" - ); - in - throwIf - (!args?self && !args?inputs) '' - When invoking flake-parts, you must pass in the flake output arguments. - - ${errorExample} - '' - warnIf - (!args?inputs) '' - When invoking flake-parts, it is recommended to pass all the flake output - arguments in the `inputs` parameter. If you only pass `self`, it's not - possible to use the `inputs` module argument in the module `imports`. - - Please pass the output function arguments. ${errorExample} - '' - - (module: - lib.evalModules { - specialArgs = { - inherit self flake-parts-lib moduleLocation; - inputs = args.inputs or /* legacy, warned above */ self.inputs; - } // specialArgs; - modules = [ ./all-modules.nix (lib.setDefaultModuleLocation errorLocation module) ]; - class = "flake"; - } - ); - - # Function to extract the default flakeModule from - # what may be a flake, returning the argument unmodified - # if it's not a flake. - # - # Useful to map over an 'imports' list to make it less - # verbose in the common case. - defaultModule = maybeFlake: - if isFlake maybeFlake - then maybeFlake.flakeModules.default or maybeFlake - else maybeFlake; - - mkFlake = args: module: - let - eval = flake-parts-lib.evalFlakeModule args module; - in - eval.config.flake; - - /** - Deprecated. Declare options directly, e.g. `options.foo.bar = mkOption { ... }`, - provided that `foo` is already declared as a submodule option. - - In flake-parts, `flake` is declared as a submodule option by the core modules, - so `options.flake.` declarations work directly. - - This function wraps option declarations in a submodule, allowing them to - be merged into an existing submodule option. For example, if `foo` is - already declared as a submodule option, using - `options.foo = mkSubmoduleOptions { bar = mkOption {...}; }` would add - `bar` to the `foo` submodule. - - # History - - This was a workaround for https://github.com/NixOS/nixpkgs/issues/146882, - fixed in Nixpkgs 22.05 by https://github.com/NixOS/nixpkgs/pull/156533. - With the fix, declaring `options.foo.bar` directly works when `foo` is - already a submodule option. Documented as deprecated in flake-parts in January 2026. - */ - mkSubmoduleOptions = - options: - mkOption { - type = types.submoduleWith { - modules = [{ inherit options; }]; - }; - }; - - /** - Deprecated. Use mkPerSystemType/mkPerSystemOption for `perSystem` type-merging, or - use Nixpkgs `types.deferredModule` directly, noting the lack of list wrapping; - see `deferredModuleWith` docs. - */ - mkDeferredModuleType = mkLegacyDeferredModuleType; - - /** - Given a module, construct an option type suitable for type-merging into `perSystem`'s type. - */ - mkPerSystemType = mkLegacyDeferredModuleType; - - /** - Deprecated. Use mkPerSystemOption for `perSystem` type-merging, or - use `mkOption` and Nixpkgs `types.deferredModule` directly, noting the - lack of list wrapping; see `deferredModuleWith` docs. - */ - mkDeferredModuleOption = - module: - mkOption { - type = flake-parts-lib.mkPerSystemType module; - }; - - /** - Given a module, construct an option declaration suitable for merging into the core `perSystem` module. - */ - mkPerSystemOption = mkDeferredModuleOption; - - # Polyfill https://github.com/NixOS/nixpkgs/pull/344216 - # Nixpkgs master 2024-12-09, Nixpkgs 25.05 - attrsWith = types.attrsWith or ({ elemType, lazy ? false, placeholder ? "name" }: - if lazy then types.attrsOf elemType else types.lazyAttrsOf elemType); - - # Helper function for defining a per-system option that - # gets transposed by the usual flake system logic to a - # top-level flake attribute. - mkTransposedPerSystemModule = { name, option, file }: { - _file = file; - - options = { - flake.${name} = mkOption { - type = attrsWith { - elemType = option.type; - lazy = true; - placeholder = "system"; - }; - default = { }; - description = '' - See {option}`perSystem.${name}` for description and examples. - ''; - }; - - perSystem = flake-parts-lib.mkPerSystemOption { - _file = file; - - options.${name} = option; - }; - }; - - config = { - transposition.${name} = { }; - }; - }; - - # Needed pending https://github.com/NixOS/nixpkgs/pull/198450 - mkAliasOptionModule = from: to: { config, options, ... }: - let - fromOpt = getAttrFromPath from options; - toOf = attrByPath to - (abort "Renaming error: option `${showOption to}' does not exist."); - toType = let opt = attrByPath to { } options; in opt.type or (types.submodule { }); - in - { - options = setAttrByPath from (mkOption - { - visible = true; - description = "Alias of {option}`${showOption to}`."; - apply = x: (toOf config); - } // optionalAttrs (toType != null) { - type = toType; - }); - config = mkAliasAndWrapDefsWithPriority (setAttrByPath to) fromOpt; - }; - - # Helper function for importing while preserving module location. To be added - # in nixpkgs: https://github.com/NixOS/nixpkgs/pull/230588 - # I expect these functions to remain identical. This one will stick around - # for a while to support older nixpkgs-lib. - importApply = - modulePath: staticArgs: - lib.setDefaultModuleLocation modulePath (import modulePath staticArgs); - - inherit (import ./lib/memoize/memoize.nix { - inherit lib; - }) memoizeStr; - - /** - `importAndPublish name module` returns a module that both imports the `module`, and exposes it as flake attribute `modules.flake.${name}`. - - This also imports the optional [`modules`](https://flake.parts/options/flake-parts-modules.html) module to support that. - */ - importAndPublish = name: module: { lib, ... }: { - _class = "flake"; - imports = [ - module - ./extras/modules.nix - ]; - flake.modules.flake.${name} = module; - }; - }; - - # A best effort, lenient estimate. Please use a recent nixpkgs lib if you - # override it at all. - minVersion = "23.05pre-git"; - -in - -if builtins.compareVersions lib.version minVersion < 0 -then - abort '' - The nixpkgs-lib dependency of flake-parts was overridden but is too old. - The minimum supported version of nixpkgs-lib is ${minVersion}, - but the actual version is ${lib.version}${revInfo}. - '' -else - - flake-parts-lib diff --git a/nix/snow/flake/module.nix b/nix/snow/flake/module.nix index 79b8804..1aacd0b 100644 --- a/nix/snow/flake/module.nix +++ b/nix/snow/flake/module.nix @@ -18,6 +18,7 @@ }: { imports = [ ./nodes + ./modules (snow.findImport /${root}/snow) ]; } diff --git a/nix/snow/flake/modules/README.md b/nix/snow/flake/modules/README.md new file mode 100644 index 0000000..d19dbc1 --- /dev/null +++ b/nix/snow/flake/modules/README.md @@ -0,0 +1,3 @@ +# Snow Module Backend +This source code was tedious so it's just a modified version of the module backend of +[github:hercules-ci/flake-parts](https://github.com/hercules-ci/flake-parts/tree/main/modules). diff --git a/nix/snow/flake/modules/apps.nix b/nix/snow/flake/modules/apps.nix index 3030d32..75cc4be 100644 --- a/nix/snow/flake/modules/apps.nix +++ b/nix/snow/flake/modules/apps.nix @@ -1,23 +1,31 @@ -{ lib, flake-parts-lib, ... }: -let - inherit (lib) +{ + lib, + snow, + ... +}: let + inherit + (lib) mkOption types ; - inherit (flake-parts-lib) - mkTransposedPerSystemModule + + inherit + (snow) + mkPerSystemFlakeOutput ; - programType = lib.types.coercedTo derivationType lib.getExe lib.types.str; + derivationType = + lib.types.package + // { + check = lib.isDerivation; + }; - derivationType = lib.types.package // { - check = lib.isDerivation; - }; + programType = lib.types.coercedTo derivationType lib.getExe lib.types.str; appType = lib.types.submodule { options = { type = mkOption { - type = lib.types.enum [ "app" ]; + type = lib.types.enum ["app"]; default = "app"; description = '' A type tag for `apps` consumers. @@ -31,7 +39,7 @@ let }; meta = mkOption { type = types.lazyAttrsOf lib.types.raw; - default = { }; + default = {}; # TODO refer to Nix manual 2.25 description = '' Metadata information about the app. @@ -43,19 +51,19 @@ let }; }; in -mkTransposedPerSystemModule { - name = "apps"; - option = mkOption { - type = types.lazyAttrsOf appType; - default = { }; - description = '' - Programs runnable with nix run ``. - ''; - example = lib.literalExpression '' - { - default.program = "''${config.packages.hello}/bin/hello"; - } - ''; - }; - file = ./apps.nix; -} + mkPerSystemFlakeOutput { + name = "apps"; + option = mkOption { + type = types.lazyAttrsOf appType; + default = {}; + description = '' + Programs runnable with nix run ``. + ''; + example = lib.literalExpression '' + { + default.program = "''${config.packages.hello}/bin/hello"; + } + ''; + }; + file = ./apps.nix; + } diff --git a/nix/snow/flake/modules/checks.nix b/nix/snow/flake/modules/checks.nix index 9e7ceae..a8a7280 100644 --- a/nix/snow/flake/modules/checks.nix +++ b/nix/snow/flake/modules/checks.nix @@ -1,21 +1,26 @@ -{ lib, flake-parts-lib, ... }: -let - inherit (lib) +{ + lib, + snow, + ... +}: let + inherit + (lib) mkOption types ; - inherit (flake-parts-lib) - mkTransposedPerSystemModule + inherit + (snow) + mkPerSystemFlakeOutput ; in -mkTransposedPerSystemModule { - name = "checks"; - option = mkOption { - type = types.lazyAttrsOf types.package; - default = { }; - description = '' - Derivations to be built by [`nix flake check`](https://nixos.org/manual/nix/stable/command-ref/new-cli/nix3-flake-check.html). - ''; - }; - file = ./checks.nix; -} + mkPerSystemFlakeOutput { + name = "checks"; + option = mkOption { + type = types.lazyAttrsOf types.package; + default = {}; + description = '' + Derivations to be built by [`nix flake check`](https://nixos.org/manual/nix/stable/command-ref/new-cli/nix3-flake-check.html). + ''; + }; + file = ./checks.nix; + } diff --git a/nix/snow/flake/modules/debug.nix b/nix/snow/flake/modules/debug.nix deleted file mode 100644 index 995f13b..0000000 --- a/nix/snow/flake/modules/debug.nix +++ /dev/null @@ -1,78 +0,0 @@ -{ config, flake-parts-lib, lib, options, getSystem, extendModules, ... }: -let - inherit (lib) - mapAttrs - mkIf - mkOption - optionalAttrs - types - ; - inherit (flake-parts-lib) - mkPerSystemOption - ; - - mkDebugConfig = { config, options, extendModules }: config // { - inherit config; - inherit (config) _module; - inherit options; - inherit extendModules; - }; -in -{ - options = { - debug = mkOption { - type = types.bool; - default = false; - description = '' - Whether to add the attributes `debug`, `allSystems` and `currentSystem` - to the flake output. When `true`, this allows inspection of options via - `nix repl`. - - ``` - $ nix repl - nix-repl> :lf . - nix-repl> currentSystem._module.args.pkgs.hello - «derivation /nix/store/7vf0d0j7majv1ch1xymdylyql80cn5fp-hello-2.12.1.drv» - ``` - - Each of `debug`, `allSystems.` and `currentSystem` is an - attribute set consisting of the `config` attributes, plus the extra - attributes `_module`, `config`, `options`, `extendModules`. So note that - these are not part of the `config` parameter, but are merged in for - debugging convenience. - - - `debug`: The top-level options - - `allSystems`: The `perSystem` submodule applied to the configured `systems`. - - `currentSystem`: Shortcut into `allSystems`. Only available in impure mode. - Works for arbitrary system values. - - See [Expore and debug option values](../debug.html) for more examples. - ''; - }; - perSystem = mkPerSystemOption - ({ options, config, extendModules, ... }: { - _file = ./formatter.nix; - options = { - debug = mkOption { - description = '' - Values to return in e.g. `allSystems.` when - [`debug = true`](#opt-debug). - ''; - type = types.lazyAttrsOf types.raw; - }; - }; - config = { - debug = mkDebugConfig { inherit config options extendModules; }; - }; - }); - }; - - config = mkIf config.debug { - flake = { - debug = mkDebugConfig { inherit config options extendModules; }; - allSystems = mapAttrs (_s: c: c.debug) config.allSystems; - } // optionalAttrs (builtins?currentSystem) { - currentSystem = (getSystem builtins.currentSystem).debug; - }; - }; -} diff --git a/nix/snow/flake/modules/default.nix b/nix/snow/flake/modules/default.nix new file mode 100644 index 0000000..e6914a0 --- /dev/null +++ b/nix/snow/flake/modules/default.nix @@ -0,0 +1,15 @@ +{...}: { + imports = [ + ./outputs.nix + + ./apps.nix + ./checks.nix + ./devShells.nix + ./formatter.nix + ./legacyPackages.nix + ./nixosConfigurations.nix + ./nixosModules.nix + ./overlays.nix + ./packages.nix + ]; +} diff --git a/nix/snow/flake/modules/devShells.nix b/nix/snow/flake/modules/devShells.nix index c0cc6c5..7116e6b 100644 --- a/nix/snow/flake/modules/devShells.nix +++ b/nix/snow/flake/modules/devShells.nix @@ -1,30 +1,35 @@ -{ lib, flake-parts-lib, ... }: -let - inherit (lib) +{ + lib, + snow, + ... +}: let + inherit + (lib) mkOption types literalExpression ; - inherit (flake-parts-lib) - mkTransposedPerSystemModule + inherit + (snow) + mkPerSystemFlakeOutput ; in -mkTransposedPerSystemModule { - name = "devShells"; - option = mkOption { - type = types.lazyAttrsOf types.package; - default = { }; - description = '' - An attribute set of packages to be used as shells. - [`nix develop .#`](https://nixos.org/manual/nix/stable/command-ref/new-cli/nix3-develop.html) will run `devShells.`. - ''; - example = literalExpression '' - { - default = pkgs.mkShell { - nativeBuildInputs = with pkgs; [ wget bat cargo ]; - }; - } - ''; - }; - file = ./devShells.nix; -} + mkPerSystemFlakeOutput { + name = "devShells"; + option = mkOption { + type = types.lazyAttrsOf types.package; + default = {}; + description = '' + An attribute set of packages to be used as shells. + [`nix develop .#`](https://nixos.org/manual/nix/stable/command-ref/new-cli/nix3-develop.html) will run `devShells.`. + ''; + example = literalExpression '' + { + default = pkgs.mkShell { + nativeBuildInputs = with pkgs; [ wget bat cargo ]; + }; + } + ''; + }; + file = ./devShells.nix; + } diff --git a/nix/snow/flake/modules/formatter.nix b/nix/snow/flake/modules/formatter.nix index e2959ed..44e07c2 100644 --- a/nix/snow/flake/modules/formatter.nix +++ b/nix/snow/flake/modules/formatter.nix @@ -1,52 +1,26 @@ -{ config, lib, flake-parts-lib, ... }: -let - inherit (lib) - filterAttrs - mapAttrs +{ + lib, + snow, + ... +}: let + inherit + (lib) mkOption - optionalAttrs types ; - inherit (flake-parts-lib) - mkPerSystemOption + inherit + (snow) + mkPerSystemFlakeOutput ; in -{ - options = { - flake.formatter = mkOption { - type = types.lazyAttrsOf types.package; - default = { }; + mkPerSystemFlakeOutput { + name = "formatter"; + option = mkOption { + type = types.nullOr types.package; + default = null; description = '' - An attribute set of per system a package used by [`nix fmt`](https://nixos.org/manual/nix/stable/command-ref/new-cli/nix3-fmt.html). + A package used by [`nix fmt`](https://nixos.org/manual/nix/stable/command-ref/new-cli/nix3-fmt.html). ''; }; - - perSystem = mkPerSystemOption { - _file = ./formatter.nix; - options = { - formatter = mkOption { - type = types.nullOr types.package; - default = null; - description = '' - A package used by [`nix fmt`](https://nixos.org/manual/nix/stable/command-ref/new-cli/nix3-fmt.html). - ''; - }; - }; - }; - }; - config = { - flake.formatter = - mapAttrs - (k: v: v.formatter) - (filterAttrs - (k: v: v.formatter != null) - config.allSystems - ); - - perInput = system: flake: - optionalAttrs (flake?formatter.${system}) { - formatter = flake.formatter.${system}; - }; - - }; -} + file = ./apps.nix; + } diff --git a/nix/snow/flake/modules/legacyPackages.nix b/nix/snow/flake/modules/legacyPackages.nix index fb17e14..f167c93 100644 --- a/nix/snow/flake/modules/legacyPackages.nix +++ b/nix/snow/flake/modules/legacyPackages.nix @@ -1,21 +1,26 @@ -{ lib, flake-parts-lib, ... }: -let - inherit (lib) +{ + lib, + snow, + ... +}: let + inherit + (lib) mkOption types ; - inherit (flake-parts-lib) - mkTransposedPerSystemModule + inherit + (snow) + mkPerSystemFlakeOutput ; in -mkTransposedPerSystemModule { - name = "legacyPackages"; - option = mkOption { - type = types.lazyAttrsOf types.raw; - default = { }; - description = '' - An attribute set of unmergeable values. This is also used by [`nix build .#`](https://nixos.org/manual/nix/stable/command-ref/new-cli/nix3-build.html). - ''; - }; - file = ./legacyPackages.nix; -} + mkPerSystemFlakeOutput { + name = "legacyPackages"; + option = mkOption { + type = types.lazyAttrsOf types.raw; + default = {}; + description = '' + Used for nixpkgs packages, also accessible via `nix build .#` [`nix build .#`](https://nixos.org/manual/nix/stable/command-ref/new-cli/nix3-build.html). + ''; + }; + file = ./legacyPackages.nix; + } diff --git a/nix/snow/flake/modules/moduleWithSystem.nix b/nix/snow/flake/modules/moduleWithSystem.nix deleted file mode 100644 index e5c7008..0000000 --- a/nix/snow/flake/modules/moduleWithSystem.nix +++ /dev/null @@ -1,32 +0,0 @@ -{ withSystem, ... }: -{ - config = { - _module.args = { - moduleWithSystem = - module: - - { config, ... }: - let - system = - config._module.args.system or - config._module.args.pkgs.stdenv.hostPlatform.system or - (throw "moduleWithSystem: Could not determine the configuration's system parameter for this module system application."); - - allArgs = withSystem system (args: args); - - lazyArgsPerParameter = f: builtins.mapAttrs - (k: v: allArgs.${k} or (throw "moduleWithSystem: module argument `${k}` does not exist.")) - (builtins.functionArgs f); - - # Use reflection to make the call lazy in the argument. - # Restricts args to the ones declared. - callLazily = f: a: f (lazyArgsPerParameter f); - in - { - imports = [ - (callLazily module allArgs) - ]; - }; - }; - }; -} diff --git a/nix/snow/flake/modules/nixosConfigurations.nix b/nix/snow/flake/modules/nixosConfigurations.nix index 597132d..7db8077 100644 --- a/nix/snow/flake/modules/nixosConfigurations.nix +++ b/nix/snow/flake/modules/nixosConfigurations.nix @@ -1,16 +1,15 @@ -{ lib, ... }: -let - inherit (lib) +{lib, ...}: let + inherit + (lib) mkOption types literalExpression ; -in -{ +in { options = { - flake.nixosConfigurations = mkOption { + outputs.nixosConfigurations = mkOption { type = types.lazyAttrsOf types.raw; - default = { }; + default = {}; description = '' Instantiated NixOS configurations. Used by `nixos-rebuild`. diff --git a/nix/snow/flake/modules/nixosModules.nix b/nix/snow/flake/modules/nixosModules.nix index 86ee9cc..6819570 100644 --- a/nix/snow/flake/modules/nixosModules.nix +++ b/nix/snow/flake/modules/nixosModules.nix @@ -1,20 +1,23 @@ -{ self, lib, moduleLocation, ... }: -let - inherit (lib) +{ + lib, + moduleLocation, + ... +}: let + inherit + (lib) mapAttrs mkOption types ; -in -{ +in { options = { - flake.nixosModules = mkOption { + outputs.nixosModules = mkOption { type = types.lazyAttrsOf types.deferredModule; - default = { }; + default = {}; apply = mapAttrs (k: v: { _class = "nixos"; _file = "${toString moduleLocation}#nixosModules.${k}"; - imports = [ v ]; + imports = [v]; }); description = '' NixOS modules. diff --git a/nix/snow/flake/modules/nixpkgs.nix b/nix/snow/flake/modules/nixpkgs.nix deleted file mode 100644 index 44df915..0000000 --- a/nix/snow/flake/modules/nixpkgs.nix +++ /dev/null @@ -1,26 +0,0 @@ -# -# Nixpkgs module. The only exception to the rule. -# -# Provides a `pkgs` argument in `perSystem`. -# -# Arguably, this shouldn't be in flake-parts, but in nixpkgs. -# Nixpkgs could define its own module that does this, which would be -# a more consistent UX, but for now this will do. -# -# The existence of this module does not mean that other flakes' logic -# will be accepted into flake-parts, because it's against the -# spirit of Flakes. -# -{ - config = { - perSystem = { inputs', lib, ... }: { - config = { - _module.args.pkgs = lib.mkOptionDefault ( - builtins.seq - (inputs'.nixpkgs or (throw "flake-parts: The flake does not have a `nixpkgs` input. Please add it, or set `perSystem._module.args.pkgs` yourself.")) - inputs'.nixpkgs.legacyPackages - ); - }; - }; - }; -} diff --git a/nix/snow/flake/modules/flake.nix b/nix/snow/flake/modules/outputs.nix similarity index 94% rename from nix/snow/flake/modules/flake.nix rename to nix/snow/flake/modules/outputs.nix index 871f04d..3539f5c 100644 --- a/nix/snow/flake/modules/flake.nix +++ b/nix/snow/flake/modules/outputs.nix @@ -9,7 +9,7 @@ types ; - flake = mkOption { + outputs = mkOption { type = types.submoduleWith { modules = [ { @@ -39,8 +39,7 @@ }; in { options = { - inherit flake; - output = {inherit flake;}; + inherit outputs; }; config = {inherit (config) flake;}; diff --git a/nix/snow/flake/modules/overlays.nix b/nix/snow/flake/modules/overlays.nix index 172336c..55423c2 100644 --- a/nix/snow/flake/modules/overlays.nix +++ b/nix/snow/flake/modules/overlays.nix @@ -1,19 +1,18 @@ -{ lib, ... }: -let - inherit (lib) +{lib, ...}: let + inherit + (lib) mkOption types ; -in -{ +in { options = { - flake.overlays = mkOption { + outputs.overlays = mkOption { # uniq -> ordered: https://github.com/NixOS/nixpkgs/issues/147052 # also update description when done type = types.lazyAttrsOf (types.uniq (types.functionTo (types.functionTo (types.lazyAttrsOf types.unspecified)))); # This eta expansion exists for the sole purpose of making nix flake check happy. apply = lib.mapAttrs (_k: f: final: prev: f final prev); - default = { }; + default = {}; example = lib.literalExpression '' { default = final: prev: {}; diff --git a/nix/snow/flake/modules/packages.nix b/nix/snow/flake/modules/packages.nix index 20f0071..517c758 100644 --- a/nix/snow/flake/modules/packages.nix +++ b/nix/snow/flake/modules/packages.nix @@ -1,23 +1,29 @@ -{ lib, flake-parts-lib, ... }: -let - inherit (lib) +{ + lib, + snow, + ... +}: let + inherit + (lib) mkOption types ; - inherit (flake-parts-lib) - mkTransposedPerSystemModule + + inherit + (snow) + mkPerSystemFlakeOutput ; in -mkTransposedPerSystemModule { - name = "packages"; - option = mkOption { - type = types.lazyAttrsOf types.package; - default = { }; - description = '' - An attribute set of packages to be built by [`nix build`](https://nixos.org/manual/nix/stable/command-ref/new-cli/nix3-build.html). + mkPerSystemFlakeOutput { + name = "packages"; + option = mkOption { + type = types.lazyAttrsOf types.package; + default = {}; + description = '' + An attribute set of packages to be built by [`nix build`](https://nixos.org/manual/nix/stable/command-ref/new-cli/nix3-build.html). - `nix build .#` will build `packages.`. - ''; - }; - file = ./packages.nix; -} + `nix build .#` will build `packages.`. + ''; + }; + file = ./packages.nix; + } diff --git a/nix/snow/flake/modules/perSystem.nix b/nix/snow/flake/modules/perSystem.nix deleted file mode 100644 index d4890ef..0000000 --- a/nix/snow/flake/modules/perSystem.nix +++ /dev/null @@ -1,159 +0,0 @@ -{ config, lib, flake-parts-lib, self, ... }: -let - inherit (lib) - genAttrs - mapAttrs - mkOption - types - ; - inherit (lib.strings) - escapeNixIdentifier - ; - inherit (flake-parts-lib) - mkPerSystemType - ; - - rootConfig = config; - - # Stubs for self and inputs. While it'd be possible to define aliases - # inside perSystem, that is not a general solution, and it would make - # top.config harder to discover, stretching the learning curve rather - # than flattening it. - - throwAliasError' = param: - throw '' - `${param}` (without `'`) is not a `perSystem` module argument, but a - module argument of the top level config. - - The following is an example usage of `${param}`. Note that its binding - is in the `top` parameter list, which is declared by the top level module - rather than the `perSystem` module. - - top@{ config, lib, ${param}, ... }: { - perSystem = { config, ${param}', ... }: { - # in scope here: - # - ${param} - # - ${param}' - # - config (of perSystem) - # - top.config (note the `top@` pattern) - }; - } - ''; - - throwAliasError = param: - throw '' - `${param}` is not a `perSystem` module argument, but a module argument of - the top level config. - - The following is an example usage of `${param}`. Note that its binding - is in the `top` parameter list, which is declared by the top level module - rather than the `perSystem` module. - - top@{ config, lib, ${param}, ... }: { - perSystem = { config, ... }: { - # in scope here: - # - ${param} - # - config (of perSystem) - # - top.config (note the `top@` pattern) - }; - } - ''; - - /** - We primarily use `systems` to help memoize the per system context, but that - doesn't extend to arbitrary `system`s. - For that, we use the slightly less efficient, but perfectly acceptable - `memoizeStr` function. - */ - otherMemoizedSystems = flake-parts-lib.memoizeStr config.perSystem; - -in -{ - options = { - systems = mkOption { - description = '' - All the system types to enumerate in the flake output subattributes. - - In other words, all valid values for `system` in e.g. `packages..foo`. - ''; - type = types.listOf types.str; - }; - - perInput = mkOption { - description = '' - A function that pre-processes flake inputs. - - It is called for users of `perSystem` such that `inputs'.''${name} = config.perInput system inputs.''${name}`. - - This is used for [`inputs'`](../module-arguments.html#inputs) and [`self'`](../module-arguments.html#self). - - The attributes returned by the `perInput` function definitions are merged into a single namespace (per input), - so each module should return an attribute set with usually only one or two predictable attribute names. Otherwise, - the `inputs'` namespace gets polluted. - ''; - type = types.functionTo (types.functionTo (types.lazyAttrsOf types.unspecified)); - }; - - perSystem = mkOption { - description = '' - A function from system to flake-like attributes omitting the `` attribute. - - Modules defined here have access to the suboptions and [some convenient module arguments](../module-arguments.html). - ''; - type = mkPerSystemType ({ config, system, ... }: { - _file = ./perSystem.nix; - config = { - _module.args.inputs' = - mapAttrs - (inputName: input: - builtins.addErrorContext "while retrieving system-dependent attributes for input ${escapeNixIdentifier inputName}" ( - if input._type or null == "flake" - then rootConfig.perInput system input - else - throw "Trying to retrieve system-dependent attributes for input ${escapeNixIdentifier inputName}, but this input is not a flake. Perhaps flake = false was added to the input declarations by mistake, or you meant to use a different input, or you meant to use plain old inputs, not inputs'." - ) - ) - self.inputs; - _module.args.self' = - builtins.addErrorContext "while retrieving system-dependent attributes for a flake's own outputs" ( - rootConfig.perInput system self - ); - - # Custom error messages - _module.args.self = throwAliasError' "self"; - _module.args.inputs = throwAliasError' "inputs"; - _module.args.getSystem = throwAliasError "getSystem"; - _module.args.withSystem = throwAliasError "withSystem"; - _module.args.moduleWithSystem = throwAliasError "moduleWithSystem"; - }; - }); - apply = modules: system: - (lib.evalModules { - inherit modules; - prefix = [ "perSystem" system ]; - specialArgs = { - inherit system; - }; - class = "perSystem"; - }).config; - }; - - allSystems = mkOption { - type = types.lazyAttrsOf types.unspecified; - description = "The system-specific config for each of systems."; - internal = true; - }; - }; - - config = { - allSystems = genAttrs config.systems config.perSystem; - _module.args.getSystem = system: config.allSystems.${system} or (otherMemoizedSystems system); - - # The warning is there for a reason. Only use this in situations where the - # performance cost has already been incurred, such as in `flakeModules.easyOverlay`, - # where we run in the context of an overlay, and the performance cost of the - # extra `pkgs` makes the cost of running `perSystem` probably negligible. - _module.args.getSystemIgnoreWarning = system: config.allSystems.${system} or (config.perSystem system); - }; - -} diff --git a/nix/snow/flake/modules/transposition.nix b/nix/snow/flake/modules/transposition.nix deleted file mode 100644 index d532e76..0000000 --- a/nix/snow/flake/modules/transposition.nix +++ /dev/null @@ -1,132 +0,0 @@ -{ config, lib, flake-parts-lib, ... }: - -let - inherit (lib) - filterAttrs - mapAttrs - mkOption - types - ; - inherit (lib.strings) - escapeNixIdentifier - ; - - transpositionModule = { - options = { - adHoc = mkOption { - type = types.bool; - default = false; - description = '' - Whether to provide a stub option declaration for {option}`perSystem.`. - - The stub option declaration does not support merging and lacks - documentation, so you are recommended to declare the {option}`perSystem.` - option yourself and avoid {option}`adHoc`. - ''; - }; - }; - }; - - perInputAttributeError = { flake, attrName, system, attrConfig }: - # This uses flake.outPath for lack of a better identifier. - # Consider adding a perInput variation that has a normally-redundant argument for the input name. - # Tested manually with - # perSystem = { inputs', ... }: { - # packages.extra = inputs'.nixpkgs.extra; - # packages.default = inputs'.nixpkgs.packages.default; - # packages.veryWrong = (top.config.perInput "x86_64-linux" inputs'.nixpkgs.legacyPackages.hello).packages.default; - # }; - # transposition.extra = {}; - let - attrPath = "${escapeNixIdentifier attrName}.${escapeNixIdentifier system}"; - flakeIdentifier = - if flake._type or null != "flake" - then - throw "An attempt was made to access attribute ${attrPath} on a value that's supposed to be a flake, but may not be a proper flake." - else - builtins.addErrorContext "while trying to find out how to describe what is supposedly a flake, whose attribute ${attrPath} was accessed but does not exist" ( - toString flake.outPath - ); - # This ought to be generalized by extending attrConfig, but this is the only known and common mistake for now. - alternateAttrNameHint = - if attrName == "packages" && flake?legacyPackages - then # Unfortunately we can't just switch them out, because that will put packages *sets* where single packages are expected in user code, resulting in potentially much worse and more confusing errors down the line. - "\nIt does define legacyPackages; try that instead?" - else ""; - in - if flake?${attrName} - then - throw '' - Attempt to access ${attrPath} of flake ${flakeIdentifier}, but it does not have it. - It does have attribute ${escapeNixIdentifier attrName}, so it appears that it does not support system type ${escapeNixIdentifier system}. - '' - else - throw '' - Attempt to access ${attrPath} of flake ${flakeIdentifier}, but it does not have attribute ${escapeNixIdentifier attrName}.${alternateAttrNameHint} - ''; - - -in -{ - options = { - transposition = lib.mkOption { - description = '' - A helper that defines transposed attributes in the flake outputs. - - When you define `transposition.foo = { };`, definitions are added to the effect of (pseudo-code): - - ```nix - flake.foo.''${system} = (perSystem system).foo; - perInput = system: inputFlake: inputFlake.foo.''${system}; - ``` - - Transposition is the operation that swaps the indices of a data structure. - Here it refers specifically to the transposition between - - ```plain - perSystem: .''${system}.''${attribute} - outputs: .''${attribute}.''${system} - ``` - - It also defines the reverse operation in [{option}`perInput`](#opt-perInput). - ''; - type = - types.lazyAttrsOf - (types.submoduleWith { modules = [ transpositionModule ]; }); - }; - }; - - config = { - flake = - lib.mapAttrs - (attrName: attrConfig: - mapAttrs - (system: v: v.${attrName} or ( - abort '' - Could not find option ${attrName} in the perSystem module. It is required to declare such an option whenever transposition. is defined (and in this instance is ${attrName}). - '')) - config.allSystems - ) - config.transposition; - - perInput = - system: flake: - mapAttrs - (attrName: attrConfig: - flake.${attrName}.${system} or ( - throw (perInputAttributeError { inherit system flake attrName attrConfig; }) - ) - ) - config.transposition; - - perSystem = { - options = - mapAttrs - (k: v: lib.mkOption { }) - (filterAttrs - (k: v: v.adHoc) - config.transposition - ); - }; - }; -} diff --git a/nix/snow/flake/modules/withSystem.nix b/nix/snow/flake/modules/withSystem.nix deleted file mode 100644 index 161eece..0000000 --- a/nix/snow/flake/modules/withSystem.nix +++ /dev/null @@ -1,37 +0,0 @@ -{ lib, flake-parts-lib, getSystem, ... }: -let - inherit (lib) - mkOption - types - ; - inherit (flake-parts-lib) - mkPerSystemOption - ; -in -{ - options = { - perSystem = mkPerSystemOption ({ config, options, specialArgs, ... }: { - _file = ./perSystem.nix; - options = { - allModuleArgs = mkOption { - type = types.lazyAttrsOf (types.raw or types.unspecified); - internal = true; - readOnly = true; - description = "Internal option that exposes _module.args, for use by withSystem."; - }; - }; - config = { - allModuleArgs = config._module.args // specialArgs // { inherit config options; }; - }; - }); - }; - - config = { - _module.args = { - withSystem = - system: f: - f - (getSystem system).allModuleArgs; - }; - }; -}