diff options
author | Nicolas Pierron <nicolas.b.pierron@gmail.com> | 2009-09-28 18:26:07 +0000 |
---|---|---|
committer | Nicolas Pierron <nicolas.b.pierron@gmail.com> | 2009-09-28 18:26:07 +0000 |
commit | bd41c01bfe45bdc20f85632b5ee35879ddd4584f (patch) | |
tree | 0dd540b19b4536315aa492d15482bf112ea272d1 /maintainers/option-usages.nix | |
parent | 373445c410fedf111d8239a652d9672885da8f80 (diff) | |
download | nixpkgs-bd41c01bfe45bdc20f85632b5ee35879ddd4584f.tar nixpkgs-bd41c01bfe45bdc20f85632b5ee35879ddd4584f.tar.gz nixpkgs-bd41c01bfe45bdc20f85632b5ee35879ddd4584f.tar.bz2 nixpkgs-bd41c01bfe45bdc20f85632b5ee35879ddd4584f.tar.lz nixpkgs-bd41c01bfe45bdc20f85632b5ee35879ddd4584f.tar.xz nixpkgs-bd41c01bfe45bdc20f85632b5ee35879ddd4584f.tar.zst nixpkgs-bd41c01bfe45bdc20f85632b5ee35879ddd4584f.zip |
Add a nix expression which generate a graph inside a pdf to display option
usages. svn path=/nixos/trunk/; revision=17483
Diffstat (limited to 'maintainers/option-usages.nix')
-rw-r--r-- | maintainers/option-usages.nix | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/maintainers/option-usages.nix b/maintainers/option-usages.nix new file mode 100644 index 00000000000..6ddc6e9db60 --- /dev/null +++ b/maintainers/option-usages.nix @@ -0,0 +1,131 @@ +{ configuration ? import ../lib/from-env.nix "NIXOS_CONFIG" /etc/nixos/configuration.nix + +# []: display all options +# [<option names>]: display the selected options +, displayOptions ? [ + "hardware.pcmcia.enable" + "environment.systemPackages" + "boot.kernelModules" + "services.udev.packages" + "jobs" + "environment.etc" + "system.activationScripts" + ] +}: + +# This file is used to generate a dot graph which contains all options and +# there dependencies to track problems and their sources. + +let + + evalFun = { + extraArgs ? {} + }: import ../lib/eval-config.nix { + modules = [ configuration ]; + inherit extraArgs; + }; + + eval = evalFun {}; + inherit (eval) pkgs; + + reportNewFailures = old: new: with pkgs.lib; + let + filterChanges = + filter ({fst, snd}: + !(fst.config.success -> snd.config.success) + ); + + keepNames = + map ({fst, snd}: + assert fst.name == snd.name; snd.name + ); + in + keepNames ( + filterChanges ( + zipLists (collect isOption old) (collect isOption new) + ) + ); + + + mkProtect = name: value: { _type = "protect"; inherit name value; }; + isProtected = attr: (pkgs.lib.typeOf attr) == "protect"; + + getName = set: with pkgs.lib; + if isProtected set then + set.name + else + getName (head (attrValues set)); + + rmProtect = set: with pkgs.lib; + if isProtected set then + set.value + else + mapAttrs (n: rmProtect) set; + + # Create a list of modules where each module contains only one failling + # options. + introspectionModules = with pkgs.lib; + let + genericFun = f: set: + fold (name: rest: + (map (v: + listToAttrs [(nameValuePair name v)] + ) (f (getAttr name set))) + ++ rest + ) [] (attrNames set); + + addIntrospection = opt: mkProtect opt.name ( + throw "Usage introspection of '${opt.name}' by forced failure." + ); + + f = v: + if isOption v then + [(addIntrospection v)] + else + genericFun f v; + in + genericFun f eval.options; + + overrideConfig = override: with pkgs.lib; + let f = configs: + zip (n: v: + if tail v == [] || isProtected (head v) then + head v + else + f v + ) configs; + in + f [ override eval.config ]; + + + graph = with pkgs.lib; + map (thrower: { + option = getName thrower; + usedBy = reportNewFailures eval.options (evalFun { + extraArgs = { + config = overrideConfig (rmProtect thrower); + }; + }).options; + }) introspectionModules; + + graphToDot = graph: with pkgs.lib; '' + digraph "Option Usages" { + ${concatMapStrings ({option, usedBy}: + assert __trace option true; + if displayOptions == [] || elem option displayOptions then + concatMapStrings (user: '' + "${option}" -> "${user}"'' + ) usedBy + else "" + ) graph} + } + ''; + +in + +pkgs.texFunctions.dot2pdf { + dotGraph = pkgs.writeTextFile { + name = "option_usages.dot"; + text = graphToDot graph; + }; +} |