diff options
Diffstat (limited to 'pkgs/rust/lib')
| -rw-r--r-- | pkgs/rust/lib/crate2nix-package.nix | 26 |
1 files changed, 24 insertions, 2 deletions
diff --git a/pkgs/rust/lib/crate2nix-package.nix b/pkgs/rust/lib/crate2nix-package.nix index d97a97e..ee75096 100644 --- a/pkgs/rust/lib/crate2nix-package.nix +++ b/pkgs/rust/lib/crate2nix-package.nix @@ -12,6 +12,7 @@ # nixpkgs' defaultCrateOverrides still apply inside buildRustCrate. { pkgs +, lib ? pkgs.lib , applyOverride , name @@ -26,6 +27,9 @@ # IFD only; Cargo.json has its features baked in , features ? [ "default" ] +# Cargo.lock the JSON plan must match; null: no check +, cargoLock ? null + , resolvedJson ? null }: @@ -67,8 +71,26 @@ let inherit buildRustCrateForPkgs; }; - cargoNix = - if useJson then fromJson else fromLock; + # Fails evaluation if the plan uses a crate version the lock doesn't have, + # i.e. Cargo.lock changed since Cargo.json was generated. Dependencies added + # to the lock aren't detected, since the plan may leave out crates for + # features or targets it doesn't use; those fail the build instead. + checkLock = result: + let + id = name: version: "${name} ${version}"; + lockPackages = (builtins.fromTOML (builtins.readFile cargoLock)).package; + locked = builtins.listToAttrs (map + (p: { name = id p.name p.version; value = null; }) + (builtins.filter (p: p ? source) lockPackages)); + planned = lib.mapAttrsToList (_: c: id c.crateName c.version) + (lib.filterAttrs (_: c: (c.source.type or "local") != "local") + (builtins.fromJSON (builtins.readFile resolvedJson')).crates); + missing = builtins.filter (i: !(locked ? ${i})) planned; + in + if cargoLock == null || missing == [] then result + else throw "crate2nix-package: ${toString resolvedJson'} is stale against ${toString cargoLock}; not in the lock: ${lib.concatStringsSep ", " (lib.take 5 missing)}${lib.optionalString (builtins.length missing > 5) ", ..."}"; + + cargoNix = if useJson then checkLock fromJson else fromLock; in cargoNix // { build = |
