summary refs log tree commit diff
path: root/pkgs/lib
diff options
context:
space:
mode:
authorNicolas Pierron <nicolas.b.pierron@gmail.com>2009-11-07 01:59:55 +0000
committerNicolas Pierron <nicolas.b.pierron@gmail.com>2009-11-07 01:59:55 +0000
commitbb077b253ff111785d84c0ad15fbfcf26d882fb3 (patch)
treec1706e40598bca8e0b28394feccaa51ac30290fb /pkgs/lib
parent88f113d032c1908fca2ebfbf429d161fc738bdc1 (diff)
downloadnixlib-bb077b253ff111785d84c0ad15fbfcf26d882fb3.tar
nixlib-bb077b253ff111785d84c0ad15fbfcf26d882fb3.tar.gz
nixlib-bb077b253ff111785d84c0ad15fbfcf26d882fb3.tar.bz2
nixlib-bb077b253ff111785d84c0ad15fbfcf26d882fb3.tar.lz
nixlib-bb077b253ff111785d84c0ad15fbfcf26d882fb3.tar.xz
nixlib-bb077b253ff111785d84c0ad15fbfcf26d882fb3.tar.zst
nixlib-bb077b253ff111785d84c0ad15fbfcf26d882fb3.zip
* Add a function to sort a list.
* Add a new property to order NixOS definitions without creating
  dependencies between snippets.
* Add mkHeader & mkFooter properties (special case of mkOrder).

svn path=/nixpkgs/trunk/; revision=18242
Diffstat (limited to 'pkgs/lib')
-rw-r--r--pkgs/lib/lists.nix19
-rw-r--r--pkgs/lib/properties.nix59
2 files changed, 78 insertions, 0 deletions
diff --git a/pkgs/lib/lists.nix b/pkgs/lib/lists.nix
index d032ab412bab..3a5ed2628de8 100644
--- a/pkgs/lib/lists.nix
+++ b/pkgs/lib/lists.nix
@@ -142,4 +142,23 @@ rec {
       if l == [] then accu
       else reverse_ ([(head l)] ++ accu) (tail l);
     in reverse_ [] l;
+
+  # Sort a list based on the `strictLess' function which compare the two
+  # elements and return true if the first argument is strictly below the
+  # second argument.  The returned list is sorted in an increasing order.
+  # The implementation does a quick-sort.
+  sort = strictLess: list:
+    let
+      # This implementation only have one element lists on the left hand
+      # side of the concatenation operator.
+      qs = l: concat:
+        if l == [] then concat
+        else if tail l == [] then l ++ concat
+        else let
+          part = partition (strictLess (head l)) (tail l);
+        in
+          qs part.wrong ([(head l)] ++ qs part.right []);
+    in
+      qs list [];
+
 }
diff --git a/pkgs/lib/properties.nix b/pkgs/lib/properties.nix
index f28d652d4e69..3964c117f14f 100644
--- a/pkgs/lib/properties.nix
+++ b/pkgs/lib/properties.nix
@@ -382,4 +382,63 @@ rec {
           mkNotdef
       ) prioValList;
 
+  /* mkOrder */
+
+  # Order definitions based on there index value.  This property is useful
+  # when the result of the merge function depends on the order on the
+  # initial list.  (e.g. concatStrings) Definitions are ordered based on
+  # their rank.  The lowest ranked definition would be the first to element
+  # of the list used by the merge function.  And the highest ranked
+  # definition would be the last.  Definitions which does not have any rank
+  # value have the default rank of 100.
+  isOrder = attrs: (typeOf attrs) == "order";
+  mkOrder = rank: content: mkProperty {
+    property = {
+      _type = "order";
+      onGlobalEval = onOrderGlobalEval;
+      inherit rank;
+    };
+    inherit content;
+  };
+
+  mkHeader = mkOrder 10;
+  mkFooter = mkOrder 1000;
+
+  # Fetch the rank of each definition (add the default rank is none) and
+  # sort them based on their ranking.
+  onOrderGlobalEval = valList:
+    let
+      defaultRank = 100;
+
+      inherit (builtins) lessThan;
+
+      getRankVal =
+        foldProperty
+          (foldFilter isOrder
+            (p@{property, content, ...}:
+              if content ? rank then
+                content
+              else
+                content // {
+                  inherit (property) rank;
+                }
+            )
+            (p@{property, content, ...}:
+              content // {
+                value = p // { content = content.value; };
+              }
+            )
+          ) (value: { inherit value; });
+
+      addDefaultRank = x:
+        if x ? rank then x
+        else x // { rank = defaultRank; };
+
+      rankValList = map (x: addDefaultRank (getRankVal x)) valList;
+
+      cmp = x: y:
+        builtins.lessThan x.rank y.rank;
+    in
+      map (x: x.value) (sort cmp rankValList);
+
 }