77a6eb4f51
As far as I can tell we can handle files and directories using the same cp(1) invocation, so we no longer need to potentially IfD derivations in the tree to figure out whether they are files or directories. Change-Id: Iabe648c30a747fa42768558715e388552024764a Reviewed-on: https://cl.tvl.fyi/c/depot/+/10996 Reviewed-by: aspen <root@gws.fyi> Autosubmit: sterni <sternenseemann@systemli.org> Tested-by: BuildkiteCI
43 lines
1.3 KiB
Nix
43 lines
1.3 KiB
Nix
{ depot, lib, pkgs, ... }:
|
|
let
|
|
inherit (lib) fix pipe mapAttrsToList isAttrs concatLines isString isDerivation isPath;
|
|
|
|
# TODO(sterni): move to //nix/utils with clearer naming and alternative similar to lib.types.path
|
|
isPathLike = value:
|
|
isPath value
|
|
|| isDerivation value
|
|
|| (isString value && builtins.hasContext value);
|
|
|
|
esc = s: lib.escapeShellArg /* ensure paths import into store */ "${s}";
|
|
|
|
writeTreeAtPath = path: tree:
|
|
''
|
|
mkdir -p "$out/"${esc path}
|
|
''
|
|
+ pipe tree [
|
|
(mapAttrsToList (k: v:
|
|
if isPathLike v then
|
|
"cp -R --reflink=auto ${v} \"$out/\"${esc path}/${esc k}"
|
|
else if lib.isAttrs v then
|
|
writeTreeAtPath (path + "/" + k) v
|
|
else
|
|
throw "invalid type (expected path, derivation, string with context, 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;
|
|
}
|