summary refs log tree commit diff
path: root/pkgs
diff options
context:
space:
mode:
authorNicolas Pierron <nicolas.b.pierron@gmail.com>2009-07-06 16:20:05 +0000
committerNicolas Pierron <nicolas.b.pierron@gmail.com>2009-07-06 16:20:05 +0000
commitc49dddb1ab2bed5c4761725c16afe165f717d7ee (patch)
tree39a8eb46e5879d24af497db1e2a38d7c80cf72e9 /pkgs
parenta89f3bca50664ff902d857b8696d7fecf236878f (diff)
downloadnixpkgs-c49dddb1ab2bed5c4761725c16afe165f717d7ee.tar
nixpkgs-c49dddb1ab2bed5c4761725c16afe165f717d7ee.tar.gz
nixpkgs-c49dddb1ab2bed5c4761725c16afe165f717d7ee.tar.bz2
nixpkgs-c49dddb1ab2bed5c4761725c16afe165f717d7ee.tar.lz
nixpkgs-c49dddb1ab2bed5c4761725c16afe165f717d7ee.tar.xz
nixpkgs-c49dddb1ab2bed5c4761725c16afe165f717d7ee.tar.zst
nixpkgs-c49dddb1ab2bed5c4761725c16afe165f717d7ee.zip
Substitute fixOptionSetsFun by multiple functions which are:
- well named,
- capable to handle the proposal of Eelco Dolstra { imports= [..]; options = {}; config = {}; } in addition to the current { require = [..]; .. } syntax.

svn path=/nixpkgs/trunk/; revision=16192
Diffstat (limited to 'pkgs')
-rw-r--r--pkgs/lib/misc.nix32
-rw-r--r--pkgs/lib/options.nix135
2 files changed, 79 insertions, 88 deletions
diff --git a/pkgs/lib/misc.nix b/pkgs/lib/misc.nix
index a8f37ec277b..dc73a2f6886 100644
--- a/pkgs/lib/misc.nix
+++ b/pkgs/lib/misc.nix
@@ -208,20 +208,24 @@ rec {
             (filter (__hasAttr name) sets));
     }) (concatMap builtins.attrNames sets));
 
-  # flatten a list of elements by following the properties of the elements.
-  # next   : return the list of following elements.
-  # seen   : lists of elements already visited.
-  # default: result if 'x' is empty.
-  # x      : list of values that have to be processed.
-  uniqFlatten = next: seen: default: x:
-    if x == []
-    then default
-    else
-      let h = head x; t = tail x; n = next h; in
-      if elem h seen
-      then uniqFlatten next seen default t
-      else uniqFlatten next (seen ++ [h]) (default ++ [h]) (n ++ t)
-    ;
+
+  lazyGenericClosure = {startSet, operator}:
+    let
+      work = list: doneKeys: result:
+        if list == [] then
+          result
+        else
+          let x = head list; key = x.key; in
+          if elem key doneKeys then
+            work (tail list) doneKeys result
+          else
+            work (tail list ++ operator x) ([key] ++ doneKeys) ([x] ++ result);
+    in
+      work startSet [] [];
+
+  genericClosure =
+    if builtins ? genericClosure then builtins.genericClosure
+    else lazyGenericClosure;
 
   innerModifySumArgs = f: x: a: b: if b == null then (f a b) // x else 
 	innerModifySumArgs f x (a // b);
diff --git a/pkgs/lib/options.nix b/pkgs/lib/options.nix
index 1e3dab80bb5..ca6173ef086 100644
--- a/pkgs/lib/options.nix
+++ b/pkgs/lib/options.nix
@@ -78,7 +78,7 @@ rec {
               merge = list:
                 decl.type.iter
                   (path: opts:
-                     fixMergeFun (recurseInto path) (optionConfig opts)
+                     lib.fix (fixableMergeFun (recurseInto path) (optionConfig opts))
                   )
                   opt.name
                   (opt.merge list);
@@ -262,6 +262,12 @@ rec {
   || builtins.isList x
   );
 
+  importIfPath = path:
+    if isPath path then
+      import path
+    else
+      path;
+
   applyIfFunction = f: arg:
     if builtins.isFunction f then
       f arg
@@ -270,106 +276,87 @@ rec {
 
   moduleClosure = initModules: args:
     let
-      moduleImport = path:
-        (applyIfFunction (import path) args) // {
+      moduleImport = m:
+        (applyIfFunction (importIfPath m) args) // {
           # used by generic closure to avoid duplicated imports.
-          key = path;
+          key = m;
         };
+
+      removeKeys = list: map (m: removeAttrs m ["key"]) list;
+
+      getImports = m:
+        if m ? config || m ? options then
+          attrByPath ["imports"] [] m
+        else
+          toList (rmProperties (attrByPath ["require"] [] (delayProperties m)));
+
+      getImportedPaths = m: filter isPath (getImports m);
+      getImportedSets = m: filter (x: !isPath x) (getImports m);
+
+      inlineImportedSets = list:
+        lib.concatMap (m:[m] ++ map moduleImport (getImportedSets m)) list;
     in
-      builtins.genericClosure {
+      inlineImportedSets (removeKeys (lazyGenericClosure {
         startSet = map moduleImport initModules;
-        operator = m:
-          map moduleImport (attrByPath ["imports"] [] m);
-      };
+        operator = m: map moduleImport (getImportedPaths m);
+      }));
 
   selectDeclsAndDefs = modules:
     lib.concatMap (m:
-       attrByPath ["options"] [] m
-    ++ attrByPath ["config"] [] m
+      if m ? config || m ? options then
+         attrByPath ["options"] [] m
+      ++ attrByPath ["config"] [] m
+      else
+        [ m ]
     ) modules;
 
-  fixMergeFun = merge: optFun:
-    lib.fix (config:
-      merge (
+
+  fixableMergeFun = merge: f: config:
+    merge (
+      # remove require because this is not an option.
+      map (m: removeAttrs m ["require"]) (
         # Delay top-level properties like mkIf
         map delayProperties (
           # generate the list of option sets.
-          optFun config
+          f config
         )
       )
     );
 
-  fixMergeModules = merge: initModules: {...}@args:
-    fixMergeFun (config:
+  fixableMergeModules = merge: initModules: {...}@args: config:
+    fixableMergeFun merge (config:
+      # filter the list of option sets.
       selectDeclsAndDefs (
+        # generate the list of modules from a closure of imports/require
+        # attribtues.
         moduleClosure initModules (args // { inherit config; })
       )
-    );
+    ) config;
 
-  fixModulesConfig = initModules: {...}@args:
-    fixMergeModules (mergeOptionSets "") initModules args;
-
-  fixOptionsConfig = initModules: {...}@args:
-    fixMergeModules (filterOptionSets "") initModules args;
-
-
-  # Evaluate a list of option sets that would be merged with the
-  # function "merge" which expects two arguments.  The attribute named
-  # "require" is used to imports option declarations and bindings.
-  #
-  # * cfg[0-9]: configuration
-  # * cfgSet[0-9]: configuration set
-  #
-  # merge: the function used to merge options sets.
-  # args: is the set of packages available. (nixpkgs)
-  # opts: list of option sets or option set functions.
-  # config: result of this evaluation.
-  fixOptionSetsFun = merge: args: opts: config:
-    let
-      # remove possible mkIf to access the require attribute.
-      noImportConditions = cfgSet0:
-        let cfgSet1 = delayProperties cfgSet0; in
-        if cfgSet1 ? require then
-          cfgSet1 // { require = rmProperties cfgSet1.require; }
-        else
-          cfgSet1;
 
-      filenameHandler = cfg:
-        if isPath cfg then import cfg else cfg;
+  fixableDefinitionsOf = initModules: {...}@args:
+    fixableMergeModules (mergeOptionSets "") initModules args;
 
-      argumentHandler = cfg:
-        applyIfFunction cfg (args // { inherit config; });
+  fixableDeclarationsOf = initModules: {...}@args:
+    fixableMergeModules (filterOptionSets "") initModules args;
 
-      preprocess = cfg0:
-        let cfg1 = filenameHandler cfg0;
-            cfg2 = argumentHandler cfg1;
-            cfg3 = noImportConditions cfg2;
-        in cfg3;
+  definitionsOf = initModules: {...}@args:
+    lib.fix (fixableDefinitionsOf initModules args);
 
-      getRequire = x: toList (attrByPath ["require"] [] (preprocess x));
-      getRecursiveRequire = x:
-        fold (cfg: l:
-          if isPath cfg then
-            [ cfg ] ++ l
-          else
-            [ cfg ] ++ (getRecursiveRequire cfg) ++ l
-        ) [] (getRequire x);
+  declarationsOf = initModules: {...}@args:
+    lib.fix (fixableDeclarationsOf initModules args);
 
-      getRequireSets = x: filter (x: ! isPath x) (getRecursiveRequire x);
-      getRequirePaths = x: filter isPath (getRecursiveRequire x);
-      rmRequire = x: removeAttrs (preprocess x) ["require"];
 
-      inlineRequiredSets = cfgs:
-        fold (cfg: l: [ cfg ] ++ (getRequireSets cfg) ++ l) [] cfgs;
-    in
-      merge "" (
-        map rmRequire (
-          inlineRequiredSets ((toList opts) ++ lib.uniqFlatten getRequirePaths [] [] (lib.concatMap getRequirePaths (toList opts)))
-        )
-      );
+  fixMergeModules = merge: initModules: {...}@args:
+    lib.fix (fixableMergeModules merge initModules args);
+
+
+  # old interface.
+  fixOptionSetsFun = merge: {...}@args: initModules: config:
+    fixableMergeModules (merge "") initModules args config;
 
-  fixOptionSets = merge: args: opts:
-    lib.fix (fixOptionSetsFun merge args opts);
+  fixOptionSets = merge: args: initModules:
+    fixMergeModules (merge "") initModules args;
 
 
   # Generate documentation template from the list of option declaration like