diff --git a/Cargo.lock b/Cargo.lock index 6ac2ac6ac6404..23e94b4e6d118 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9283,6 +9283,7 @@ dependencies = [ "url", "vercel-api-mock", "webbrowser", + "which", ] [[package]] @@ -9310,6 +9311,7 @@ dependencies = [ "tempfile", "thiserror", "turbopath", + "which", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index d34beb647cc17..8a65e31d9fa2f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -197,3 +197,4 @@ tracing-subscriber = "0.3.16" url = "2.2.2" urlencoding = "2.1.2" webbrowser = "0.8.7" +which = "4.4.0" diff --git a/crates/turborepo-lib/Cargo.toml b/crates/turborepo-lib/Cargo.toml index caee9fa914514..c9cc93d45f127 100644 --- a/crates/turborepo-lib/Cargo.toml +++ b/crates/turborepo-lib/Cargo.toml @@ -93,6 +93,7 @@ turbo-updater = { workspace = true } turbopath = { workspace = true } turborepo-api-client = { workspace = true } webbrowser = { workspace = true } +which = { workspace = true } [target.'cfg(target_os = "windows")'.dependencies] diff --git a/crates/turborepo-lib/src/package_manager/yarn.rs b/crates/turborepo-lib/src/package_manager/yarn.rs index 966e67aff625d..58c7d4517bd0c 100644 --- a/crates/turborepo-lib/src/package_manager/yarn.rs +++ b/crates/turborepo-lib/src/package_manager/yarn.rs @@ -4,6 +4,7 @@ use anyhow::{anyhow, Context, Result}; use node_semver::{Range, Version}; use serde::Deserialize; use turbopath::{AbsoluteSystemPathBuf, RelativeSystemPathBuf}; +use which::which; use crate::package_manager::PackageManager; @@ -42,7 +43,8 @@ impl<'a> YarnDetector<'a> { return Ok(version.clone()); } - let output = Command::new("yarn") + let yarn_binary = which("yarn")?; + let output = Command::new(yarn_binary) .arg("--version") .current_dir(&self.repo_root) .output()?; diff --git a/crates/turborepo-scm/Cargo.toml b/crates/turborepo-scm/Cargo.toml index 9c40f507ce844..dd0e9e80988fd 100644 --- a/crates/turborepo-scm/Cargo.toml +++ b/crates/turborepo-scm/Cargo.toml @@ -12,6 +12,7 @@ dunce = { workspace = true } git2 = { version = "0.16.1", default-features = false } thiserror = { workspace = true } turbopath = { workspace = true } +which = { workspace = true } [dev-dependencies] tempfile = { workspace = true } diff --git a/crates/turborepo-scm/src/git.rs b/crates/turborepo-scm/src/git.rs index 79b45ad100948..c4706b57f6654 100644 --- a/crates/turborepo-scm/src/git.rs +++ b/crates/turborepo-scm/src/git.rs @@ -5,6 +5,7 @@ use std::{ use turbopath::{ AbsoluteSystemPath, AbsoluteSystemPathBuf, AnchoredSystemPathBuf, RelativeUnixPath, }; +use which::which; use crate::Error; @@ -76,7 +77,8 @@ fn execute_git_command( args: &[&str], pathspec: &str, ) -> Result, Error> { - let mut command = Command::new("git"); + let git_binary = which("git")?; + let mut command = Command::new(git_binary); command.args(args).current_dir(git_root); add_pathspec(&mut command, pathspec); @@ -156,7 +158,8 @@ pub fn previous_content( file_path.as_path().try_into()? }; - let mut command = Command::new("git"); + let git_binary = which("git")?; + let mut command = Command::new(git_binary); let command = command .arg("show") .arg(format!( @@ -190,6 +193,7 @@ mod tests { use git2::{Oid, Repository}; use tempfile::TempDir; use turbopath::{PathError, PathValidationError}; + use which::which; use super::previous_content; use crate::{git::changed_files, Error}; @@ -253,7 +257,9 @@ mod tests { #[test] fn test_shallow_clone() -> Result<(), Error> { let tmp_dir = tempfile::tempdir()?; - let output = Command::new("git") + + let git_binary = which("git")?; + let output = Command::new(git_binary) .args(&[ "clone", "--depth", diff --git a/crates/turborepo-scm/src/lib.rs b/crates/turborepo-scm/src/lib.rs index 86abdfc38d4e5..a24be7f8fd08e 100644 --- a/crates/turborepo-scm/src/lib.rs +++ b/crates/turborepo-scm/src/lib.rs @@ -19,4 +19,6 @@ pub enum Error { Io(#[from] std::io::Error, #[backtrace] backtrace::Backtrace), #[error("path error: {0}")] Path(#[from] PathError, #[backtrace] backtrace::Backtrace), + #[error("could not find git binary")] + GitBinaryNotFound(#[from] which::Error), } diff --git a/turborepo-tests/integration/tests/package_manager.t b/turborepo-tests/integration/tests/package_manager.t index 3dc469f3fcff1..aafc9c6055c61 100644 --- a/turborepo-tests/integration/tests/package_manager.t +++ b/turborepo-tests/integration/tests/package_manager.t @@ -36,3 +36,48 @@ Set package manager to pnpm in package.json Run test run $ ${TURBO} run build --__test-run | jq .package_manager "pnpm" + +Clear package manager field in package.json + $ jq 'del(.packageManager)' package.json > package.json.tmp && mv package.json.tmp package.json + +Delete package-lock.json + $ rm package-lock.json + +Use yarn 1.22.19 + $ corepack prepare yarn@1.22.19 --activate + Preparing yarn@1.22.19 for immediate activation... + +Create yarn.lock + $ touch yarn.lock + +Run test run + $ ${TURBO} run build --__test-run | jq .package_manager + "yarn" + +Use yarn 3.5.1 + $ corepack prepare yarn@3.5.1 --activate + Preparing yarn@3.5.1 for immediate activation... + +Run test run + $ ${TURBO} run build --__test-run | jq .package_manager + "berry" + +Delete yarn.lock + $ rm yarn.lock + +Create pnpm-lock.yaml + $ touch pnpm-lock.yaml + +Run test run + $ ${TURBO} run build --__test-run | jq .package_manager + "pnpm" + +Delete pnpm-lock.yaml + $ rm pnpm-lock.yaml + +Create package-lock.json + $ touch package-lock.json + +Run test run + $ ${TURBO} run build --__test-run | jq .package_manager + "npm" \ No newline at end of file