Support Nix <2.4 (#1418)

* Downgrades the error to a warning.
* Adds `filterPath` as a way to disable filtering to have caching work between Nix <2.4 and >=2.4.
* Disables filtering on `haskell-nix.hackage-project` based functions (should make all the GHC derivations the same).

I think it would also be possible to make a `filterPath` implementation that recursively used `builtins.readDir` and called the `filter` function to implement filtering on Nix <2.4, but I am not sure if it is worth it.

Anyone that needs the old behaviour for project packages (consistent filtering between <2.4 and >=2.4, but not between store and local) replace:

```
project = pkgs.haskell-nix.cabalProject {
  src = pkgs.haskell-nix.haskellLib.cleanGit {
    src = ./.;
  };
};
```

```
project = pkgs.haskell-nix.cabalProject {
  src = pkgs.haskell-nix.haskellLib.cleanGit {
     src = {
       outPath = ./.;
       filterPath = { path, ... }@args:
         if builtins.hasContext (toString path) then path else builtins.path args;
     };
  };
};
```
This commit is contained in:
Hamish Mackenzie 2022-03-29 01:24:01 +13:00 committed by GitHub
parent 9660601302
commit 8eb5d29d37
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 44 additions and 7 deletions

View File

@ -2,10 +2,7 @@
# https://github.com/NixOS/nixpkgs/blob/1d9d31a0eb8e8358830528538a391df52f6a075a/lib/sources.nix#L41
# It adds a subDir argument in a way that allows descending into a subdirectory
# to compose with cleaning the source with a filter.
{ lib }:
if lib.versionOlder builtins.nixVersion "2.4"
then throw "Nix version 2.4 or higher is required for Haskell.nix"
else rec {
{ lib }: rec {
# Like `builtins.filterSource`, except it will compose with itself,
# allowing you to chain multiple calls together without any
@ -53,6 +50,33 @@ else rec {
# (and forward a `name` argument) can use this to make
# the message to the use more meaningful.
#
# Nix <2.4 Suport with filterPath
#
# As of Nix >=2.4 filtering is now possible on all paths (including those in the store).
# If you still need to support older versions of Nix and want to maximise cache hits for your project
# you may want to consider using setting the `filterPath` attribute on `src` (must be done on
# the original src not the output of another `cleanSourceWith`).
#
# To disable filtering completely replace:
#
# src = ./.;
#
# with:
#
# src = { outPath = ./.; filterPath = { path, ... }: path; };
#
# To disable filtering only when the path is in the store use (when Nix <2.4 is unable to filter it):
#
# src = {
# outPath = ./.;
# filterPath = { path, ... }@args:
# if builtins.hasContext (toString path) then path else builtins.path args;
# };
#
# Currently `haskell-nix.hackage-project` (used by `hackage-package`, `tool` and `tools`) disables
# filtering. See `overlays/haskell.nix` for details.
#
# For more see https://github.com/input-output-hk/haskell.nix/pull/1418
cleanSourceWith = { filter ? _path: _type: true, src, subDir ? "", name ? null
, caller ? "cleanSourceWith", includeSiblings ? false }:
let
@ -106,10 +130,17 @@ else rec {
__trace (
"WARNING: `${caller}` called on ${toString src} without a `name`. "
+ "Consider adding `name = \"${baseNameOf src}\";`") "source";
filterPath = origSrc.filterPath or (
if builtins.compareVersions builtins.nixVersion "2.4" >= 0
then builtins.path
else __trace "WARNING: Using nix <2.4 will result in inconsistent filtering of ${toString origSrc} (see lib/clean-source-with.nix)"
(if builtins.hasContext or (lib.hasPrefix builtins.storeDir) (toString origSrc)
then { path, ... }: path
else builtins.path));
in {
inherit origSrc origSubDir origSrcSubDir;
filter = filter';
outPath = (builtins.path { filter = filter'; path = origSrc; name = name'; }) + origSubDir;
outPath = (filterPath { filter = filter'; path = origSrc; name = name'; }) + origSubDir;
_isLibCleanSourceWithEx = true;
# It is only safe for older cleanSourceWith to filter this one
# if the we are still looking at the root of origSrc

View File

@ -471,14 +471,20 @@ final: prev: {
inherit (rev) sha256;
};
revSuffix = final.lib.optionalString (rev.revNum > 0) "-r${toString rev.revNum}";
in let src = final.buildPackages.pkgs.runCommand "${name}-${version'}${revSuffix}-src" { } (''
in let src = final.buildPackages.pkgs.runCommand "${name}-${version'}${revSuffix}-src" {} (''
tmp=$(mktemp -d)
cd $tmp
tar xzf ${tarball}
mv "${name}-${version'}" $out
'' + final.lib.optionalString (rev.revNum > 0) ''
cp ${cabalFile} $out/${name}.cabal
'');
'') // {
# TODO remove once nix >=2.4 is widely adopted (will trigger rebuilds of everything).
# Disable filtering keeps pre ond post nix 2.4 behaviour the same. This means that
# the same `alex`, `happy` and `hscolour` are used to build GHC. It also means that
# that `tools` in the shell will be built the same.
filterPath = { path, ... }: path;
};
in cabalProject' (
(final.haskell-nix.hackageQuirks { inherit name; version = version'; }) //
builtins.removeAttrs args [ "version" "revision" ] // { inherit src; });