about summary refs log tree commit diff
diff options
context:
space:
mode:
authorIlan Joselevich <personal@ilanjoselevich.com>2024-08-17T16·50+0300
committerIlan Joselevich <personal@ilanjoselevich.com>2024-08-23T17·03+0000
commit6da55dc1a6c91db2b507bb8fec0ddcedfe65e6c3 (patch)
tree995ad4260ec0932379aaa8c32f60a80bbe41c93b
parentafef485221953ac00fcf35f206af9d9e250c4944 (diff)
feat(tvix/utils): Add mkCrate2nixCheck r/8565
This adds a function which can be used across the monorepo to create a
an extra CI step that checks whether the Cargo.nix file is up-to-date.

Change-Id: Idb8298b29ddc2ca5dff1facb1b9ed86a236ee66d
Reviewed-on: https://cl.tvl.fyi/c/depot/+/12227
Tested-by: BuildkiteCI
Reviewed-by: flokli <flokli@flokli.de>
-rw-r--r--tvix/default.nix67
-rw-r--r--tvix/utils.nix25
2 files changed, 36 insertions, 56 deletions
diff --git a/tvix/default.nix b/tvix/default.nix
index f8aa47a108c5..0791c17df04d 100644
--- a/tvix/default.nix
+++ b/tvix/default.nix
@@ -40,59 +40,6 @@ in
 {
   inherit crates protos;
 
-  # Run crate2nix generate, ensure the output doesn't differ afterwards
-  # (and doesn't fail).
-  #
-  # Currently this re-downloads every crate every time
-  # crate2nix-check (but not crate2nix) is built.
-  # TODO(amjoseph): be less wasteful with bandwidth.
-  #
-  crate2nix-check =
-    let
-      outputHashAlgo = "sha256";
-    in
-    pkgs.stdenv.mkDerivation {
-      inherit src;
-
-      # Important: we include the hash of all Cargo related files in the derivation name.
-      # This forces the FOD to be rebuilt/re-verified whenever one of them changes.
-      name = "tvix-crate2nix-check-" + builtins.substring 0 8 (builtins.hashString "sha256"
-        (lib.concatMapStrings (f: builtins.hashFile "sha256" f)
-          ([ ./Cargo.toml ./Cargo.lock ] ++ (map (m: ./. + "/${m}/Cargo.toml") (lib.importTOML ./Cargo.toml).workspace.members))
-        )
-      );
-
-      nativeBuildInputs = with pkgs; [ git cacert cargo ];
-      buildPhase = ''
-        export CARGO_HOME=$(mktemp -d)
-
-        # The following command can be omitted, in which case
-        # crate2nix-generate will run it automatically, but won't show the
-        # output, which makes it look like the build is somehow "stuck" for a
-        # minute or two.
-        cargo metadata > /dev/null
-
-        ${pkgs.crate2nix}/bin/crate2nix generate --all-features
-        ${pkgs.treefmt}/bin/treefmt Cargo.nix \
-          --no-cache \
-          --on-unmatched=debug \
-          --config-file=${depot.tools.depotfmt.config} \
-          --tree-root=.
-
-        # technically unnecessary, but provides more-helpful output in case of error
-        diff -ur Cargo.nix ${src}/Cargo.nix
-
-        # the FOD hash will check that the (re-)generated Cargo.nix matches the committed Cargo.nix
-        cp Cargo.nix $out
-      '';
-
-      # This is an FOD in order to allow `cargo` to perform network access.
-      outputHashMode = "flat";
-      inherit outputHashAlgo;
-      outputHash = builtins.hashFile outputHashAlgo ./Cargo.nix;
-      env.SSL_CERT_FILE = "${pkgs.cacert.out}/etc/ssl/certs/ca-bundle.crt";
-    };
-
   # Provide the Tvix logo in both .webp and .png format.
   logo = pkgs.runCommand "logo"
     {
@@ -158,12 +105,22 @@ in
     buildPhase = "cargo clippy --tests --all-features --benches --examples -- -Dwarnings | tee $out";
   };
 
+  crate2nix-check =
+    let
+      crate2nix-check = depot.tvix.utils.mkCrate2nixCheck ./Cargo.nix;
+    in
+    crate2nix-check.command.overrideAttrs {
+      meta.ci.extraSteps = {
+        inherit crate2nix-check;
+      };
+    };
+
   meta.ci.targets = [
     "clippy"
-    "crate2nix-check"
     "shell"
     "rust-docs"
+    "crate2nix-check"
   ];
 
-  utils = import ./utils.nix { inherit lib depot; };
+  utils = import ./utils.nix { inherit pkgs lib depot; };
 }
diff --git a/tvix/utils.nix b/tvix/utils.nix
index dc40df5007ea..c398930e7587 100644
--- a/tvix/utils.nix
+++ b/tvix/utils.nix
@@ -1,4 +1,4 @@
-{ lib, depot, ... }:
+{ pkgs, lib, depot, ... }:
 
 {
   mkFeaturePowerset = { crateName, features, override ? { } }:
@@ -125,4 +125,27 @@
         src = depot.tvix.utils.filterRustCrateSrc { root = prev.src.origSrc; };
       };
     };
+
+  # This creates an extraStep in CI to check whether the Cargo.nix file is up-to-date.
+  mkCrate2nixCheck =
+    path: # The path to the Cargo.nix to be checked.
+    let
+      relCrateRoot = lib.removePrefix "./" (builtins.dirOf (lib.path.removePrefix depot.path.origSrc path));
+    in
+    {
+      label = "crate2nix check for ${relCrateRoot}";
+      needsOutput = true;
+      alwaysRun = true;
+      command = pkgs.writeShellScript "crate2nix-check-for-${lib.replaceStrings [ "/" ] ["-"] relCrateRoot}" ''
+        (cd $(git rev-parse --show-toplevel)/${relCrateRoot} &&
+          ${depot.tools.crate2nix-generate}/bin/crate2nix-generate &&
+          if [[ -n "$(git status --porcelain -unormal Cargo.nix)" ]]; then
+              echo "----------------------------------------------------------------------------------------------------"
+              echo "Cargo.nix needs to be updated, run 'mg run //tools/crate2nix-generate' in ${relCrateRoot}"
+              echo "----------------------------------------------------------------------------------------------------"
+              exit 1
+          fi
+        )
+      '';
+    };
 }