Optimize searching for cargo configuration files

* Rather than recursively look up all paths in a given project and then
  filtering for cargo-specific files, we now use our own customized
  traversal method to only capture the results we want.
This commit is contained in:
Ivan Petkov 2022-01-28 18:24:51 -08:00
parent 4a2dd7388c
commit 5bae4b91c1
4 changed files with 58 additions and 18 deletions

View File

@ -380,6 +380,18 @@ vendoring.
* `source`: the source key recorded in the Cargo.lock file * `source`: the source key recorded in the Cargo.lock file
* `version`: the version of the crate * `version`: the version of the crate
### `lib.findCargoFiles`
`findCargoFiles :: path -> set of lists`
Given a path, recursively search it for any `Cargo.toml`, `.cargo/config` or
`.cargo/config.toml` files.
```nix
lib.findCargoFiles ./src
# { cargoTomls = [ "..." ]; cargoConfigs = [ "..." ]; }
```
### `lib.fromTOML` ### `lib.fromTOML`
`fromTOML :: String -> set` `fromTOML :: String -> set`

View File

@ -21,6 +21,7 @@ lib.makeScope newScope (self:
cleanCargoToml = callPackage ./cleanCargoToml.nix { }; cleanCargoToml = callPackage ./cleanCargoToml.nix { };
crateNameFromCargoToml = callPackage ./crateNameFromCargoToml.nix { }; crateNameFromCargoToml = callPackage ./crateNameFromCargoToml.nix { };
downloadCargoPackage = callPackage ./downloadCargoPackage.nix { }; downloadCargoPackage = callPackage ./downloadCargoPackage.nix { };
findCargoFiles = callPackage ./findCargoFiles.nix { };
mkCargoDerivation = callPackage ./mkCargoDerivation.nix { }; mkCargoDerivation = callPackage ./mkCargoDerivation.nix { };
mkDummySrc = callPackage ./mkDummySrc.nix { }; mkDummySrc = callPackage ./mkDummySrc.nix { };
urlForCargoPackage = callPackage ./urlForCargoPackage.nix { }; urlForCargoPackage = callPackage ./urlForCargoPackage.nix { };

41
lib/findCargoFiles.nix Normal file
View File

@ -0,0 +1,41 @@
{ lib
}:
src:
let
inherit (lib)
flatten
lists
mapAttrs
mapAttrsToList;
# A specialized form of lib.listFilesRecursive except it will only look
# for Cargo.toml and config.toml files to keep the intermediate results lean
listFilesRecursive = parentIsDotCargo: dir: flatten (mapAttrsToList
(name: type:
let
cur = dir + "/${name}";
isConfig = parentIsDotCargo && (name == "config" || name == "config.toml");
isCargoToml = name == "Cargo.toml";
in
if type == "directory"
then listFilesRecursive (name == ".cargo") cur
else if isCargoToml
then [{ path = cur; type = "cargoTomls"; }]
else if isConfig
then [{ path = cur; type = "cargoConfigs"; }]
else [ ]
)
(builtins.readDir dir));
foundFiles = listFilesRecursive false src;
grouped = builtins.groupBy (x: x.type) foundFiles;
cleaned = mapAttrs (_: map (y: y.path)) grouped;
# Ensure we have a well typed result
default = {
cargoTomls = [ ];
cargoConfigs = [ ];
};
in
default // cleaned

View File

@ -1,4 +1,5 @@
{ cleanCargoToml { cleanCargoToml
, findCargoFiles
, lib , lib
, runCommand , runCommand
, writeText , writeText
@ -13,12 +14,10 @@ let
inherit (builtins) inherit (builtins)
dirOf dirOf
concatStringsSep concatStringsSep
filter
hasAttr hasAttr
pathExists; pathExists;
inherit (lib) inherit (lib)
hasSuffix
optionalString optionalString
removePrefix; removePrefix;
@ -34,22 +33,9 @@ let
cp -f ${dummyrs} ${prefix}/${path} cp -f ${dummyrs} ${prefix}/${path}
''; '';
allPaths = lib.filesystem.listFilesRecursive src; inherit (findCargoFiles src)
cargoTomls
isCargoToml = path: hasSuffix "Cargo.toml" path; cargoConfigs;
isCargoConfig = path:
let
p = toString path;
matches = s: hasSuffix s p;
# Cargo accepts one of two file names for its configuration.
# Just copy whatever we find and let cargo sort it out.
# https://doc.rust-lang.org/cargo/reference/config.html
isMatch = matches ".cargo/config" || matches ".cargo/config.toml";
in
isMatch;
cargoConfigs = filter isCargoConfig allPaths;
cargoTomls = filter isCargoToml allPaths;
basePath = (toString src) + "/"; basePath = (toString src) + "/";
copyAllCargoConfigs = concatStrings (map copyAllCargoConfigs = concatStrings (map