diff --git a/nix/utils/default.nix b/nix/utils/default.nix index 0c6c88faf..675f22499 100644 --- a/nix/utils/default.nix +++ b/nix/utils/default.nix @@ -148,6 +148,27 @@ let */ isSymlink = path: pathType' path ? symlink; + /* Checks whether the given value is (or contains) a reference to a + path that will be retained in the store path resulting from a derivation. + So if isReferencablePath returns true, the given value may be used in a + way that allows accessing it at runtime of any Nix built program. + + Returns true for: + + - Strings with context (if the string is/contains a single path is not verified!) + - Path values + - Derivations + + Note that the value still needs to used in a way that forces string context + (and thus reference tracking) to be created, e.g. in string interpolation. + + Type: any -> bool + */ + isReferencablePath = value: + builtins.isPath value + || lib.isDerivation value + || (builtins.isString value && builtins.hasContext value); + in { inherit @@ -156,5 +177,6 @@ in isDirectory isRegularFile isSymlink + isReferencablePath ; } diff --git a/nix/writeTree/default.nix b/nix/writeTree/default.nix index 4f22221f3..11112ad46 100644 --- a/nix/writeTree/default.nix +++ b/nix/writeTree/default.nix @@ -1,12 +1,7 @@ { 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); + inherit (depot.nix.utils) isReferencablePath; esc = s: lib.escapeShellArg /* ensure paths import into store */ "${s}"; @@ -16,7 +11,7 @@ let '' + pipe tree [ (mapAttrsToList (k: v: - if isPathLike v then + if isReferencablePath v then "cp -R --reflink=auto ${esc "${v}"} \"$out/\"${esc path}/${esc k}" else if lib.isAttrs v then writeTreeAtPath (path + "/" + k) v