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.