Awesome
<h1 align=center>cargo-run-bin</h1>Build, cache, and run CLI tools scoped in
Cargo.toml
rather than installing globally. Stop the version drifts across your team, keep it all in sync within your project!
Overview
Installing tooling globally when working in teams or on CI is a silly problem to manage. cargo-run-bin
builds, caches, and executes binaries from their locked down versions in Cargo.toml
. This acts similarly to npm run
and gomodrun
, and allows your teams to always be running the same tooling versions.
For command lines that extend cargo such as cargo-nextest
, run-bin will create and manage cargo aliases to allow using cargo extensions without any changes to your command line scripts! cargo-run-bin
gets out of your way, and you'll forget you're even using it!
Install
Minimum Rust Version: 1.70.0
Run the following to install cargo-run-bin
, and ignore the cache directory in your project.
cargo install cargo-run-bin
cd my/rust/project
echo ".bin/" >> .gitignore
You can also use it as a library within your existing logic.
[dependencies]
cargo-run-bin = { version = "1.7.2", default-features = false }
Distro packages
<details> <summary>Packaging status</summary> </details>If your distribution has packaged cargo-run-bin
, you can use that package for the installation.
Arch Linux
You can use pacman to install from the extra repository:
pacman -S cargo-run-bin
Alpine Linux
cargo-run-bin
is available for Alpine Edge. It can be installed via apk after enabling the testing repository.
apk add cargo-run-bin
Usage
cargo-run-bin
keeps track of the binaries and their versions from within Cargo.toml
under the [package.metadata.bin]
.
table. A quick example taken from this repo:
[package.metadata.bin]
cargo-binstall = { version = "1.1.2" }
cargo-nextest = { version = "0.9.57", locked = true }
dprint = { version = "0.30.3" }
cargo-mobile2 = { version = "0.5.2", bins = ["cargo-android", "cargo-mobile"], locked = true }
Or if you're setting up in a workspace:
[workspace.metadata.bin]
cargo-binstall = { version = "1.1.2" }
cargo-nextest = { version = "0.9.57", locked = true }
Parameter | Type | Required | Description |
---|---|---|---|
version | String | true | Specifies the version of the crate. |
bins | Vec<String> | false | An array of binaries that the crate contains that you wish to build. These can be found in a crates Cargo.toml file. See cargo-mobile2 as an example. |
locked | Boolean | false | A parameter when set to true runs cargo install with the --locked parameter. |
features | Vec<String> | false | An array of crate features to enable. |
default-features | Boolean | false | When set to false , disables all default features. |
git | String | false | A git URL to install from rather than from crates.io. This will also be used by Binstall to look up Cargo manifist if Binstall is available. |
branch | String | false | A git branch to install from when git is set. This takes priority over tag and rev |
tag | String | false | A git tag to install from when git is set. branch will take priority if set, and takes priority over rev . |
rev | String | false | A git revision to install from when git is set. branch and tag will take priority if set. |
path | String | false | The path to a local crate to install. |
If you're a fan of prebuilt binaries and fast downloads, run-bin will use cargo-binstall
if it's installed globally, or configured within [package.metadata.bin]
, rather than building tools from source.
cargo bin CRATE
Taking an example of dprint
, running cargo bin dprint --help
with install/build and cache the dprint binary with the
specified version in Cargo.toml
. All future executions will run instantly without an install step, and dprint can be used
as you wish!
cargo bin --sync-aliases
With the power of cargo aliases, cargo bin --sync-aliases
will create aliases for any cargo-*
crate, allowing you to execute commands such cargo nextest run
that will use
cargo bin
under the hood. Check out some of the example from this repo.
cargo bin --install
When pulling down a new repo, or adding a step to CI, cargo bin --install
will install or build all binaries that have not been
cached which are configured in Cargo.toml
.
Library
run-bin
can also be used as a library and paired nicely with your build.rs
or any other scripts. The following
example demos having dprint
configured within [package.metadata.bin]
, and executing dprint --help
.
[package.metadata.bin]
dprint = { version = "0.40.2" }
use anyhow::Result;
use cargo_run_bin::{binary, metadata};
fn main() -> Result<()> {
let binary_package = metadata::get_binary_packages()?
.iter()
.find(|e| e.package == "dprint")
.unwrap()
.to_owned();
let bin_path = binary::install(binary_package)?;
binary::run(bin_path, vec!["--help".to_string()])?;
return Ok(());
}
Using binary::run
is optional. You can recreate it and make changes to your liking using std::process
, with shims included!
use std::process;
use anyhow::Result;
use cargo_run_bin::{binary, metadata, shims};
fn main() -> Result<()> {
let binary_package = metadata::get_binary_packages()?
.iter()
.find(|e| e.package == "dprint")
.unwrap()
.to_owned();
let bin_path = binary::install(binary_package)?;
let mut shell_paths = shims::get_shim_paths()?;
shell_paths.push(env::var("PATH").unwrap_or("".to_string()));
process::Command::new(bin_path)
.args(["--help"])
.env("PATH", shell_paths.join(":"))
.spawn();
return Ok(());
}
License
MIT.