summary refs log tree commit diff
diff options
context:
space:
mode:
authorDaniël de Kok <me@danieldk.eu>2021-05-08 07:44:31 +0200
committerDaniël de Kok <me@danieldk.eu>2021-05-28 08:01:28 +0200
commitb3969f3ad793ee98af14cf0c649f626520943a53 (patch)
treea2d96f9e34dd6ad96d4d77b1207e8ae038532edb
parent2f46d77e2806dd22f4ec4ac6ea3f9981df81dd94 (diff)
downloadnixpkgs-b3969f3ad793ee98af14cf0c649f626520943a53.tar
nixpkgs-b3969f3ad793ee98af14cf0c649f626520943a53.tar.gz
nixpkgs-b3969f3ad793ee98af14cf0c649f626520943a53.tar.bz2
nixpkgs-b3969f3ad793ee98af14cf0c649f626520943a53.tar.lz
nixpkgs-b3969f3ad793ee98af14cf0c649f626520943a53.tar.xz
nixpkgs-b3969f3ad793ee98af14cf0c649f626520943a53.tar.zst
nixpkgs-b3969f3ad793ee98af14cf0c649f626520943a53.zip
rustPlatform.buildRustPackage: support direct use of Cargo.lock
This change introduces the cargoLock argument to buildRustPackage,
which can be used in place of cargo{Sha256,Hash} or cargoVendorDir. It
uses the importCargoLock function to build the vendor
directory. Differences compared to cargo{Sha256,Hash}:

- Requires a Cargo.lock file.
- Does not require a Cargo hash.
- Retrieves all dependencies as fixed-output derivations.

This makes buildRustPackage much easier to use as part of a Rust
project, since it does not require updating cargo{Sha256,Hash} for
every change to the lock file.
-rw-r--r--doc/languages-frameworks/rust.section.md48
-rw-r--r--pkgs/build-support/rust/default.nix25
-rw-r--r--pkgs/development/compilers/rust/make-rust-platform.nix2
3 files changed, 64 insertions, 11 deletions
diff --git a/doc/languages-frameworks/rust.section.md b/doc/languages-frameworks/rust.section.md
index 70aced7d5cb..008909e5c76 100644
--- a/doc/languages-frameworks/rust.section.md
+++ b/doc/languages-frameworks/rust.section.md
@@ -107,6 +107,54 @@ rustPlatform.buildRustPackage rec {
 }
 ```
 
+### Importing a `Cargo.lock` file
+
+Using `cargoSha256` or `cargoHash` is tedious when using
+`buildRustPackage` within a project, since it requires that the hash
+is updated after every change to `Cargo.lock`. Therefore,
+`buildRustPackage` also supports vendoring dependencies directly from
+a `Cargo.lock` file using the `cargoLock` argument. For example:
+
+```nix
+rustPlatform.buildRustPackage rec {
+  pname = "myproject";
+  version = "1.0.0";
+
+  cargoLock = {
+    lockFile = ./Cargo.lock;
+  }
+
+  # ...
+}
+```
+
+This will retrieve the dependencies using fixed-output derivations from
+the specified lockfile.
+
+The output hash of each dependency that uses a git source must be
+specified in the `outputHashes` attribute. For example:
+
+```nix
+rustPlatform.buildRustPackage rec {
+  pname = "myproject";
+  version = "1.0.0";
+
+  cargoLock = {
+    lockFile = ./Cargo.lock;
+    outputHashes = {
+      "finalfusion-0.14.0" = "17f4bsdzpcshwh74w5z119xjy2if6l2wgyjy56v621skr2r8y904";
+    };
+  }
+
+  # ...
+}
+```
+
+If you do not specify an output hash for a git dependency, building
+the package will fail and inform you of which crate needs to be
+added. To find the correct hash, you can first use `lib.fakeSha256` or
+`lib.fakeHash` as a stub hash. Building the package (and thus the
+vendored dependencies) will then inform you of the correct hash.
 
 ### Cross compilation
 
diff --git a/pkgs/build-support/rust/default.nix b/pkgs/build-support/rust/default.nix
index ff9ca642daa..711276116a6 100644
--- a/pkgs/build-support/rust/default.nix
+++ b/pkgs/build-support/rust/default.nix
@@ -7,6 +7,7 @@
 , cargoInstallHook
 , cargoSetupHook
 , fetchCargoTarball
+, importCargoLock
 , runCommandNoCC
 , rustPlatform
 , callPackage
@@ -41,6 +42,7 @@
 , cargoDepsHook ? ""
 , buildType ? "release"
 , meta ? {}
+, cargoLock ? null
 , cargoVendorDir ? null
 , checkType ? buildType
 , depsExtraArgs ? {}
@@ -55,19 +57,22 @@
 , buildAndTestSubdir ? null
 , ... } @ args:
 
-assert cargoVendorDir == null -> !(cargoSha256 == "" && cargoHash == "");
+assert cargoVendorDir == null && cargoLock == null -> cargoSha256 == "" && cargoHash == ""
+  -> throw "cargoSha256, cargoHash, cargoVendorDir, or cargoLock must be set";
 assert buildType == "release" || buildType == "debug";
 
 let
 
-  cargoDeps = if cargoVendorDir == null
-    then fetchCargoTarball ({
-        inherit src srcs sourceRoot unpackPhase cargoUpdateHook;
-        name = cargoDepsName;
-        hash = cargoHash;
-        patches = cargoPatches;
-        sha256 = cargoSha256;
-      } // depsExtraArgs)
+  cargoDeps =
+    if cargoVendorDir == null
+    then if cargoLock != null then importCargoLock cargoLock
+    else fetchCargoTarball ({
+      inherit src srcs sourceRoot unpackPhase cargoUpdateHook;
+      name = cargoDepsName;
+      hash = cargoHash;
+      patches = cargoPatches;
+      sha256 = cargoSha256;
+    } // depsExtraArgs)
     else null;
 
   # If we have a cargoSha256 fixed-output derivation, validate it at build time
@@ -96,7 +101,7 @@ in
 # See https://os.phil-opp.com/testing/ for more information.
 assert useSysroot -> !(args.doCheck or true);
 
-stdenv.mkDerivation ((removeAttrs args ["depsExtraArgs"]) // lib.optionalAttrs useSysroot {
+stdenv.mkDerivation ((removeAttrs args [ "depsExtraArgs" "cargoLock" ]) // lib.optionalAttrs useSysroot {
   RUSTFLAGS = "--sysroot ${sysroot} " + (args.RUSTFLAGS or "");
 } // {
   inherit buildAndTestSubdir cargoDeps;
diff --git a/pkgs/development/compilers/rust/make-rust-platform.nix b/pkgs/development/compilers/rust/make-rust-platform.nix
index 2343fd74901..2a38933df16 100644
--- a/pkgs/development/compilers/rust/make-rust-platform.nix
+++ b/pkgs/development/compilers/rust/make-rust-platform.nix
@@ -13,7 +13,7 @@ rec {
 
   buildRustPackage = callPackage ../../../build-support/rust {
     inherit cargoBuildHook cargoCheckHook cargoInstallHook cargoSetupHook
-      fetchCargoTarball rustc;
+      fetchCargoTarball importCargoLock rustc;
   };
 
   importCargoLock = buildPackages.callPackage ../../../build-support/rust/import-cargo-lock.nix {};