[Nix-dev] first hacky attempts to create option summary

Marc Weber marco-oweber at gmx.de
Tue Mar 10 01:37:47 CET 2009


Hi,

I've tried generating some option summary documentations..
diff is attached. You can also checkout the t/option-summary branch from
git://mawercer.de/nixos.
configuration-text and configuration-xml just output the text to stdout so that
you can view it in your favourite way (editor, less ..)

I've pasted the first 40 lines of the text below.
However I've had various problems:

xml:
  max output level depth 3 (you'll get to many arguments (long?) to for /bin/sh)
  still ugly

text:
  max output level depth 4 (you'll get exit status 1, no error message (?))
  still ugly

I've tried passing the text by env var:

    docXML = pkgs.writeText "configuration.nix-doc" ''
        this should be a real man page one day.. Its just a plain text file for now.
        It tells you about all options availible in /etc/nixos/configuration.nix.
        It is automatically generated by nixos-rebulid to reflect your current system setup
        and work in progress.. so don't but fix it :-)
        
        TODO: Add another man page which also contains the files defining the options.
              use some other formatting or such..
        
        ${declToXML optionDeclarations}
      '';

So I still have to do some more investigation to figure out which is the best
way to pass such a long argument and get it into a file which can be processed
by another tool to generate prettier man page (or another target document..?)

Marc Weber

text version (generated in nix language) :
 ======================================== ======================================== ========================================
  this should be a real man page one day.. Its just a plain text file for now.
  It tells you about all options availible in /etc/nixos/configuration.nix.
  It is automatically generated by nixos-rebulid to reflect your current system setup
  and work in progress.. so don't but fix it :-)

  TODO: Add another man page which also contains the files defining the options.
        use some other formatting or such..

   availible options for configuration.nix
   +- boot
     +- (type option): .boot.bootMount
       +- apply : is a function
       +- default : string 
       +- description : string 
            If the system partition may be wiped on reinstall, it is better
            to have /boot on a small partition. To do it, we need to explain
            to GRUB where the kernels live. Specify the partition here (in 
            GRUB notation.
          
       +- example : string (hd0,0)
       +- merge : is a function
       +- name : string boot.bootMount
      
     +- (type option): .boot.configurationLimit
       +- apply : is a function
       +- default : unkown thing
       +- description : string 
            Maximum of configurations in boot menu. GRUB has problems when
            there are too many entries.
          
       +- example : unkown thing


xml version (generated in nix language) :
 ======================================== ======================================== ========================================
  this should be a real man page one day.. Its just a plain text file for now.
  It tells you about all options availible in /etc/nixos/configuration.nix.
  It is automatically generated by nixos-rebulid to reflect your current system setup
  and work in progress.. so don't but fix it :-)

  TODO: Add another man page which also contains the files defining the options.
        use some other formatting or such..

  <?xml version='1.0' encoding='utf-8'?>
  <expr>
    <attrs>
      <attr name="boot">
        <attrs>
          <attr name="bootMount">
            <attrs>
              <attr name="_type">
                <list>
                </list>
              </attr>
              <attr name="apply">
                <list>
                </list>
              </attr>
              <attr name="default">
                <list>
                </list>
              </attr>
              <attr name="description">
                <list>
                </list>
              </attr>
              <attr name="example">
                <list>
                </list>
              </attr>
              <attr name="merge">
                <list>
                </list>
              </attr>
              <attr name="name">
                <list>


diff against fix-style :
 ======================================== ======================================== ========================================

diff --git a/system/options.nix b/system/options.nix
index 68cad69..95e7f44 100644
--- a/system/options.nix
+++ b/system/options.nix
@@ -384,6 +384,7 @@ in
 
     # system
     (import ../system/system-options.nix)
+    (import ../system/system-man-pages.nix)
     (import ../system/activate-configuration.nix)
     (import ../upstart-jobs/default.nix)
 
diff --git a/system/system-man-pages.nix b/system/system-man-pages.nix
new file mode 100644
index 0000000..abfc791
--- /dev/null
+++ b/system/system-man-pages.nix
@@ -0,0 +1,122 @@
+{pkgs, config, ...}:
+
+###### interface
+let
+  inherit (pkgs.lib) mkOption mkIf typeOf;
+  inherit (config.system) optionDeclarations;
+
+in
+
+###### implementation
+
+# for now there is only the "man configuration.nix" page..
+# I'd like to add a man nixos-beginners or such as well.
+# which would contain faq answers..
+
+let
+  inherit (builtins) isAttrs isFunction isString isList toString removeAttrs sub;
+  inherit (pkgs.lib) mapRecordFlatten concatLists concatStringsSep mapAttrs;
+
+  # simple tree like visualization of the option declarations..
+  # is the xml output prettier? Would have been faster
+  traverse = depth : path : name : prefix : prefixContinuation : thing :
+    if depth == 0 then []
+    else if isAttrs thing then
+      if (thing ? outPath) then
+        ["${prefix} ${name} : is a derivation with name ${thing.name}"]
+      else let t = typeOf thing; in
+        if t != "" then
+          ["${prefix} (type ${t}): ${path}"]
+          ++ concatLists (
+              mapRecordFlatten (a : v : traverse (sub depth 1) "${path}.${a}" a 
+                                  "${prefixContinuation} +-"  "${prefixContinuation}  " v
+                               ) (removeAttrs thing ["_type"])
+             )
+          ++ [prefixContinuation]
+        else
+          ["${prefix} ${name}"]
+          ++ concatLists (
+              mapRecordFlatten (a : v : traverse (sub depth 1) "${path}.${a}" a 
+                                  "${prefixContinuation} +-"  "${prefixContinuation}  " v
+                               ) thing
+             )
+          ++ [prefixContinuation]
+    else if isString thing then ["${prefix} ${name} : string ${thing}"]
+    else if isFunction thing then ["${prefix} ${name} : is a function"]
+    else if isList thing then
+          ["${prefix} ${name} (list)"]
+          ++ concatLists (
+                map (i : traverse (sub depth 1) "" "" "${prefixContinuation} *" "${prefixContinuation} " i) thing
+              )
+          ++ [prefixContinuation]
+    else ["${prefix} ${name} : unkown thing"];
+
+  declToStr = decls : concatStringsSep "\n" 
+          /* you can't set depth to 5! */
+          (traverse 4 "" "availible options for configuration.nix"
+                    "" "" decls);
+
+  declToXML = decls : 
+    let f = depth : thing :
+      if depth == 0 then []
+      else if isAttrs thing then
+        mapAttrs (a : v: f (sub depth 1) v) thing
+      else if isString thing then thing
+      else if isFunction thing then "a function"
+      else if isList thing then map (i : f (sub depth 1) i) thing
+      else thing;
+    in builtins.toXML (f 3 decls);
+
+ docText = pkgs.writeText "configuration.nix-doc" ''
+      this should be a real man page one day.. Its just a plain text file for now.
+      It tells you about all options availible in /etc/nixos/configuration.nix.
+      It is automatically generated by nixos-rebulid to reflect your current system setup
+      and work in progress.. so don't but fix it :-)
+      
+      TODO: Add another man page which also contains the files defining the options.
+            use some other formatting or such..
+      
+      ${declToStr optionDeclarations}
+    '';
+
+  docXML = pkgs.writeText "configuration.nix-doc" ''
+      this should be a real man page one day.. Its just a plain text file for now.
+      It tells you about all options availible in /etc/nixos/configuration.nix.
+      It is automatically generated by nixos-rebulid to reflect your current system setup
+      and work in progress.. so don't but fix it :-)
+      
+      TODO: Add another man page which also contains the files defining the options.
+            use some other formatting or such..
+      
+      ${declToXML optionDeclarations}
+    '';
+
+  configurationText = pkgs.writeTextFile {
+    name = "configuration-text";
+    executable = true;
+    destination = "/bin/configuration-text";
+    text = ''
+    #!/bin/sh
+    cat ${docText}
+    '' ;
+  };
+  configurationXML = pkgs.writeTextFile {
+    name = "configuration-xml";
+    executable = true;
+    destination = "/bin/configuration-xml";
+    text = ''
+    #!/bin/sh
+    cat ${docXML}
+    '' ;
+  };
+
+in
+
+{
+
+  environment = {
+    # trace for convinince...
+    extraPackages = [ configurationText configurationXML ];
+  };
+
+}
diff --git a/system/system.nix b/system/system.nix
index 570ba91..31f2fa8 100644
--- a/system/system.nix
+++ b/system/system.nix
@@ -4,12 +4,14 @@
 , nixpkgs ? null
 }:
 
+
 rec {
 
   configComponents = [
     configuration
     (import ./options.nix)
     systemPathList
+    optionDeclarationComponent
   ];
 
   # Make a configuration object from which we can retrieve option
@@ -25,6 +27,17 @@ rec {
       pkgs configComponents
       config;
 
+
+  # pass the declaration options to build the man configuration.nix file based on it
+  optionDeclarationComponent = {
+    system = {
+      optionDeclarations = pkgs.lib.mkOption {
+        default = optionDeclarations; # from system/system.nix
+        merge = l: throw "Are you kidding, this is a system option guy!";
+      };
+    };
+  };
+
   pkgs = if nixpkgs == null then 
     import "${nixpkgsPath}/pkgs/top-level/all-packages.nix" {system = platform;}
   else nixpkgs;




More information about the nix-dev mailing list