about summary refs log tree commit diff
diff options
context:
space:
mode:
authorCole Helbling <cole.e.helbling@outlook.com>2022-12-02 13:19:35 -0800
committerCole Helbling <cole.e.helbling@outlook.com>2022-12-08 13:50:05 -0800
commitdce9add02b24d8ee02a2afb79ce972a9ebc0aaa3 (patch)
tree5048f9da0366c3a35accd7267cc497625f0f6b3f
parent38e50898148a137bfbd97ed9acf52b87af37f19e (diff)
nixos/activation/bootspec: refactor the generator script
We separate the different steps (injecting the toplevel and injecting
the specialisations) so that it's easy to document what each snippet is
actually doing.
-rw-r--r--nixos/modules/system/activation/bootspec.nix51
1 files changed, 32 insertions, 19 deletions
diff --git a/nixos/modules/system/activation/bootspec.nix b/nixos/modules/system/activation/bootspec.nix
index 59b9f47339653..99cc6f5374977 100644
--- a/nixos/modules/system/activation/bootspec.nix
+++ b/nixos/modules/system/activation/bootspec.nix
@@ -31,29 +31,42 @@ let
 
       generator =
         let
-          specialisationLoader = (lib.mapAttrsToList
-            (childName: childToplevel: lib.escapeShellArgs [ "--slurpfile" childName "${childToplevel}/bootspec/${filename}" ])
-            children);
+          # NOTE: Be careful to not introduce excess newlines at the end of the
+          # injectors, as that may affect the pipes and redirects.
+
+          # Inject toplevel and init into the bootspec.
+          # This can only be done here because we *cannot* depend on $out
+          # referring to the toplevel, except by living in the toplevel itself.
+          toplevelInjector = lib.escapeShellArgs [
+            "${pkgs.jq}/bin/jq"
+            ''
+              .v1.toplevel = $toplevel |
+              .v1.init = $init
+            ''
+            "--sort-keys"
+            "--arg" "toplevel" "$out"
+            "--arg" "init" "$out/init"
+          ] + " < ${json}";
+
+          # We slurp all specialisations and inject them as values, such that
+          # `.specialisations.${name}` embeds the specialisation's bootspec
+          # document.
+          specialisationInjector =
+            let
+              specialisationLoader = (lib.mapAttrsToList
+                (childName: childToplevel: lib.escapeShellArgs [ "--slurpfile" childName "${childToplevel}/bootspec/${filename}" ])
+                children);
+            in
+            lib.escapeShellArgs [
+              "${pkgs.jq}/bin/jq"
+              "--sort-keys"
+              ".v1.specialisation = ($ARGS.named | map_values(. | first | .v1))"
+            ] + " ${lib.concatStringsSep " " specialisationLoader}";
         in
         ''
           mkdir -p $out/bootspec
 
-          # Inject toplevel and init in the bootspec.
-          # This can be done only here because we *cannot* depend on $out, except
-          # by living in $out itself.
-          ${pkgs.jq}/bin/jq '
-            .v1.toplevel = $toplevel |
-            .v1.init = $init
-            ' \
-            --sort-keys \
-            --arg toplevel "$out" \
-            --arg init "$out/init" \
-            < ${json} \
-            | ${pkgs.jq}/bin/jq \
-              --sort-keys \
-              '.v1.specialisation = ($ARGS.named | map_values(. | first | .v1))' \
-              ${lib.concatStringsSep " " specialisationLoader} \
-            > $out/bootspec/${filename}
+          ${toplevelInjector} | ${specialisationInjector} > $out/bootspec/${filename}
         '';
 
       validator = pkgs.writeCueValidator ./bootspec.cue {