diff options
author | Aspen Smith <root@gws.fyi> | 2024-02-18T18·57-0500 |
---|---|---|
committer | clbot <clbot@tvl.fyi> | 2024-02-21T20·52+0000 |
commit | 944483ef5e3536c96bf9120ef2054aa520cf6e60 (patch) | |
tree | 188a8341ae62d2b9431ea081ab172a559254edc9 /nix/writeTree/default.nix | |
parent | d74c68025b5d1ffea3cd4f9731ee53b6ca2c6271 (diff) |
feat(nix/writeTree): init r/7589
Add //nix/writeTree, a function to make a derivation to build a directory structure from a Nix attribute set. Co-authored-by: sterni <sternenseemann@systemli.org> Change-Id: I9c0fc91611a55a20ad33de6f2b27abde4b6abd21 Reviewed-on: https://cl.tvl.fyi/c/depot/+/10963 Reviewed-by: sterni <sternenseemann@systemli.org> Tested-by: BuildkiteCI Autosubmit: aspen <root@gws.fyi> Reviewed-by: aspen <root@gws.fyi>
Diffstat (limited to 'nix/writeTree/default.nix')
-rw-r--r-- | nix/writeTree/default.nix | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/nix/writeTree/default.nix b/nix/writeTree/default.nix new file mode 100644 index 000000000000..43ece9b19f97 --- /dev/null +++ b/nix/writeTree/default.nix @@ -0,0 +1,51 @@ +{ depot, lib, pkgs, ... }: +let + inherit (lib) fix pipe mapAttrsToList isAttrs concatLines isString; + + inherit (depot.nix.utils) isDirectory isRegularFile; + + esc = s: lib.escapeShellArg /* ensure paths import into store */ "${s}"; + + writeTreeAtPath = path: tree: + '' + mkdir -p "$out/"${esc path} + '' + + pipe tree [ + (mapAttrsToList (k: v: + # TODO(sterni): a more discoverable isPathLike would fit into //nix/utils + # ATTN: This check has the flaw that it accepts paths without context + # that would not be available in the sandbox! + if lib.types.path.check v then + if isRegularFile v then + "cp --reflink=auto ${esc v} \"$out/\"${esc path}/${esc k}" + else if isDirectory v then '' + mkdir -p "$out/"${esc path} + cp -r --reflink=auto ${esc v} "$out/"${esc path}/${esc k} + '' + else + throw "invalid path type (expected file or directory)" + else if isAttrs v then + writeTreeAtPath "${path}/${k}" v + else if isString v then + "cp --reflink=auto ${esc v} \"$out/\"${esc path}/${esc k}" + else + throw "invalid type (expected file, directory, or attrs)")) + concatLines + ]; + + /* Create a directory tree specified by a Nix attribute set structure. + + Each value in `tree` should either be a file, a directory, or another tree + attribute set. Those paths will be written to a directory tree + corresponding to the structure of the attribute set. + + Type: string -> attrSet -> derivation + */ + writeTree = name: tree: + pkgs.runCommandLocal name { } (writeTreeAtPath "" tree); +in + +# __functor trick so readTree can add the tests attribute +{ + __functor = _: writeTree; +} |