Patching a Rust Package's Cargo.toml

Hello, I’m using Typst to write a document and I submitted patches to one of its dependencies a while ago (which got accepted) but the dependency (hayagriva) hasn’t had a release since and therefore Typst hasn’t bumped its version to include my patches. I submitted these patches back when I used Arch and now I want to use them on my NixOS machine.

I’d like to patch the Cargo.toml of typst to point at the commit hash of current HEAD of hayagriva rather than the latest release, but I’m not sure how to do that with a Nix package in a way that I can install it on my machine(s) easily.

Is there documentation somewhere for this that I’ve missed?

I have tried many different ways now and couldn’t overwrite a rust package with my local modified version so far. What I tried just now is following the instructions on: nixpkgs/doc/languages-frameworks/rust.section.md at dc47f56f1bc48c8e702e3244e6093e681aac487c · NixOS/nixpkgs · GitHub for building the package but it said error: attribute ‘rustPlatform’ missing. Let me know if you found a solution

I’ve been trying to write an overlay for it but so far I can’t figure out a way to patch it without maintaining my own typst repository.

I wasn’t fully expecting it to work, but I tried to just substituteInPlace the hayagriva line in the Cargo.toml to see if it would lead anywhere, this failed because cargo --offline is used. Then I thought I could fetch the hayagriva source, add it to the sourcetree of typst with a patch, and sub out the hayagriva line to point at the local hayagriva revision but it turns out that hayagrivas dependencies must have changed since the last release.

flake.nix:

{
  description = "Typst - patched with newer hayagriva";

  inputs = {
    nixpkgs.url = "https://channels.nixos.org/nixpkgs-unstable/nixexprs.tar.xz";
    flake-utils.url = "github:numtide/flake-utils";
  };

  outputs = {
    self,
    nixpkgs,
    flake-utils,
    ...
  }:
    flake-utils.lib.eachDefaultSystem (
      system: let
        pkgs = import nixpkgs {inherit system;};

        hayagrivaSrc = pkgs.fetchFromGitHub {
          owner = "typst";
          repo = "hayagriva";
          rev = "a137441413a5907c15ced44d1502dfb9fa1a3014";
          hash = "sha256-8kQ94TGWHPJyg0XrDg9ROMCSuMuBdgiCzW2GiP5f2/I=";
        };

        patchedTypst = pkgs.typst.overrideAttrs (old: {
          postPatch =
            (old.postPatch or "")
            + ''
              cp -r ${hayagrivaSrc} crates/hayagriva
              substituteInPlace Cargo.toml \
                --replace-fail 'hayagriva = "0.9.1"' \
                               'hayagriva = { path = "crates/hayagriva" }'
            '';
          cargoHash = pkgs.lib.fakeHash;
        });
      in {
        packages.patched-typst = patchedTypst;
        defaultPackage = patchedTypst;
      }
    );
}

Current error:

error: Cannot build '/nix/store/shipydmcncnqkiv371gc4m5wsbs666i6-typst-0.14.2.drv'.
       Reason: builder failed with exit code 101.
       Output paths:
         /nix/store/8ka24iaz3yqmns3gqbhnrx9qcih06yrk-typst-0.14.2
       Last 21 log lines:
       > Using versionCheckHook
       > Running phase: unpackPhase
       > unpacking source archive /nix/store/06hjh717cbqgkns36azna4wdd4fbf20p-source
       > source root is source
       > Executing cargoSetupPostUnpackHook
       > Finished cargoSetupPostUnpackHook
       > Running phase: patchPhase
       > Executing cargoSetupPostPatchHook
       > Validating consistency between /build/source/Cargo.lock and /build/typst-0.14.2-vendor/Cargo.lock
       > Finished cargoSetupPostPatchHook
       > Running phase: updateAutotoolsGnuConfigScriptsPhase
       > Running phase: configurePhase
       > Running phase: buildPhase
       > Executing cargoBuildHook
       > cargoBuildHook flags: -j 16 --target x86_64-unknown-linux-gnu --offline --profile release
       > error: failed to select a version for the requirement `strum = "^0.26"`
       > candidate versions found which didn't match: 0.27.2
       > location searched: directory source `/build/typst-0.14.2-vendor` (which is replacing registry `crates-io`)
       > required by package `hayagriva v0.9.1 (/build/source/crates/hayagriva)`
       > perhaps a crate was updated and forgotten to be re-vendored?
       > As a reminder, you're using offline mode (--offline) which can sometimes cause surprising resolution failures, if this error is too confusing you may wish to retry without `--offline`.
       For full logs, run:
         nix log /nix/store/shipydmcncnqkiv371gc4m5wsbs666i6-typst-0.14.2.drv

I found a somewhat ugly way to patch it

flake.nix

{
  description = "Typst - patched with newer hayagriva";

  inputs = {
    nixpkgs.url = "https://channels.nixos.org/nixpkgs-unstable/nixexprs.tar.xz";
    flake-utils.url = "github:numtide/flake-utils";
  };

  outputs =
    {
      self,
      nixpkgs,
      flake-utils,
      ...
    }:
    flake-utils.lib.eachDefaultSystem (
      system:
      let
        pkgs = import nixpkgs { inherit system; };

        patchedTypst = pkgs.typst.overrideAttrs (old: {
          patches = [ ./hayagriva.patch ];
          cargoDeps = old.cargoDeps.overrideAttrs (old: {
            vendorStaging = old.vendorStaging.overrideAttrs {
              patches = [ ./hayagriva.patch ];
              outputHash = "sha256-5yOkNmnNJt/gLzU7Pwn751vzOxj0f6lriKj+NnUa1t4=";
            };
          });
        });
      in
      {
        packages.patched-typst = patchedTypst;
        defaultPackage = patchedTypst;
      }
    );
}

hayagriva.patch

--- a/Cargo.lock
+++ b/Cargo.lock
@@ -935,8 +935,7 @@ checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100"
 [[package]]
 name = "hayagriva"
 version = "0.9.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1cb69425736f184173b3ca6e27fcba440a61492a790c786b1c6af7e06a03e575"
+source = "git+https://github.com/typst/hayagriva?rev=a137441413a5907c15ced44d1502dfb9fa1a3014#a137441413a5907c15ced44d1502dfb9fa1a3014"
 dependencies = [
  "biblatex",
  "ciborium",
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -62,7 +62,7 @@ fontdb = { version = "0.23", default-features = false }
 fs_extra = "1.3"
 rustc-hash = "2.1"
 glidesort = "0.1.2"
-hayagriva = "0.9.1"
+hayagriva = { git = "https://github.com/typst/hayagriva", rev = "a137441413a5907c15ced44d1502dfb9fa1a3014" }
 hayro = { version = "0.4.0", default-features = false }
 hayro-svg = { version = "0.2.0", default-features = false }
 hayro-syntax = "0.4.0"

Ugly is fine for me, as long as it works. Will give it a try :slight_smile:

EDIT: works fine for now, would be nice for hayagriva to bump their version but I don’t want to be annoying.