summary refs log tree commit diff
path: root/nixos/lib/typechecker.nix
diff options
context:
space:
mode:
Diffstat (limited to 'nixos/lib/typechecker.nix')
-rw-r--r--nixos/lib/typechecker.nix91
1 files changed, 91 insertions, 0 deletions
diff --git a/nixos/lib/typechecker.nix b/nixos/lib/typechecker.nix
new file mode 100644
index 00000000000..b4d8277f8fe
--- /dev/null
+++ b/nixos/lib/typechecker.nix
@@ -0,0 +1,91 @@
+{ config, lib, pkgs, baseModules, ... }:
+
+with pkgs;
+with pkgs.lib;
+
+let
+
+  optionsSpecs = inferenceMode:
+    let
+      versionModule =
+        { system.nixosVersionSuffix = config.system.nixosVersionSuffix;
+          system.nixosRevision = config.system.nixosRevision;
+          nixpkgs.system = config.nixpkgs.system;
+        };
+
+      internalModule = { _module = config._module; } // (if isNull inferenceMode then {} else { _module.typeInference = mkForce inferenceMode; });
+
+      eval = evalModules {
+        modules = [ versionModule ] ++ baseModules ++ [ internalModule ];
+        args = (config._module.args) // { modules = [ ]; };
+      };
+
+      # Remove invisible and internal options.
+      optionsSpecs' = filter (opt: opt.visible && !opt.internal) (optionAttrSetToParseableSpecifications config._module eval.options);
+
+      # INFO: Please add 'defaultText' or 'literalExample' to the option
+      #       definition to avoid this exception!
+      substFunction = key: decls: x:
+        if builtins.isAttrs x then mapAttrs (name: substFunction key decls) x
+        else if builtins.isList x then map (substFunction key decls) x
+        else if builtins.isFunction x then throw "Found an unexpected <function> in ${key} declared in ${concatStringsSep " and " decls}."
+        else x;
+
+      prefix = toString ../..;
+
+      stripPrefix = fn:
+        if substring 0 (stringLength prefix) fn == prefix then
+          substring (stringLength prefix + 1) 1000 fn
+        else
+          fn;
+
+      # Clean up declaration sites to not refer to the NixOS source tree.
+      cleanupOptions = x: flip map x (opt:
+        let substFunction' = y: substFunction opt.name opt.declarations y;
+        in opt
+           // { declarations = map (fn: stripPrefix fn) opt.declarations; }
+           // optionalAttrs (opt ? example) { example = substFunction' opt.example; }
+           // optionalAttrs (opt ? default) { default = substFunction' opt.default; }
+           // optionalAttrs (opt ? type) { type = substFunction' opt.type; });
+
+    in
+      cleanupOptions optionsSpecs';
+
+in
+
+{
+
+  system.build.typechecker = {
+
+    # The NixOS options as machine readable specifications in JSON format.
+    specifications = stdenv.mkDerivation {
+      name = "options-specs-json";
+
+      buildCommand = ''
+        # Export list of options in different format.
+        dst=$out/share/doc/nixos
+        mkdir -p $dst
+
+        cp ${builtins.toFile "options.json" (builtins.unsafeDiscardStringContext (builtins.toJSON
+          (listToAttrs (map (o: { name = o.name; value = removeAttrs o ["name" "visible" "internal"]; }) (optionsSpecs null)))))
+        } $dst/options-specs.json
+
+        mkdir -p $out/nix-support
+        echo "file json $dst/options-specs.json" >> $out/nix-support/hydra-build-products
+      ''; # */
+
+      meta.description = "List of NixOS options specifications in JSON format";
+    };
+
+    silent = listToAttrs (map (o: { name = o.name; value = removeAttrs o ["name" "visible" "internal"]; }) (optionsSpecs "silent"));
+    printAll = listToAttrs (map (o: { name = o.name; value = removeAttrs o ["name" "visible" "internal"]; }) (optionsSpecs "printAll"));
+    printUnspecified = listToAttrs (map (o: { name = o.name; value = removeAttrs o ["name" "visible" "internal"]; }) (optionsSpecs "printUnspecified"));
+
+  };
+
+}
+
+
+
+
+