Skip to content

Commit

Permalink
lib: convert to modules
Browse files Browse the repository at this point in the history
  • Loading branch information
infinisil committed Dec 6, 2017
1 parent 391f1df commit efc486b
Show file tree
Hide file tree
Showing 6 changed files with 213 additions and 215 deletions.
6 changes: 1 addition & 5 deletions modules/files.nix
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,6 @@ let

homeDirectory = config.home.homeDirectory;

fileType = (import lib/file-type.nix {
inherit homeDirectory lib pkgs;
}).fileType;

# A symbolic link whose target path matches this pattern will be
# considered part of a Home Manager generation.
homeFilePattern = "${builtins.storeDir}/*-home-manager-files/*";
Expand All @@ -24,7 +20,7 @@ in
home.file = mkOption {
description = "Attribute set of files to link into the user home.";
default = {};
type = fileType "<envar>HOME</envar>" homeDirectory;
type = fileType.fileType "<envar>HOME</envar>" homeDirectory;
};

home-files = mkOption {
Expand Down
217 changes: 115 additions & 102 deletions modules/lib/dag.nix
Original file line number Diff line number Diff line change
Expand Up @@ -7,118 +7,131 @@
# - the addition of the function `dagEntryBefore` indicating a
# "wanted by" relationship.

{ lib }:
{ lib, ... }:

with lib;

rec {
{
lib.dag = let
d = {

emptyDag = {};
emptyDag = {};

isDag = dag:
let
isEntry = e: (e ? data) && (e ? after) && (e ? before);
in
builtins.isAttrs dag && all (x: x) (mapAttrsToList (n: isEntry) dag);
isDag = dag:
let
isEntry = e: (e ? data) && (e ? after) && (e ? before);
in
builtins.isAttrs dag && all (x: x) (mapAttrsToList (n: isEntry) dag);

# Takes an attribute set containing entries built by
# dagEntryAnywhere, dagEntryAfter, and dagEntryBefore to a
# topologically sorted list of entries.
#
# Internally this function uses the `toposort` function in
# `<nixpkgs/lib/lists.nix>` and its value is accordingly.
#
# Specifically, the result on success is
#
# { result = [{name = ?; data = ?;} …] }
#
# For example
#
# nix-repl> dagTopoSort {
# a = dagEntryAnywhere "1";
# b = dagEntryAfter ["a" "c"] "2";
# c = dagEntryBefore ["d"] "3";
# d = dagEntryBefore ["e"] "4";
# e = dagEntryAnywhere "5";
# } == {
# result = [
# { data = "1"; name = "a"; }
# { data = "3"; name = "c"; }
# { data = "2"; name = "b"; }
# { data = "4"; name = "d"; }
# { data = "5"; name = "e"; }
# ];
# }
# true
#
# And the result on error is
#
# {
# cycle = [ {after = ?; name = ?; data = ?} … ];
# loops = [ {after = ?; name = ?; data = ?} … ];
# }
#
# For example
#
# nix-repl> dagTopoSort {
# a = dagEntryAnywhere "1";
# b = dagEntryAfter ["a" "c"] "2";
# c = dagEntryAfter ["d"] "3";
# d = dagEntryAfter ["b"] "4";
# e = dagEntryAnywhere "5";
# } == {
# cycle = [
# { after = ["a" "c"]; data = "2"; name = "b"; }
# { after = ["d"]; data = "3"; name = "c"; }
# { after = ["b"]; data = "4"; name = "d"; }
# ];
# loops = [
# { after = ["a" "c"]; data = "2"; name = "b"; }
# ];
# } == {}
# true
dagTopoSort = dag:
let
dagBefore = dag: name:
mapAttrsToList (n: v: n) (
filterAttrs (n: v: any (a: a == name) v.before) dag
);
normalizedDag =
mapAttrs (n: v: {
name = n;
data = v.data;
after = v.after ++ dagBefore dag n;
}) dag;
before = a: b: any (c: a.name == c) b.after;
sorted = toposort before (mapAttrsToList (n: v: v) normalizedDag);
in
if sorted ? result then
{ result = map (v: { inherit (v) name data; }) sorted.result; }
else
sorted;
# Takes an attribute set containing entries built by
# dagEntryAnywhere, dagEntryAfter, and dagEntryBefore to a
# topologically sorted list of entries.
#
# Internally this function uses the `toposort` function in
# `<nixpkgs/lib/lists.nix>` and its value is accordingly.
#
# Specifically, the result on success is
#
# { result = [{name = ?; data = ?;} …] }
#
# For example
#
# nix-repl> dagTopoSort {
# a = dagEntryAnywhere "1";
# b = dagEntryAfter ["a" "c"] "2";
# c = dagEntryBefore ["d"] "3";
# d = dagEntryBefore ["e"] "4";
# e = dagEntryAnywhere "5";
# } == {
# result = [
# { data = "1"; name = "a"; }
# { data = "3"; name = "c"; }
# { data = "2"; name = "b"; }
# { data = "4"; name = "d"; }
# { data = "5"; name = "e"; }
# ];
# }
# true
#
# And the result on error is
#
# {
# cycle = [ {after = ?; name = ?; data = ?} … ];
# loops = [ {after = ?; name = ?; data = ?} … ];
# }
#
# For example
#
# nix-repl> dagTopoSort {
# a = dagEntryAnywhere "1";
# b = dagEntryAfter ["a" "c"] "2";
# c = dagEntryAfter ["d"] "3";
# d = dagEntryAfter ["b"] "4";
# e = dagEntryAnywhere "5";
# } == {
# cycle = [
# { after = ["a" "c"]; data = "2"; name = "b"; }
# { after = ["d"]; data = "3"; name = "c"; }
# { after = ["b"]; data = "4"; name = "d"; }
# ];
# loops = [
# { after = ["a" "c"]; data = "2"; name = "b"; }
# ];
# } == {}
# true
dagTopoSort = dag:
let
dagBefore = dag: name:
mapAttrsToList (n: v: n) (
filterAttrs (n: v: any (a: a == name) v.before) dag
);
normalizedDag =
mapAttrs (n: v: {
name = n;
data = v.data;
after = v.after ++ dagBefore dag n;
}) dag;
before = a: b: any (c: a.name == c) b.after;
sorted = toposort before (mapAttrsToList (n: v: v) normalizedDag);
in
if sorted ? result then
{ result = map (v: { inherit (v) name data; }) sorted.result; }
else
sorted;

# Applies a function to each element of the given DAG.
dagMap = f: dag: mapAttrs (n: v: v // { data = f n v.data; }) dag;
# Applies a function to each element of the given DAG.
dagMap = f: dag: mapAttrs (n: v: v // { data = f n v.data; }) dag;

# Create a DAG entry with no particular dependency information.
dagEntryAnywhere = data: {
inherit data;
before = [];
after = [];
};
# Create a DAG entry with no particular dependency information.
dagEntryAnywhere = data: {
inherit data;
before = [];
after = [];
};

dagEntryBetween = before: after: data: {
inherit data before after;
};
dagEntryBetween = before: after: data: {
inherit data before after;
};

dagEntryAfter = after: data: {
inherit data after;
before = [];
};
dagEntryAfter = after: data: {
inherit data after;
before = [];
};

dagEntryBefore = before: data: {
inherit data before;
after = [];
};
dagEntryBefore = before: data: {
inherit data before;
after = [];
};
};
in d // {
empty = d.emptyDag;
isDag = d.isDag;
topoSort = d.dagTopoSort;
map = d.dagMap;
entryAnywhere = d.dagEntryAnywhere;
entryBetween = d.dagEntryBetween;
entryAfter = d.dagEntryAfter;
entryBefore = d.dagEntryBefore;
};

}
20 changes: 4 additions & 16 deletions modules/lib/default.nix
Original file line number Diff line number Diff line change
@@ -1,18 +1,6 @@
{ lib }:

{
dag =
let
d = import ./dag.nix { inherit lib; };
in
{
empty = d.emptyDag;
isDag = d.isDag;
topoSort = d.dagTopoSort;
map = d.dagMap;
entryAnywhere = d.dagEntryAnywhere;
entryBetween = d.dagEntryBetween;
entryAfter = d.dagEntryAfter;
entryBefore = d.dagEntryBefore;
};
imports = [
./dag.nix
./file-type.nix
];
}

0 comments on commit efc486b

Please sign in to comment.