diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 74f9258..3b39e1a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,10 +8,6 @@ on: branches: - main -defaults: - run: - shell: bash - jobs: all: name: All @@ -49,4 +45,46 @@ jobs: run: cargo run -- --help - name: Test upt list + run: cargo run -- list + + msys2: + name: MSYS2 + + runs-on: windows-latest + + env: + RUSTFLAGS: --deny warnings + + steps: + - uses: actions/checkout@v4 + + - name: Install Rust Toolchain Components + uses: dtolnay/rust-toolchain@stable + + - uses: Swatinem/rust-cache@v2 + + - name: Test + run: cargo test --all + + - name: Clippy + run: cargo clippy --all --all-targets -- -D warnings + + - name: Format + run: cargo fmt --all --check + + - uses: msys2/setup-msys2@v2 + with: + path-type: inherit + + - name: Test upt --help on Windows Bash + if: runner.os == 'Windows' + run: cargo run -- --help + shell: bash + + - name: Test upt --help on MSYS2 + shell: msys2 {0} + run: cargo run -- --help + + - name: Test upt list + shell: msys2 {0} run: cargo run -- list \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index 8bcc9a5..e191295 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -8,5 +8,5 @@ mod utils; mod vendor; pub use error::UptError; -pub use utils::detect_os; +pub use utils::{detect_os, run_command}; pub use vendor::{detect_vendor, init_vendor, Vendor}; diff --git a/src/macros.rs b/src/macros.rs index cb912c2..184d9d3 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -65,6 +65,7 @@ macro_rules! os_vendors { $( $os => vec![$($tool),+].into_iter().filter_map(|tool| which_cmd(tool).map(|bin_name| (tool, bin_name))).collect(), )+ + "windows/msys2" => vec![("pacman","pacman")], _ => ["apt", "dnf", "pacman"].into_iter().map(|tool| (tool, tool)).collect(), }; match $crate::utils::find_tool(&pairs) { diff --git a/src/main.rs b/src/main.rs index 955b8a9..3798c33 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,11 +1,12 @@ -use std::env; use std::path::Path; -use std::process::{self, Command}; -use upt::{detect_os, detect_vendor, init_vendor, UptError, Vendor}; +use std::{env, process}; +use upt::{detect_os, detect_vendor, init_vendor, run_command, UptError, Vendor}; fn main() { match run() { - Ok(v) => v, + Ok(c) => { + process::exit(c); + } Err(e) => { eprintln!("{}", e); process::exit(1); @@ -13,7 +14,7 @@ fn main() { } } -fn run() -> Result<(), Box<dyn std::error::Error>> { +fn run() -> Result<i32, Box<dyn std::error::Error>> { let env_args = env::args().collect::<Vec<String>>(); let bin = Path::new(&env_args[0]) .file_stem() @@ -28,17 +29,17 @@ fn run() -> Result<(), Box<dyn std::error::Error>> { Ok(v) => v, Err(UptError::DisplayHelp(t)) => { println!("{t}"); - return Ok(()); + return Ok(0); } Err(e) => return Err(e.into()), }; if let Ok(v) = std::env::var("UPT_DRY_RUN") { if v == "true" || v == "1" { println!("{}", cmd); - return Ok(()); + return Ok(0); } } - run_cmd(cmd.as_str(), &os) + run_command(cmd.as_str(), &os) } fn create_cmd(vendor: &Vendor, args: &[String], os: &str) -> Result<String, UptError> { @@ -50,21 +51,3 @@ fn create_cmd(vendor: &Vendor, args: &[String], os: &str) -> Result<String, UptE let cmd = tool.eval(&task)?; Ok(cmd) } - -#[cfg(not(target_os = "windows"))] -fn run_cmd(cmd: &str, _os: &str) -> Result<(), Box<dyn std::error::Error>> { - let mut child = Command::new("sh").arg("-c").arg(cmd).spawn()?; - child.wait()?; - Ok(()) -} - -#[cfg(target_os = "windows")] -fn run_cmd(cmd: &str, os: &str) -> Result<(), Box<dyn std::error::Error>> { - let mut child = if os == "windows/msys2" { - Command::new("sh").arg("-c").arg(cmd).spawn()? - } else { - Command::new("cmd").args(["/C", cmd]).spawn()? - }; - child.wait()?; - Ok(()) -} diff --git a/src/utils.rs b/src/utils.rs index 5ca06e9..e5fdced 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,3 +1,5 @@ +use std::process::Command; + use which::which; pub fn find_tool(pairs: &[(&str, &str)]) -> Option<String> { @@ -38,11 +40,15 @@ pub fn find_tool(pairs: &[(&str, &str)]) -> Option<String> { #[cfg(target_os = "windows")] pub fn detect_os() -> Option<String> { - if let Ok(true) = std::env::var("OSTYPE").map(|v| v == "msys") { - Some("windows/msys2".to_string()) - } else { - Some("windows".to_string()) + if std::env::var("MSYSTEM").is_ok() { + let os = "windows/msys2"; + if let Ok(output) = Command::new("sh").arg("-c").arg("which pacman").output() { + if output.status.success() { + return Some(os.to_string()); + } + } } + Some("windows".to_string()) } #[cfg(target_os = "macos")] @@ -72,3 +78,12 @@ pub fn detect_os() -> Option<String> { let id = id[3..].trim_matches('"'); Some(id.to_string()) } + +pub fn run_command(cmd: &str, os: &str) -> Result<i32, Box<dyn std::error::Error>> { + let exit_status = if os == "windows" { + Command::new("cmd").args(["/C", cmd]).status()? + } else { + Command::new("sh").arg("-c").arg(cmd).status()? + }; + Ok(exit_status.code().unwrap_or_default()) +} diff --git a/src/vendor.rs b/src/vendor.rs index 05444b9..2daa9ff 100644 --- a/src/vendor.rs +++ b/src/vendor.rs @@ -41,7 +41,6 @@ os_vendors!( "garuda" => "pacman"; "antergos" => "pacman"; "kaos" => "pacman"; - "windows/msys2" => "pacman"; // apk "alpine" => "apk"; "postmarket" => "apk";