summaryrefslogtreecommitdiffstats
path: root/pkgs/rust/lib/crate2nix-package.nix
diff options
context:
space:
mode:
Diffstat (limited to 'pkgs/rust/lib/crate2nix-package.nix')
-rw-r--r--pkgs/rust/lib/crate2nix-package.nix26
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 =