diff --git a/lib/default.nix b/lib/default.nix index f729a36249af..03a902945a3b 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -93,7 +93,7 @@ let hiPrioSet; inherit (sources) pathType pathIsDirectory cleanSourceFilter cleanSource sourceByRegex sourceFilesBySuffices - commitIdFromGitRepo cleanSourceWith; + commitIdFromGitRepo cleanSourceWith pathHasContext canCleanSource; inherit (modules) evalModules closeModules unifyModuleSyntax applyIfFunction unpackSubmodule packSubmodule mergeModules mergeModules' mergeOptionDecls evalOptionValue mergeDefinitions diff --git a/lib/sources.nix b/lib/sources.nix index 703f5a71da6a..704711b20cd9 100644 --- a/lib/sources.nix +++ b/lib/sources.nix @@ -93,4 +93,8 @@ rec { else lib.head matchRef else throw ("Not a .git directory: " + path); in lib.flip readCommitFromFile "HEAD"; + + pathHasContext = builtins.hasContext or (lib.hasPrefix builtins.storeDir); + + canCleanSource = src: src ? _isLibCleanSourceWith || !(pathHasContext (toString src)); } diff --git a/pkgs/build-support/safe-discard-string-context.nix b/pkgs/build-support/safe-discard-string-context.nix new file mode 100644 index 000000000000..293a15295d55 --- /dev/null +++ b/pkgs/build-support/safe-discard-string-context.nix @@ -0,0 +1,14 @@ +# | Discard the context of a string while ensuring that expected path +# validity invariants hold. +# +# This relies on import-from-derivation, but it is only useful in +# contexts where the string is going to be used in an +# import-from-derivation anyway. +# +# safeDiscardStringContext : String → String +{ writeText }: s: + builtins.seq + (import (writeText + "discard.nix" + "${builtins.substring 0 0 s}null\n")) + (builtins.unsafeDiscardStringContext s) diff --git a/pkgs/development/haskell-modules/make-package-set.nix b/pkgs/development/haskell-modules/make-package-set.nix index 5a2f7fb89f0d..b91d73c9748c 100644 --- a/pkgs/development/haskell-modules/make-package-set.nix +++ b/pkgs/development/haskell-modules/make-package-set.nix @@ -146,7 +146,9 @@ in package-set { inherit pkgs stdenv callPackage; } self // { overrideCabal (self.callPackage (haskellSrc2nix { inherit name; src = pkgs.lib.cleanSourceWith - { inherit src; + { src = if pkgs.lib.canCleanSource src + then src + else pkgs.safeDiscardStringContext src; filter = path: type: pkgs.lib.hasSuffix "${name}.cabal" path || pkgs.lib.hasSuffix "package.yaml" path; diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index dbbb754852a0..1ee54227398d 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -20237,4 +20237,6 @@ with pkgs; wal-g = callPackage ../tools/backup/wal-g {}; tlwg = callPackage ../data/fonts/tlwg { }; + + safeDiscardStringContext = callPackage ../build-support/safe-discard-string-context.nix { }; }