nix-helpers: ed31f18a3066df6cdb837608231172bcf6c6d1e9
1: # Builds a directory whose entries/content correspond to the names/values of
2: # the given attrset. When a value is an attrset, the corresponding entry is
3: # a directory, whose contents is generated with attrsToDirs on that value.
4: { addPathToStore, asPath, die, dummyBuild, foldAttrs', getType, hello, isPath
5: , lib, nixListToBashArray, nothing, runCmd, runCommand, sanitiseName
6: , writeScript }:
7:
8: with builtins;
9: with lib;
10: with rec {
11: # Traverses into the given nested attrset, producing a list of name/value
12: # pairs, where each value is a path or derivation, and each name is the path
13: # through the attrsets to reach that value. Values which are paths get copied
14: # into the Nix store first.
15: toPaths = prefix: val:
16: if isPath val then [{
17: name = prefix;
18: value = addPathToStore val;
19: }] else if isDerivation val then [{
20: name = prefix;
21: value = val;
22: }] else if isAttrs val then
23: concatMap (entry: toPaths (prefix + "/" + entry) (getAttr entry val))
24: (attrNames val)
25: else
26: die {
27: error = "Unsupported type in attrsToDirs'";
28: given = getType val;
29: allowed = [ "path" "derivation" "set" ];
30: };
31: };
32: rawName: attrs:
33: with rec {
34: name = sanitiseName "${rawName}";
35:
36: # We can't have empty attr names, so always stick a dummy '_' at the start,
37: # and strip it off in the build script
38: data = listToAttrs (toPaths "_" attrs);
39:
40: # The element order of these lists is arbitrary, but they must match
41: paths = attrNames data;
42: content = map (n: getAttr n data) paths;
43:
44: # Create bash code and env vars for the build command, without forcing any
45: # derivations to be built at eval time.
46: pathData = nixListToBashArray {
47: name = "VALPATHS";
48: args = paths;
49: };
50: contentData = nixListToBashArray {
51: name = "VALUES";
52: args = content;
53: };
54: };
55: if attrs == { } then
56: dummyBuild name
57: else
58: runCmd name (pathData.env // contentData.env) ''
59: ${pathData.code}
60: ${contentData.code}
61:
62: # Loop over each path/content entry in our arrays (off-by-one cruft
63: # is due to seq preferring to count from 1)
64: for NPLUSONE in $(seq 1 "''${#VALUES[@]}")
65: do
66: N=$(( NPLUSONE - 1 ))
67:
68: # The output path we're going to make; cut off leading _ and
69: # prepend $out
70: STRIPPED=$(echo "''${VALPATHS[$N]}" | cut -c 2-)
71: P="$out$STRIPPED"
72:
73: # Ensure parent directories exist
74: mkdir -p "$(dirname "$P")"
75:
76: # Link value in place (saves space compared to copying)
77: ln -s "''${VALUES[$N]}" "$P"
78: done
79: ''
Generated by git2html.