summaryrefslogtreecommitdiffstats
path: root/nixos/lib
diff options
context:
space:
mode:
authorThomas Strobel <ts468@cam.ac.uk>2016-02-20 01:47:01 +0100
committerThomas Strobel <ts468@cam.ac.uk>2016-02-29 01:09:00 +0100
commitcad8957eabcbf73062226d28366fd446c15c8737 (patch)
tree0299e96391c14f612e7bd1cf3b2274198425fd61 /nixos/lib
parentc483224c82c8e94324c03576e64c5dfbf16bd2f8 (diff)
Add the tool "nixos-typecheck" that can check an option declaration to:
- Enforce that an option declaration has a "defaultText" if and only if the type of the option derives from "package", "packageSet" or "nixpkgsConfig" and if a "default" attribute is defined. - Enforce that the value of the "example" attribute is wrapped with "literalExample" if the type of the option derives from "package", "packageSet" or "nixpkgsConfig". - Warn if a "defaultText" is defined in an option declaration if the type of the option does not derive from "package", "packageSet" or "nixpkgsConfig". - Warn if no "type" is defined in an option declaration.
Diffstat (limited to 'nixos/lib')
-rw-r--r--nixos/lib/eval-config.nix15
-rw-r--r--nixos/lib/typechecker.nix91
2 files changed, 103 insertions, 3 deletions
diff --git a/nixos/lib/eval-config.nix b/nixos/lib/eval-config.nix
index a87b285c5b7b..79890e0add7d 100644
--- a/nixos/lib/eval-config.nix
+++ b/nixos/lib/eval-config.nix
@@ -20,8 +20,13 @@
, # !!! See comment about args in lib/modules.nix
specialArgs ? {}
, modules
+, # Pass through a configuration of the internal modules declared
+ # in lib/modules.nix.
+ _module ? {}
+, # !!! See comment about typeInference in lib/modules.nix
+ typeInference ? null
, # !!! See comment about check in lib/modules.nix
- check ? true
+ check ? null
, prefix ? []
, lib ? import ../../lib
}:
@@ -41,13 +46,17 @@ let
};
};
+ internalModule = { _module = (_module
+ // (if isNull check then {} else { inherit check; })
+ // (if isNull typeInference then {} else { inherit typeInference; })); };
+
in rec {
# Merge the option definitions in all modules, forming the full
# system configuration.
inherit (lib.evalModules {
- inherit prefix check;
- modules = modules ++ extraModules ++ baseModules ++ [ pkgsModule ];
+ inherit prefix;
+ modules = modules ++ extraModules ++ baseModules ++ [ pkgsModule ] ++ [ internalModule ];
args = extraArgs;
specialArgs = { modulesPath = ../modules; } // specialArgs;
}) config options;
diff --git a/nixos/lib/typechecker.nix b/nixos/lib/typechecker.nix
new file mode 100644
index 000000000000..b4d8277f8fe9
--- /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"));
+
+ };
+
+}
+
+
+
+
+