diff --git a/nix/utils/default.nix b/nix/utils/default.nix index 0c6c88faf..a29f34651 100644 --- a/nix/utils/default.nix +++ b/nix/utils/default.nix @@ -43,6 +43,21 @@ let else builtins.throw "Don't know how to get (base)name of " + lib.generators.toPretty { } p; + /* Retrieves the drvPath attribute from a given derivation, but ensures that + the resulting string only depends on the `.drv` file in the nix store and + not on its realised outputs as well. + + Type: drv -> string + */ + onlyDrvPath = drv: + let + inherit (drv) drvPath; + unsafeDrvPath = builtins.unsafeDiscardStringContext drvPath; + in + builtins.appendContext unsafeDrvPath { + ${unsafeDrvPath} = { path = true; }; + }; + /* Query the type of a path exposing the same information as would be by `builtins.readDir`, but for a single, specific target path. @@ -152,6 +167,7 @@ in { inherit storePathName + onlyDrvPath pathType isDirectory isRegularFile diff --git a/nix/utils/tests/default.nix b/nix/utils/tests/default.nix index 344a1771d..d5159a843 100644 --- a/nix/utils/tests/default.nix +++ b/nix/utils/tests/default.nix @@ -15,6 +15,7 @@ let isSymlink pathType storePathName + onlyDrvPath ; assertUtilsPred = msg: act: exp: [ @@ -91,9 +92,19 @@ let (storePathName cleanedSource) cleanedSource.name) ]; + + onlyDrvPathTests = it "correctly updates the string context of drvPath" [ + (assertEq "onlyDrvPath only produces path dependencies" + (builtins.all + (dep: dep.path or false) + (builtins.attrValues + (builtins.getContext (onlyDrvPath depot.tools.cheddar)))) + true) + ]; in runTestsuite "nix.utils" [ pathPredicates storePathNameTests + onlyDrvPathTests ]