43f91c44bd
Passes the location from the root at which packages are imported on to all packages. The path is passed in as a parameter called 'locatedAt' which contains a list of strings with each individual path component. For example, the blog source in `services/tazblog` will have a list with `[ "services" "tazblog" ]` passed in as the `locatedAt` attribute. This can be used for enabling features such as path-specific imports when using things like buildGo.
78 lines
2 KiB
Nix
78 lines
2 KiB
Nix
initPath: { pkgs, ... } @ args:
|
|
|
|
let
|
|
inherit (builtins)
|
|
attrNames
|
|
filter
|
|
head
|
|
isString
|
|
length
|
|
listToAttrs
|
|
map
|
|
match
|
|
readDir
|
|
split
|
|
tail
|
|
toPath
|
|
toString;
|
|
|
|
attrsToList = attrs: map (name: {
|
|
inherit name;
|
|
value = attrs."${name}";
|
|
}) (attrNames attrs);
|
|
|
|
isFile = s: s == "regular";
|
|
isDir = s: s == "directory";
|
|
|
|
joinPath = p: f: toPath ((toString p) + "/" + f);
|
|
|
|
isNixFile = file:
|
|
let res = match "(.*)\.nix" file;
|
|
in if res == null then null else head res;
|
|
|
|
filterNixFiles = dir:
|
|
let files = filter (e: isFile e.value) dir;
|
|
nixFiles = map (f: {
|
|
# Name and value are intentionally flipped to get the
|
|
# correct attribute set structure back out
|
|
name = isNixFile f.name;
|
|
value = f.name; # i.e. the path
|
|
}) files;
|
|
in filter (f: isString f.name) nixFiles;
|
|
|
|
# Some packages require that their position in the tree is passed in
|
|
# as an argument. To do this the root directory (i.e. $PWD during
|
|
# imports) is chopped off the front of the path components in
|
|
# imports.
|
|
pathParts = p: tail (filter isString (split "/" (toString p)));
|
|
initLen = length (pathParts ./.);
|
|
drop = n: l:
|
|
if n == 0
|
|
then l
|
|
else if l == []
|
|
then []
|
|
else drop (n - 1) (tail l);
|
|
|
|
argsWithPath = args: parts: args // {
|
|
locatedAt = drop initLen parts;
|
|
};
|
|
|
|
traverse = path: dir:
|
|
let nixFiles = filterNixFiles dir;
|
|
imported = map (f: {
|
|
inherit (f) name;
|
|
value = import (joinPath path f.value) args;
|
|
}) nixFiles;
|
|
dirs = map (d: {
|
|
inherit (d) name;
|
|
value = readTree (joinPath path d.name);
|
|
}) (filter (e: isDir e.value) dir);
|
|
in listToAttrs (imported ++ dirs);
|
|
|
|
importOr = path: dir: f:
|
|
if dir ? "default.nix"
|
|
then import path (argsWithPath args (pathParts path))
|
|
else f path (attrsToList dir);
|
|
|
|
readTree = path: importOr path (readDir path) traverse;
|
|
in readTree initPath
|