Cargo: Patch Dependencies
There are several scenarios when you will need to override or patch upstream dependencies.
- Testing a bugfix of your crates before pushing to crates.io
- A non-working upstream crate has a new feature or a bug fix on the master branch of its git repository that you'd want to try.
- You've submitted a fix to an upstream crate for a bug you discovered, but you'd like your application to start using the fixed version of the crate immediately instead of waiting for the bug fix to be merged.
In these cases, the [patch]
section of Cargo.toml might be useful.
Patch dependencies from local
Let's say you're working with the uuid crate
but while you're working on it you discover a bug. You decide to try to fix the bug.
Originally your Cargo.toml manifest will look like this:
[package]
name = "my-library"
version = "0.1.0"
[dependencies]
uuid = "1.0"
First thing we'll do is to clone the uuid repository locally via:
$ git clone https://github.com/uuid-rs/uuid
Next we'll edit the Cargo.toml of my-library to contain:
[package]
name = "my-library"
version = "0.1.0"
[dependencies]
uuid = "1.0"
[patch.crates-io]
uuid = { path = "../path/to/uuid" }
Here we declare that we're patching the source crates-io with a new dependency.
This will effectively add the local checked out version of uuid to the crates.io
registry for our local package.
In any case, typically all you need to do now is:
$ cargo build
Compiling uuid v1.0.0 (.../uuid)
Compiling my-library v0.1.0 (.../my-library)
Finished dev [unoptimized + debuginfo] target(s) in 0.32 secs
Patch dependencies from your Github
Once you've fixed the bug you originally found the next thing you'll want to do is to likely submit that as a pull request to the uuid crate itself. Nevertheless, while you wait for your PR to be merged, you may begin using your patch by pushing it to your git repo and updating the [patch] section.:
[patch.crates-io]
uuid = { git = 'https://github.com/duyet/uuid-patched' }
Overriding repository URL
In case the dependency you want to override isn't loaded from crates.io, you'll have to change a bit how you use [patch]. For example, if the dependency is a git dependency, you can override it to a local path or another git dependency:
[dependencies]
uuid = { git = 'https://github.com/uuid-rs/uuid' }
[patch.'https://github.com/uuid-rs/uuid']
uuid = { git = "https://github.com/duyet/uuid-patched", branch = "2.0.0" }
You can also patch your lib from git dependency with the local folder:
[dependencies]
my-library = { git = 'https://github.com/duyet/mylib-rs' }
[patch.'https://github.com/duyet/mylib-rs']
my-library = { path = "../local/mylib" }
References
Related Posts
Cargo: workspace inheritance
Since 1.64.0, Cargo now supports workspace inheritance, so you can avoid duplicating similar field values between crates while working within a workspace. Workspace inheritance can include things like shared version numbers, repository URLs, or rust-version.
Rust: Why ? is good
In Rust, the question mark (?) operator is used as an alternate error propagation method for functions that yield Result or Option types. The ? operator is a shortcut that minimizes the amount of code required in a function to quickly return Err or None from the types Result<T, Err>, or Option.
Apache OpenDAL in Rust to Access Any Kind of Data Services
OpenDAL is a data access layer that allows users to easily and efficiently retrieve data from various storage services in a unified way such as S3, FTP, FS, Google Drive, HDFS, etc. They has been rewritten in Rust for the Core and have a binding from many various language like Python, Node.js, C, etc..
Fossil Data Platform Rewritten in Rust 🦀
My data engineering team at Fossil recently released some of Rust-based components of our Data Platform after faced performance and maintenance challenges of the old Python codebase. I would like to share the insights and lessons learned during the process of migrating Fossil's Data Platform from Python to Rust.