Skip to content

Commit 2771155

Browse files
authored
findCargoFiles: take source filters into account when searching (#987)
The fact that we search the original source (e.g. avoid IFD and source renaming quirks) means we effectively ignore filtering (including git ignore filters) which means we might end up finding (and later parsing) totally invalid files. This change remedies that. #985
1 parent db590d9 commit 2771155

10 files changed

Lines changed: 92 additions & 33 deletions

File tree

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,12 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
1414
`--show-progress=...` will take precedence). This avoids progress bar
1515
(re)painting from resulting in garbled build logs
1616

17+
### Fixed
18+
* `findCargoFiles` (and by extension `mkDummySrc` and `vendorCargoDeps`) will
19+
now always respect source filters, meaning any ignored `Cargo.toml` or
20+
`.cargo/config.toml` files will no longer be processed and included during
21+
processing.
22+
1723
## [0.23.1] - 2026-02-14
1824

1925
### Added

checks/default.nix

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,14 @@ onlyDrvs (
438438
};
439439
};
440440

441+
# https://github.com/ipetkov/crane/issues/985
442+
filesetIgnoredInvalidCargotoml = myLib.buildPackage {
443+
src = lib.fileset.toSource {
444+
root = ./simple-with-extra-invalid-cargo-toml;
445+
fileset = lib.fileset.difference ./simple-with-extra-invalid-cargo-toml ./simple-with-extra-invalid-cargo-toml/invalid;
446+
};
447+
};
448+
441449
filesetWorkspace = myLib.buildPackage {
442450
src = lib.fileset.toSource {
443451
root = ./workspace;
@@ -599,6 +607,14 @@ onlyDrvs (
599607
'';
600608
};
601609

610+
# https://github.com/ipetkov/crane/issues/985
611+
simpleIgnoredInvalidCargotoml = myLib.buildPackage {
612+
src = lib.cleanSourceWith {
613+
src = ./simple-with-extra-invalid-cargo-toml;
614+
filter = path: type: !(type == "directory" && lib.hasSuffix "invalid" path);
615+
};
616+
};
617+
602618
simpleNoDeps = myLib.buildPackage {
603619
src = myLib.cleanCargoSource ./simple-no-deps;
604620
cargoVendorDir = "/dev/null";

checks/simple-with-extra-invalid-cargo-toml/Cargo.lock

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
[package]
2+
name = "simple"
3+
version = "0.1.0"
4+
edition = "2021"
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"something": "invalid"
3+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
fn main() {}

docs/API.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1177,6 +1177,12 @@ The default filter applied by `cleanCargoToml`. Currently corresponds to
11771177
Given a path, recursively search it for any `Cargo.toml`, `.cargo/config` or
11781178
`.cargo/config.toml` files.
11791179

1180+
Note: if `src` is the result of `lib.cleanSource`, `lib.cleanSourceWith`, or
1181+
`lib.fileset.toSource` the embedded filtering logic will be respected (i.e. if
1182+
the result of the cleaned source would ignore certain `Cargo.toml` or
1183+
`.cargo/config.toml` files, they will also be omitted in the results here). The
1184+
resulting files will use paths from the original (unfiltered) source.
1185+
11801186
```nix
11811187
craneLib.findCargoFiles ./src
11821188
# { cargoTomls = [ "..." ]; cargoConfigs = [ "..." ]; }

lib/findCargoFiles.nix

Lines changed: 41 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2,56 +2,70 @@
22
lib,
33
}:
44

5-
src:
65
let
76
inherit (lib)
87
flatten
8+
flip
99
groupBy
1010
mapAttrs
1111
mapAttrsToList
12+
optionals
1213
;
14+
defaultFilter = _: _: true;
1315

1416
# A specialized form of lib.listFilesRecursive except it will only look
1517
# for Cargo.toml and config.toml files to keep the intermediate results lean
1618
listFilesRecursive =
17-
parentIsDotCargo: dir:
19+
filter: parentIsDotCargo: dir:
1820
flatten (
19-
mapAttrsToList (
21+
flip mapAttrsToList (builtins.readDir dir) (
2022
name: type:
2123
let
22-
cur = dir + "/${name}";
24+
cur = builtins.unsafeDiscardStringContext ((toString dir) + "/${name}");
25+
2326
isConfig = parentIsDotCargo && (name == "config.toml" || name == "config");
2427
isCargoToml = name == "Cargo.toml";
2528
in
26-
if type == "directory" then
27-
listFilesRecursive (name == ".cargo") cur
28-
else if isCargoToml then
29-
[
30-
{
31-
path = cur;
32-
type = "cargoTomls";
33-
}
34-
]
35-
else if isConfig then
36-
[
37-
{
38-
path = cur;
39-
type = "cargoConfigs";
40-
}
41-
]
42-
else
43-
[ ]
44-
) (builtins.readDir dir)
29+
# NB: manually apply any cleanSourceWith filtering here to avoid surprises
30+
# in accidentally finding files that were meant to be excluded
31+
# https://github.com/ipetkov/crane/issues/985
32+
optionals (filter cur type) (
33+
if type == "directory" then
34+
listFilesRecursive filter (name == ".cargo") cur
35+
else if isCargoToml then
36+
[
37+
{
38+
path = cur;
39+
type = "cargoTomls";
40+
}
41+
]
42+
else if isConfig then
43+
[
44+
{
45+
path = cur;
46+
type = "cargoConfigs";
47+
}
48+
]
49+
else
50+
[ ]
51+
)
52+
)
4553
);
4654

47-
foundFiles = listFilesRecursive false src;
48-
grouped = groupBy (x: x.type) foundFiles;
49-
cleaned = mapAttrs (_: map (y: y.path)) grouped;
50-
5155
# Ensure we have a well typed result
5256
default = {
5357
cargoTomls = [ ];
5458
cargoConfigs = [ ];
5559
};
5660
in
61+
src:
62+
let
63+
isCleanSourceWith = src._isLibCleanSourceWith or false;
64+
origSrc = if isCleanSourceWith then src.origSrc or src else src;
65+
filter = if isCleanSourceWith then src.filter or defaultFilter else defaultFilter;
66+
67+
foundFiles = listFilesRecursive filter false origSrc;
68+
grouped = groupBy (x: x.type) foundFiles;
69+
cleaned = mapAttrs (_: map (y: y.path)) grouped;
70+
in
5771
default // cleaned

lib/mkDummySrc.nix

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,10 +96,12 @@ let
9696
# whose prefix won't match the paths we observe when we try to clean the source a bit further down
9797
# (Nix optimizes multiple filters by running them all once against the original source).
9898
# https://github.com/ipetkov/crane/issues/46
99-
origSrc = if src ? _isLibCleanSourceWith then src.origSrc else src;
100-
99+
origSrc = if src._isLibCleanSourceWith or false then src.origSrc else src;
101100
uncleanSrcBasePath = builtins.unsafeDiscardStringContext ((toString origSrc) + "/");
102-
uncleanFiles = findCargoFiles origSrc;
101+
# NB: findCargoFiles will apply any cleanSourceWith filters so we pass in the original
102+
# src (not origSrc) here which will give us the best of both worlds
103+
# https://github.com/ipetkov/crane/issues/985
104+
uncleanFiles = findCargoFiles src;
103105

104106
cargoTomlsBase = uncleanSrcBasePath;
105107
inherit (uncleanFiles) cargoTomls;

lib/vendorCargoDeps.nix

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@ let
1313

1414
inherit (lib.attrsets) optionalAttrs;
1515

16-
origSrc = src: if src ? _isLibCleanSourceWith then src.origSrc else src;
17-
18-
cargoConfigs = if args ? src then (findCargoFiles (origSrc args.src)).cargoConfigs else [ ];
16+
# NB: findCargoFiles will apply any filtering for us here so we don't need to check origSrc
17+
cargoConfigs = if args ? src then (findCargoFiles args.src).cargoConfigs else [ ];
1918

19+
origSrc = src: if src._isLibCleanSourceWith or false then src.origSrc else src;
2020
src = origSrc (
2121
args.src or (throw ''
2222
unable to find `src` attribute. consider one of the following:

0 commit comments

Comments
 (0)