From e143f551961ae845c3240cef3bb18f6dcc2c4fbc Mon Sep 17 00:00:00 2001 From: Dustin Blackman Date: Thu, 30 Nov 2023 20:15:24 -0500 Subject: [PATCH] feat: Add Windows support --- .github/workflows/test.yml | 23 ++++++++++- Cargo.lock | 83 ++++++++++++++++++++++---------------- Cargo.toml | 25 ++++++------ rust-toolchain.toml | 2 +- src/binary.rs | 13 +++--- src/cli.rs | 4 +- src/shims.rs | 52 +++++++++++++++++++----- 7 files changed, 135 insertions(+), 67 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index c4537a0..fc9c32f 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -3,7 +3,7 @@ on: [push, pull_request] name: ci jobs: - build_and_test: + test_coverage: name: cargo-run-bin runs-on: ubuntu-latest steps: @@ -30,3 +30,24 @@ jobs: with: github-token: ${{ secrets.GITHUB_TOKEN }} path-to-lcov: ./lcov.info + + test: + name: cargo-run-bin + strategy: + matrix: + os: [macos-latest, windows-latest] + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v2 + - uses: actions-rs/toolchain@v1 + with: + toolchain: stable + - uses: Swatinem/rust-cache@v2 + with: + cache-directories: ".bin" + - name: Install deps + run: | + cargo install --path . + cargo bin --build + - name: Test + run: cargo cmd test diff --git a/Cargo.lock b/Cargo.lock index 425727e..63fac7e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,15 +4,16 @@ version = 3 [[package]] name = "anstream" -version = "0.5.0" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1f58811cfac344940f1a400b6e6231ce35171f614f26439e80f8c1465c5cc0c" +checksum = "0ca84f3628370c59db74ee214b3263d58f9aadd9b4fe7e711fd87dc452b7f163" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", + "is-terminal", "utf8parse", ] @@ -42,9 +43,9 @@ dependencies = [ [[package]] name = "anstyle-wincon" -version = "2.1.0" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58f54d10c6dfa51283a066ceab3ec1ab78d13fae00aa49243a45e4571fb79dfd" +checksum = "c677ab05e09154296dd37acecd46420c17b9713e8366facafa8fc0885167cf4c" dependencies = [ "anstyle", "windows-sys 0.48.0", @@ -52,9 +53,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.75" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" +checksum = "28b2cd92db5cbd74e8e5028f7e27dd7aa3090e89e4f2a197cc7c8dfb69c7063b" [[package]] name = "assert_cmd" @@ -101,6 +102,7 @@ dependencies = [ "anyhow", "assert_cmd", "cargo-husky", + "cfg-if", "clap", "insta", "owo-colors", @@ -120,20 +122,26 @@ dependencies = [ "libc", ] +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + [[package]] name = "clap" -version = "4.4.4" +version = "4.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1d7b8d5ec32af0fadc644bf1fd509a688c2103b185644bb1e29d164e0703136" +checksum = "5fd304a20bff958a57f04c4e96a2e7594cc4490a0e809cbd48bb6437edaa452d" dependencies = [ "clap_builder", ] [[package]] name = "clap_builder" -version = "4.4.4" +version = "4.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5179bb514e4d7c2051749d8fcefa2ed6d06a9f4e6d69faf3805f5d80b8cf8d56" +checksum = "01c6a3f08f1fe5662a35cfe393aec09c4df95f60ee93b7556505260f75eee9e1" dependencies = [ "anstream", "anstyle", @@ -223,13 +231,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" [[package]] -name = "home" -version = "0.5.5" +name = "hermit-abi" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" -dependencies = [ - "windows-sys 0.48.0", -] +checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" [[package]] name = "indexmap" @@ -243,9 +248,9 @@ dependencies = [ [[package]] name = "insta" -version = "1.32.0" +version = "1.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e02c584f4595792d09509a94cdb92a3cef7592b1eb2d9877ee6f527062d0ea" +checksum = "a0770b0a3d4c70567f0d58331f3088b0e4c4f56c9b8d764efe654b4a5d46de3a" dependencies = [ "console", "lazy_static", @@ -255,6 +260,17 @@ dependencies = [ "yaml-rust", ] +[[package]] +name = "is-terminal" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" +dependencies = [ + "hermit-abi", + "rustix", + "windows-sys 0.48.0", +] + [[package]] name = "itertools" version = "0.11.0" @@ -373,18 +389,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.188" +version = "1.0.149" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" +checksum = "256b9932320c590e707b94576e3cc1f7c9024d0ee6612dfbcf1cb106cbe8e055" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.188" +version = "1.0.149" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" +checksum = "b4eae9b04cbffdfd550eb462ed33bc6a1b68c935127d008b27444d08380f94e4" dependencies = [ "proc-macro2", "quote", @@ -405,9 +421,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" -version = "2.0.37" +version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7303ef2c05cd654186cb250d29049a24840ca25d2747c25c0381c8d9e2f582e8" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" dependencies = [ "proc-macro2", "quote", @@ -422,9 +438,9 @@ checksum = "3369f5ac52d5eb6ab48c6b4ffdc8efbcad6b89c765749064ba298f2c68a16a76" [[package]] name = "toml" -version = "0.5.11" +version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" +checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7" dependencies = [ "serde", ] @@ -437,9 +453,9 @@ checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" [[package]] name = "toml_edit" -version = "0.19.15" +version = "0.19.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +checksum = "f8123f27e969974a3dfba720fdb560be359f57b44302d280ba72e76a74480e8a" dependencies = [ "indexmap", "toml_datetime", @@ -460,9 +476,9 @@ checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" [[package]] name = "version_check" -version = "0.9.4" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" [[package]] name = "wait-timeout" @@ -475,14 +491,13 @@ dependencies = [ [[package]] name = "which" -version = "4.4.2" +version = "4.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" +checksum = "2441c784c52b289a054b7201fc93253e288f094e2f4be9058343127c4226a269" dependencies = [ "either", - "home", + "libc", "once_cell", - "rustix", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index e9a4bcf..e0c055e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,22 +16,23 @@ name = "cargo-bin" path = "src/main.rs" [dependencies] -anyhow = "1.0.40" -clap = "4.3.19" -owo-colors = "3.5.0" -serde = { version = "1.0.149", features = ["derive"] } -toml = "0.5.9" -toml_edit = "0.19.14" -version_check = "0.9.3" -which = "4.4.0" +anyhow = "=1.0.40" +cfg-if = "=1.0.0" +clap = "=4.3.19" +owo-colors = "=3.5.0" +serde = { version = "=1.0.149", features = ["derive"] } +toml = "=0.5.9" +toml_edit = "=0.19.14" +version_check = "=0.9.3" +which = "=4.4.0" [dev-dependencies] -assert_cmd = "2.0.12" -cargo-husky = { version = "1.5.0", default-features = false, features = ["user-hooks"] } -insta = { version = "1.31.0", features = ["yaml"] } +assert_cmd = "=2.0.12" +cargo-husky = { version = "=1.5.0", default-features = false, features = ["user-hooks"] } +insta = { version = "=1.31.0", features = ["yaml"] } [package.metadata.bin] -cargo-binstall = { version = "1.4.4" } +cargo-binstall = { version = "1.4.6" } cargo-cmd = { version = "0.3.1" } cargo-deny = { version = "0.13.5" } cargo-dist = { version = "0.1.0-prerelease.10" } diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 9b2d918..33f37a5 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,3 +1,3 @@ [toolchain] -channel = "1.71.1" +channel = "1.74.0" components = ["rustfmt", "clippy", "llvm-tools-preview"] diff --git a/src/binary.rs b/src/binary.rs index c2ea18b..16404df 100644 --- a/src/binary.rs +++ b/src/binary.rs @@ -1,7 +1,6 @@ use std::env; use std::fs; use std::io; -use std::os::fd::AsFd; use std::path; use std::process; @@ -22,11 +21,10 @@ pub fn cargo_install( binary_package: metadata::BinaryPackage, cache_path: path::PathBuf, ) -> Result<()> { - let stderr = io::stderr().as_fd().try_clone_to_owned()?; let mut cmd_prefix = process::Command::new("cargo"); cmd_prefix - .stdout::(stderr.into()) + .stdout(io::stderr()) .stderr(process::Stdio::inherit()) .arg("install") .arg("--root") @@ -74,12 +72,10 @@ pub fn cargo_install( } pub fn binstall(binary_package: metadata::BinaryPackage, cache_path: path::PathBuf) -> Result<()> { - let stderr = io::stderr().as_fd().try_clone_to_owned()?; - let mut cmd_prefix = process::Command::new("cargo"); cmd_prefix - .stdout::(stderr.into()) + .stdout(io::stderr()) .stderr(process::Stdio::inherit()) .arg("binstall") .arg("--no-confirm") @@ -131,8 +127,11 @@ pub fn install(binary_package: metadata::BinaryPackage) -> Result { .join(binary_package.package.clone()) .join(binary_package.version.clone()); let cache_bin_path = cache_path.join("bin").join(bin_name); + let mut cache_bin_path_win = cache_bin_path.clone(); + cache_bin_path_win.set_extension("exe"); - if !path::Path::new(&cache_bin_path).exists() { + if !path::Path::new(&cache_bin_path).exists() && !path::Path::new(&cache_bin_path_win).exists() + { fs::create_dir_all(&cache_path)?; if binary_package.bin_target.is_none() && binary_package.features.is_none() diff --git a/src/cli.rs b/src/cli.rs index 07097ef..27316e6 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -122,7 +122,9 @@ pub fn run() -> Result<()> { app.print_long_help()?; } else { let mut args: Vec<_> = env::args().collect(); - let start_index = args.iter().position(|e| return e.ends_with("/cargo-bin")); + let start_index = args + .iter() + .position(|e| return e.ends_with("/cargo-bin") || e.ends_with("cargo-bin.exe")); if start_index.is_none() || start_index.unwrap() == (args.len() + 1) { app.print_long_help()?; return Ok(()); diff --git a/src/shims.rs b/src/shims.rs index 4b6d58a..b1f8c20 100644 --- a/src/shims.rs +++ b/src/shims.rs @@ -1,9 +1,10 @@ use std::env; use std::fs; use std::io::Write; -use std::os::unix::prelude::OpenOptionsExt; +use std::path; use anyhow::Result; +use cfg_if::cfg_if; use crate::metadata; @@ -11,7 +12,10 @@ use crate::metadata; #[path = "shims_test.rs"] mod shims_test; -fn create_shim(binary: &str) -> Result { +#[cfg(target_family = "unix")] +fn create_shim(binary: &str, bin_path: path::PathBuf) -> Result<()> { + use std::os::unix::prelude::OpenOptionsExt; + let shell = env::var("SHELL") .unwrap_or("bash".to_string()) .split('/') @@ -29,7 +33,33 @@ else fi"# ); - return Ok(script); + let mut f = fs::OpenOptions::new() + .create(true) + .write(true) + .mode(0o770) + .open(bin_path)?; + + write!(f, "{}", script)?; + + return Ok(()); +} + +#[cfg(not(target_family = "unix"))] +fn create_shim(binary: &str, bin_path: path::PathBuf) -> Result<()> { + let script = format!( + r#"@echo off +cargo bin {binary} %* +"# + ); + + let mut f = fs::OpenOptions::new() + .create(true) + .write(true) + .open(bin_path)?; + + write!(f, "{}", script)?; + + return Ok(()); } pub fn sync() -> Result<()> { @@ -48,18 +78,18 @@ pub fn sync() -> Result<()> { continue; } - let script = create_shim(&bin)?; - let bin_path = bin_dir.join(&bin); + let mut bin_path = bin_dir.join(&bin); + bin_path.set_extension(""); + cfg_if! { + if #[cfg(not(target_family = "unix"))] { + bin_path.set_extension("cmd"); + } + } if bin_path.exists() { continue; } - let mut f = fs::OpenOptions::new() - .create(true) - .write(true) - .mode(0o770) - .open(&bin_path)?; - write!(f, "{}", script)?; + create_shim(&bin, bin_path)?; } return Ok(());