diff options
Diffstat (limited to 'pkgs')
| -rw-r--r-- | pkgs/rust/default.nix | 10 | ||||
| -rw-r--r-- | pkgs/rust/lib/crate2nix-package.nix | 26 |
2 files changed, 32 insertions, 4 deletions
diff --git a/pkgs/rust/default.nix b/pkgs/rust/default.nix index d273db6..f6c7eb7 100644 --- a/pkgs/rust/default.nix +++ b/pkgs/rust/default.nix @@ -30,6 +30,12 @@ let lib.optionalAttrs (builtins.pathExists (path + "/Cargo.json")) { resolvedJson = path + "/Cargo.json"; }; + + # The checkout's Cargo.lock, to check the JSON plan against. + localLock = path: + lib.optionalAttrs (builtins.pathExists (path + "/Cargo.lock")) { + cargoLock = path + "/Cargo.lock"; + }; in { @@ -72,10 +78,10 @@ in in if explicitPackages ? ${pname} then assert mylib.debug "pkgs/rust: overriding ${pname}.src with ${mylib.pretty dir}"; - hrmPlan explicitPackages.${pname} // callArgs explicitPackages.${pname} // { inherit src; } + hrmPlan explicitPackages.${pname} // callArgs explicitPackages.${pname} // { inherit src; } // localLock dir else assert mylib.debug "pkgs/rust: automatic package ${pname} from ${mylib.pretty dir}"; - { name = pname; inherit src; } + { name = pname; inherit src; } // localLock dir ) automaticPackages; 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 = |
