Add a --bin argument to mirror cargo install --bin. (#2189)

* Add a --bin argument to mirror cargo install --bin.

* Update crates/bin/src/args.rs

Co-authored-by: Jiahao XU <30436523+NobodyXu@users.noreply.github.com>
Signed-off-by: Matan Lurey <matanlurey@users.noreply.github.com>

* Update crates/binstalk/src/ops.rs

Co-authored-by: Jiahao XU <30436523+NobodyXu@users.noreply.github.com>
Signed-off-by: Matan Lurey <matanlurey@users.noreply.github.com>

* Address feedback, make e2e-test test both source/non-source.

* Update crates/bin/src/entry.rs

Co-authored-by: Jiahao XU <30436523+NobodyXu@users.noreply.github.com>
Signed-off-by: Matan Lurey <matanlurey@users.noreply.github.com>

* Update crates/binstalk/src/ops/resolve/resolution.rs

Co-authored-by: Jiahao XU <30436523+NobodyXu@users.noreply.github.com>
Signed-off-by: Matan Lurey <matanlurey@users.noreply.github.com>

* Update crates/binstalk/src/ops/resolve/resolution.rs

Co-authored-by: Jiahao XU <30436523+NobodyXu@users.noreply.github.com>
Signed-off-by: Matan Lurey <matanlurey@users.noreply.github.com>

* Update crates/binstalk/src/ops/resolve/resolution.rs

Co-authored-by: Jiahao XU <30436523+NobodyXu@users.noreply.github.com>
Signed-off-by: Matan Lurey <matanlurey@users.noreply.github.com>

* Get everything compiling again.

* optimize ResolutionFetch::resolve_bins

Signed-off-by: Jiahao XU <30436523+NobodyXu@users.noreply.github.com>

* fix e2e-test on unix due to ordering

Signed-off-by: Jiahao XU <30436523+NobodyXu@users.noreply.github.com>

* fix specific-binaries.sh: relax no-compile

Signed-off-by: Jiahao XU <30436523+NobodyXu@users.noreply.github.com>

---------

Signed-off-by: Matan Lurey <matanlurey@users.noreply.github.com>
Signed-off-by: Jiahao XU <30436523+NobodyXu@users.noreply.github.com>
Co-authored-by: Jiahao XU <30436523+NobodyXu@users.noreply.github.com>
This commit is contained in:
Matan Lurey 2025-06-10 04:17:48 -07:00 committed by GitHub
parent ea65a39d2d
commit 8d2b46b8bd
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 83 additions and 6 deletions

View file

@ -93,6 +93,20 @@ pub struct Args {
)]
pub(crate) targets: Option<Vec<String>>,
/// Install only the specified binaries.
///
/// This mirrors the equivalent argument in `cargo install --bin`.
///
/// If omitted, all binaries are installed.
#[clap(
help_heading = "Package selection",
long,
value_name = "BINARY",
num_args = 1..,
action = clap::ArgAction::Append
)]
pub(crate) bin: Option<Vec<CompactString>>,
/// Override Cargo.toml package manifest path.
///
/// This skips searching crates.io for a manifest and uses the specified path directly, useful

View file

@ -157,6 +157,10 @@ pub fn install_crates(
desired_targets,
resolvers,
cargo_install_fallback,
bins: args.bin.map(|mut bins| {
bins.sort_unstable();
bins
}),
temp_dir: temp_dir.path().to_owned(),
install_path,

View file

@ -2,6 +2,7 @@
use std::{path::PathBuf, sync::Arc, time::Duration};
use compact_str::CompactString;
use semver::VersionReq;
use crate::{
@ -45,6 +46,9 @@ pub struct Options {
pub resolvers: Vec<Resolver>,
pub cargo_install_fallback: bool,
/// If provided, the names are sorted.
pub bins: Option<Vec<CompactString>>,
pub temp_dir: PathBuf,
pub install_path: PathBuf,
pub cargo_root: Option<PathBuf>,

View file

@ -1,5 +1,6 @@
use std::{borrow::Cow, env, ffi::OsStr, fmt, iter, path::Path, sync::Arc};
use binstalk_bins::BinFile;
use command_group::AsyncCommandGroup;
use compact_str::{CompactString, ToCompactString};
use either::Either;
@ -87,14 +88,27 @@ impl ResolutionFetch {
current_version: self.new_version,
source: self.source,
target: self.fetcher.target().to_compact_string(),
bins: self
.bin_files
.into_iter()
.map(|bin| bin.base_name)
.collect(),
bins: Self::resolve_bins(&opts.bins, self.bin_files),
})
}
fn resolve_bins(
user_specified_bins: &Option<Vec<CompactString>>,
crate_bin_files: Vec<BinFile>,
) -> Vec<CompactString> {
// We need to filter crate_bin_files by user_specified_bins in case the prebuilt doesn't
// have featured-gated (optional) binary (gated behind feature).
crate_bin_files
.into_iter()
.map(|bin| bin.base_name)
.filter(|bin_name| {
user_specified_bins
.as_ref()
.map_or(true, |bins| bins.binary_search(bin_name).is_ok())
})
.collect()
}
pub fn print(&self, opts: &Options) {
let fetcher = &self.fetcher;
let bin_files = &self.bin_files;
@ -185,6 +199,12 @@ impl ResolutionSource {
cmd.arg("--no-track");
}
if let Some(bins) = &opts.bins {
for bin in bins {
cmd.arg("--bin").arg(bin);
}
}
debug!("Running `{}`", format_cmd(&cmd));
if !opts.dry_run {

33
e2e-tests/specific-binaries.sh Executable file
View file

@ -0,0 +1,33 @@
#!/bin/bash
set -euxo pipefail
unset CARGO_INSTALL_ROOT
CARGO_HOME=$(mktemp -d 2>/dev/null || mktemp -d -t 'cargo-home')
export CARGO_HOME
export PATH="$CARGO_HOME/bin:$PATH"
# Install a specific binary, ensuring we don't fallback to source.
"./$1" binstall --no-confirm taplo-cli --bin taplo
# Verify that the binary was installed and is executable
if ! command -v taplo >/dev/null 2>&1; then
echo "taplo was not installed"
exit 1
fi
# Run the binary to check it works
taplo --version
# Install a specific binary, but always compile from source.
"./$1" binstall --no-confirm ripgrep --bin rg --strategies compile
# Verify that the binary was installed and is executable
if ! command -v rg >/dev/null 2>&1; then
echo "rg was not installed"
exit 1
fi
# Run the binary to check it works
rg --version

View file

@ -224,6 +224,7 @@ e2e-test-signing: (e2e-test "signing")
e2e-test-continue-on-failure: (e2e-test "continue-on-failure")
e2e-test-private-github-repo: (e2e-test "private-github-repo")
e2e-test-self-install: (e2e-test "self-install")
e2e-test-specific-binaries: (e2e-test "specific-binaries")
# WinTLS (Windows in CI) does not have TLS 1.3 support
[windows]
@ -232,7 +233,8 @@ e2e-test-tls: (e2e-test "tls" "1.2")
[macos]
e2e-test-tls: (e2e-test "tls" "1.2") (e2e-test "tls" "1.3")
e2e-tests: e2e-test-live e2e-test-manifest-path e2e-test-git e2e-test-other-repos e2e-test-strategies e2e-test-version-syntax e2e-test-upgrade e2e-test-tls e2e-test-self-upgrade-no-symlink e2e-test-uninstall e2e-test-subcrate e2e-test-no-track e2e-test-registries e2e-test-signing e2e-test-continue-on-failure e2e-test-private-github-repo e2e-test-self-install
# e2e-test-self-install needs to be the last task to run, as it would consume the cargo-binstall binary
e2e-tests: e2e-test-live e2e-test-manifest-path e2e-test-git e2e-test-other-repos e2e-test-strategies e2e-test-version-syntax e2e-test-upgrade e2e-test-tls e2e-test-self-upgrade-no-symlink e2e-test-uninstall e2e-test-subcrate e2e-test-no-track e2e-test-registries e2e-test-signing e2e-test-continue-on-failure e2e-test-private-github-repo e2e-test-specific-binaries e2e-test-self-install
unit-tests: print-env
cargo test --no-run --target {{target}}