Skip to content

Commit

Permalink
fix(turborepo): Use which crate to resolve yarn binary (#5001)
Browse files Browse the repository at this point in the history
### Description

Fixes #4940 by using `which` crate to resolve yarn binary. That way we
use the correct extension, i.e. `yarn.cmd` on Windows.


### Testing Instructions
Tested manually on Windows. Will add more integration tests

---------

Co-authored-by: --global <Nicholas Yang>
  • Loading branch information
NicholasLYang committed May 17, 2023
1 parent 9f73619 commit 3333dcb
Show file tree
Hide file tree
Showing 8 changed files with 64 additions and 4 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Expand Up @@ -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"
1 change: 1 addition & 0 deletions crates/turborepo-lib/Cargo.toml
Expand Up @@ -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]
Expand Down
4 changes: 3 additions & 1 deletion crates/turborepo-lib/src/package_manager/yarn.rs
Expand Up @@ -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;

Expand Down Expand Up @@ -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()?;
Expand Down
1 change: 1 addition & 0 deletions crates/turborepo-scm/Cargo.toml
Expand Up @@ -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 }
12 changes: 9 additions & 3 deletions crates/turborepo-scm/src/git.rs
Expand Up @@ -5,6 +5,7 @@ use std::{
use turbopath::{
AbsoluteSystemPath, AbsoluteSystemPathBuf, AnchoredSystemPathBuf, RelativeUnixPath,
};
use which::which;

use crate::Error;

Expand Down Expand Up @@ -76,7 +77,8 @@ fn execute_git_command(
args: &[&str],
pathspec: &str,
) -> Result<Vec<u8>, 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);
Expand Down Expand Up @@ -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!(
Expand Down Expand Up @@ -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};
Expand Down Expand Up @@ -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",
Expand Down
2 changes: 2 additions & 0 deletions crates/turborepo-scm/src/lib.rs
Expand Up @@ -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),
}
45 changes: 45 additions & 0 deletions turborepo-tests/integration/tests/package_manager.t
Expand Up @@ -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"

0 comments on commit 3333dcb

Please sign in to comment.