Skip to content
106 changes: 63 additions & 43 deletions default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -22,45 +22,9 @@ rec {
sources
;

rawNixosModules = lib'.flattenAttrs "." (
with lib;
foldl recursiveUpdate { } (attrValues (mapAttrs (_: project: project.nixos.modules) projects))
);

nixosModules = {
# The default module adds the default overlay on top of Nixpkgs.
# This is so that `ngipkgs` can be used alongside `nixpkgs` in a configuration.
default.nixpkgs.overlays = [ overlays.default ];
} // rawNixosModules;

optionsDoc =
let
nixosSystem =
args:
import (sources.nixpkgs + "/nixos/lib/eval-config.nix") (
{
inherit lib;
system = null;
}
// args
);
in
pkgs.nixosOptionsDoc {
options =
(nixosSystem {
inherit system;
modules = [
{
networking = {
domain = "invalid";
hostName = "options";
};

system.stateVersion = "23.05";
}
] ++ lib.attrValues nixosModules;
}).options;
};
optionsDoc = pkgs.nixosOptionsDoc {
inherit (evaluated-modules) options;
};

# TODO: we should be exporting our custom functions as `lib`, but refactoring
# this to use `pkgs.lib` everywhere is a lot of movement
Expand All @@ -77,6 +41,27 @@ rec {
in
f "";

# Recursively evaluate attributes for an attribute set.
# Coupled with an evaluated nixos configuration, this presents an efficient
# way for checking module types.
forceEvalRecursive =
attrs:
lib.mapAttrsRecursive (
n: v:
if lib.isList v then
map (
i:
# if eval fails
if !(builtins.tryEval i).success then
# recursively recurse into attrsets
if lib.isAttrs i then lib'.forceEvalRecursive i else (builtins.tryEval i).success
else
(builtins.tryEval i).success
) v
else
(builtins.tryEval v).success
) attrs;

# get the path of NixOS module from string
# example:
# lib'.moduleLocFromOptionString "services.ntpd-rs"
Expand Down Expand Up @@ -141,15 +126,50 @@ rec {
}
// foldl recursiveUpdate { } (map (project: project.nixos.modules) (attrValues projects));

ngipkgsModules = lib.filter (m: m != null) (
lib.mapAttrsToList (name: value: value) nixos-modules.services
++ lib.mapAttrsToList (name: value: value) nixos-modules.programs
);

nixosModules = import "${sources.nixpkgs}/nixos/modules/module-list.nix";
extendedNixosModules =
with lib;
[
nixos-modules.ngipkgs
# Allow using packages from `ngipkgs` to be used alongside regular `pkgs`
{
nixpkgs.overlays = [ overlays.default ];
}
# TODO: needed for examples that use sops (like Pretalx)
sops-nix
]
++ attrValues nixos-modules.programs
++ attrValues nixos-modules.services;
++ ngipkgsModules
++ nixosModules;

evaluated-modules = lib.evalModules {
class = "nixos";
modules = [
{
nixpkgs.hostPlatform = { inherit system; };

networking = {
domain = "invalid";
hostName = "options";
};

# faster eval time
documentation.nixos.enable = false;
documentation.man.generateCaches = false;

system.stateVersion = "23.05";
}
raw-projects # for checks
] ++ extendedNixosModules;
specialArgs = {
modulesPath = "${sources.nixpkgs}/nixos/modules";
};
};

# recursively evaluates each attribute for all projects
check-projects = lib'.forceEvalRecursive evaluated-modules.config.projects;

ngipkgs = import ./pkgs/by-name { inherit pkgs lib dream2nix; };

Expand Down
13 changes: 7 additions & 6 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,6 @@

overlay = classic'.overlays.default;

# Note that modules and examples are system-agnostic, so import them first.
# TODO: get rid of these, it's extremely confusing to import the seemingly same thing twice
rawNgiProjects = classic'.projects;

toplevel = machine: machine.config.system.build.toplevel;

# Finally, define the system-agnostic outputs.
Expand All @@ -57,7 +53,7 @@
makemake = import ./infra/makemake { inherit inputs; };
};

inherit (classic') nixosModules;
nixosModules = classic'.ngipkgsModules;

# Overlays a package set (e.g. Nixpkgs) with the packages defined in this flake.
overlays.default = overlay;
Expand Down Expand Up @@ -118,8 +114,13 @@
checksForNixosTests = concatMapAttrs (testName: test: {
"projects/${projectName}/nixos/tests/${testName}" = test;
}) project.nixos.tests;
checksForNixosTypes = {
"projects/${projectName}/nixos/check" = pkgs.writeText "${projectName}-eval-check" (
lib.strings.toJSON classic.check-projects.${projectName}
);
};
in
checksForNixosTests;
checksForNixosTests // checksForNixosTypes;
in
concatMapAttrs checksForProject classic.projects;

Expand Down