summary refs log tree commit diff
path: root/lib/sources.nix
diff options
context:
space:
mode:
authorBas van Dijk <v.dijk.bas@gmail.com>2019-07-19 16:23:11 +0200
committerBas van Dijk <v.dijk.bas@gmail.com>2019-07-19 16:23:11 +0200
commit58ea28eb2c11a419b3e895f16d045fbd8f05468c (patch)
treea0ffe9cbbfb802aafb3fb24f4b8a66781b40b48c /lib/sources.nix
parent663542ad0483131e8c36742283191a8f40a7363d (diff)
downloadnixpkgs-58ea28eb2c11a419b3e895f16d045fbd8f05468c.tar
nixpkgs-58ea28eb2c11a419b3e895f16d045fbd8f05468c.tar.gz
nixpkgs-58ea28eb2c11a419b3e895f16d045fbd8f05468c.tar.bz2
nixpkgs-58ea28eb2c11a419b3e895f16d045fbd8f05468c.tar.lz
nixpkgs-58ea28eb2c11a419b3e895f16d045fbd8f05468c.tar.xz
nixpkgs-58ea28eb2c11a419b3e895f16d045fbd8f05468c.tar.zst
nixpkgs-58ea28eb2c11a419b3e895f16d045fbd8f05468c.zip
lib: allow sourceByRegex to be composed after cleanSourceWith
`sourceByRegex src regexes` should include a source file if one of the
regular expressions `regexes` matches the path of that file relative
to `src`.

However to compute this relative path `sourceByRegex` uses:

```
relPath = lib.removePrefix (toString src + "/") (toString path);
```

Note that `toString path` evaluates to an absolute file somewhere
under `src` and not under `/nix/store`.

The problem is that this doesn't work if `src` is a `cleanSourceWith`
invocation as well because `toString src` will then evaluate to
`src.outPath` which will evaluate to `builtins.filterSource ...` which
evaluates to a path in `/nix/store` which is not a prefix of `path`.

The solution is to replace `src` with `origSrc` where

```
origSrc = if isFiltered then src.origSrc else src;
isFiltered = src ? _isLibCleanSourceWith;
```

Test this by executing the following from the nixpkgs repo:

```
(cat << 'EOI'
let
  pkgs = import ./. {};
in pkgs.runCommand "test-sourceByRegex" {
  test_sourceByRegex =
    let
      src1 = pkgs.lib.sourceByRegex ./.  [ "^test-sourceByRegex.nix$" ];
      src2 = pkgs.lib.sourceByRegex src1 [ "^test-sourceByRegex.nix$" ];
    in src2 + "/test-sourceByRegex.nix";
} ''
 cp $test_sourceByRegex $out
''
EOI
) > test-sourceByRegex.nix
nix-build test-sourceByRegex.nix
```
Diffstat (limited to 'lib/sources.nix')
-rw-r--r--lib/sources.nix16
1 files changed, 10 insertions, 6 deletions
diff --git a/lib/sources.nix b/lib/sources.nix
index 0ffadea8f1b..c4680087b24 100644
--- a/lib/sources.nix
+++ b/lib/sources.nix
@@ -53,12 +53,16 @@ rec {
   # Filter sources by a list of regular expressions.
   #
   # E.g. `src = sourceByRegex ./my-subproject [".*\.py$" "^database.sql$"]`
-  sourceByRegex = src: regexes: cleanSourceWith {
-    filter = (path: type:
-      let relPath = lib.removePrefix (toString src + "/") (toString path);
-      in lib.any (re: builtins.match re relPath != null) regexes);
-    inherit src;
-  };
+  sourceByRegex = src: regexes:
+    let
+      isFiltered = src ? _isLibCleanSourceWith;
+      origSrc = if isFiltered then src.origSrc else src;
+    in lib.cleanSourceWith {
+      filter = (path: type:
+        let relPath = lib.removePrefix (toString origSrc + "/") (toString path);
+        in lib.any (re: builtins.match re relPath != null) regexes);
+      inherit src;
+    };
 
   # Get all files ending with the specified suffices from the given
   # directory or its descendants.  E.g. `sourceFilesBySuffices ./dir