From 67a10c88bbf0d359d71485decd002c6303351f2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dani=C3=ABl=20de=20Kok?= Date: Sun, 8 Nov 2020 08:47:12 +0100 Subject: [PATCH 1/2] buildRustPackage: add `cargoHash` for SRI hashes of vendored deps `buildRustPackage` currently accepts `cargoSha256` as a hash for vendored dependencies. This change adds `cargoHash` which accepts SRI hashes, setting `outputHashAlgo` to `null`. The hash mismatch message still uses `cargoSha256` as an example, which it probably should until we completely switch to SRI hashes. --- pkgs/build-support/rust/default.nix | 13 ++++++++++--- pkgs/build-support/rust/fetchCargoTarball.nix | 15 ++++++++++----- pkgs/tools/misc/broot/default.nix | 2 +- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/pkgs/build-support/rust/default.nix b/pkgs/build-support/rust/default.nix index 8e47a2b0bf2..9e8e32035d0 100644 --- a/pkgs/build-support/rust/default.nix +++ b/pkgs/build-support/rust/default.nix @@ -15,7 +15,13 @@ }: { name ? "${args.pname}-${args.version}" -, cargoSha256 ? "unset" + + # SRI hash +, cargoHash ? "" + + # Legacy hash +, cargoSha256 ? "" + , src ? null , srcs ? null , unpackPhase ? null @@ -46,7 +52,7 @@ , buildAndTestSubdir ? null , ... } @ args: -assert cargoVendorDir == null -> cargoSha256 != "unset"; +assert cargoVendorDir == null -> !(cargoSha256 == "" && cargoHash == ""); assert buildType == "release" || buildType == "debug"; let @@ -54,6 +60,7 @@ let cargoDeps = if cargoVendorDir == null then fetchCargoTarball ({ inherit name src srcs sourceRoot unpackPhase cargoUpdateHook; + hash = cargoHash; patches = cargoPatches; sha256 = cargoSha256; } // depsExtraArgs) @@ -61,7 +68,7 @@ let # If we have a cargoSha256 fixed-output derivation, validate it at build time # against the src fixed-output derivation to check consistency. - validateCargoDeps = cargoSha256 != "unset"; + validateCargoDeps = !(cargoHash == "" && cargoSha256 == ""); # Some cargo builds include build hooks that modify their own vendor # dependencies. This copies the vendor directory into the build tree and makes diff --git a/pkgs/build-support/rust/fetchCargoTarball.nix b/pkgs/build-support/rust/fetchCargoTarball.nix index dff5d99da9e..0726e5cfa5a 100644 --- a/pkgs/build-support/rust/fetchCargoTarball.nix +++ b/pkgs/build-support/rust/fetchCargoTarball.nix @@ -22,11 +22,17 @@ in , srcs ? [] , patches ? [] , sourceRoot -, sha256 +, hash ? "" +, sha256 ? "" , cargoUpdateHook ? "" , ... } @ args: -stdenv.mkDerivation ({ + +let hash_ = + if hash != "" then { outputHashAlgo = null; outputHash = hash; } + else if sha256 != "" then { outputHashAlgo = "sha256"; outputHash = sha256; } + else throw "fetchCargoTarball requires a hash for ${name}"; +in stdenv.mkDerivation ({ name = "${name}-vendor.tar.gz"; nativeBuildInputs = [ cacert git cargo-vendor-normalise cargo ]; @@ -40,7 +46,7 @@ stdenv.mkDerivation ({ echo echo "ERROR: The Cargo.lock file doesn't exist" echo - echo "Cargo.lock is needed to make sure that cargoSha256 doesn't change" + echo "Cargo.lock is needed to make sure that cargoHash/cargoSha256 doesn't change" echo "when the registry is updated." echo @@ -72,8 +78,7 @@ stdenv.mkDerivation ({ -czf $out $name ''; - outputHashAlgo = "sha256"; - outputHash = sha256; + inherit (hash_) outputHashAlgo outputHash; impureEnvVars = stdenv.lib.fetchers.proxyImpureEnvVars; } // (builtins.removeAttrs args [ diff --git a/pkgs/tools/misc/broot/default.nix b/pkgs/tools/misc/broot/default.nix index 4e40a4a336d..e4561c38228 100644 --- a/pkgs/tools/misc/broot/default.nix +++ b/pkgs/tools/misc/broot/default.nix @@ -18,7 +18,7 @@ rustPlatform.buildRustPackage rec { sha256 = "04nidx43w4nnccgbrw30wg9ai8p7hbklxpn1gc6gr2325yhqvwhl"; }; - cargoSha256 = "1bzq0dsdnmxniwnb6989wlhih28c4lyd11sci821whs11lhlfpz0"; + cargoHash = "sha256-4F9HIQ1BQx4EikyH0DwlDAkYIeUJJbMsj7ZX23QD+K8="; nativeBuildInputs = [ makeWrapper From b6728fa15c540b02fb6a336e1f6f6bb9d287f298 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dani=C3=ABl=20de=20Kok?= Date: Thu, 3 Dec 2020 09:39:39 +0100 Subject: [PATCH 2/2] docs/rust: describe cargoHash --- doc/languages-frameworks/rust.section.md | 35 +++++++++++++++++++----- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/doc/languages-frameworks/rust.section.md b/doc/languages-frameworks/rust.section.md index 0230993d3f0..fe394b662bb 100644 --- a/doc/languages-frameworks/rust.section.md +++ b/doc/languages-frameworks/rust.section.md @@ -27,16 +27,16 @@ Rust applications are packaged by using the `buildRustPackage` helper from `rust ``` rustPlatform.buildRustPackage rec { pname = "ripgrep"; - version = "11.0.2"; + version = "12.1.1"; src = fetchFromGitHub { owner = "BurntSushi"; repo = pname; rev = version; - sha256 = "1iga3320mgi7m853la55xip514a3chqsdi1a1rwv25lr9b1p7vd3"; + sha256 = "1hqps7l5qrjh9f914r5i6kmcz6f1yb951nv4lby0cjnp5l253kps"; }; - cargoSha256 = "17ldqr3asrdcsh4l29m3b5r37r5d0b3npq1lrgjmxb6vlx6a36qh"; + cargoSha256 = "03wf9r2csi6jpa7v5sw5lpxkrk4wfzwmzx7k3991q3bdjzcwnnwp"; meta = with stdenv.lib; { description = "A fast line-oriented regex search tool, similar to ag and ack"; @@ -47,10 +47,31 @@ rustPlatform.buildRustPackage rec { } ``` -`buildRustPackage` requires a `cargoSha256` attribute which is computed over -all crate sources of this package. Currently it is obtained by inserting a -fake checksum into the expression and building the package once. The correct -checksum can then be taken from the failed build. +`buildRustPackage` requires either the `cargoSha256` or the +`cargoHash` attribute which is computed over all crate sources of this +package. `cargoHash256` is used for traditional Nix SHA-256 hashes, +such as the one in the example above. `cargoHash` should instead be +used for [SRI](https://www.w3.org/TR/SRI/) hashes. For example: + +``` + cargoHash = "sha256-l1vL2ZdtDRxSGvP0X/l3nMw8+6WF67KPutJEzUROjg8="; +``` + +Both types of hashes are permitted when contributing to nixpkgs. The +Cargo hash is obtained by inserting a fake checksum into the +expression and building the package once. The correct checksum can +then be taken from the failed build. A fake hash can be used for +`cargoSha256` as follows: + +``` + cargoSha256 = stdenv.lib.fakeSha256; +``` + +For `cargoHash` you can use: + +``` + cargoHash = stdenv.lib.fakeHash; +``` Per the instructions in the [Cargo Book](https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html) best practices guide, Rust applications should always commit the `Cargo.lock`