diff --git a/.changes/cli-yarn-berry.md b/.changes/cli-yarn-berry.md new file mode 100644 index 000000000..6c75565de --- /dev/null +++ b/.changes/cli-yarn-berry.md @@ -0,0 +1,6 @@ +--- +"tauri-cli": "patch:bug" +"@tauri-apps/cli": "patch:bug" +--- + +Fix detecting yarn berry (v2 and higher) in various tauri cli commands. diff --git a/crates/tauri-cli/src/add.rs b/crates/tauri-cli/src/add.rs index ceb735333..f02771d97 100644 --- a/crates/tauri-cli/src/add.rs +++ b/crates/tauri-cli/src/add.rs @@ -81,10 +81,7 @@ pub fn run(options: Options) -> Result<()> { })?; if !metadata.rust_only { - if let Some(manager) = frontend_dir - .map(PackageManager::from_project) - .and_then(|managers| managers.into_iter().next()) - { + if let Some(manager) = frontend_dir.map(PackageManager::from_project) { let npm_version_req = version .map(ToString::to_string) .or(metadata.version_req.as_ref().map(|v| match manager { diff --git a/crates/tauri-cli/src/helpers/npm.rs b/crates/tauri-cli/src/helpers/npm.rs index 8e6134bb1..d1591f78d 100644 --- a/crates/tauri-cli/src/helpers/npm.rs +++ b/crates/tauri-cli/src/helpers/npm.rs @@ -7,6 +7,22 @@ use anyhow::Context; use crate::helpers::cross_command; use std::{fmt::Display, path::Path, process::Command}; +pub fn manager_version(package_manager: &str) -> Option { + cross_command(package_manager) + .arg("-v") + .output() + .map(|o| { + if o.status.success() { + let v = String::from_utf8_lossy(o.stdout.as_slice()).to_string(); + Some(v.split('\n').next().unwrap().to_string()) + } else { + None + } + }) + .ok() + .unwrap_or_default() +} + #[derive(Debug, PartialEq, Eq, Clone, Copy)] pub enum PackageManager { Npm, @@ -35,7 +51,16 @@ impl Display for PackageManager { } impl PackageManager { - pub fn from_project>(path: P) -> Vec { + /// Detects package manager from the given directory, falls back to [`PackageManager::Npm`]. + pub fn from_project>(path: P) -> Self { + Self::all_from_project(path) + .first() + .copied() + .unwrap_or(Self::Npm) + } + + /// Detects all possible package managers from the given directory. + pub fn all_from_project>(path: P) -> Vec { let mut found = Vec::new(); if let Ok(entries) = std::fs::read_dir(path) { @@ -47,7 +72,15 @@ impl PackageManager { } else if name.as_ref() == "pnpm-lock.yaml" { found.push(PackageManager::Pnpm); } else if name.as_ref() == "yarn.lock" { - found.push(PackageManager::Yarn); + let yarn = if manager_version("yarn") + .map(|v| v.chars().next().map(|c| c > '1').unwrap_or_default()) + .unwrap_or(false) + { + PackageManager::YarnBerry + } else { + PackageManager::Yarn + }; + found.push(yarn); } else if name.as_ref() == "bun.lockb" { found.push(PackageManager::Bun); } else if name.as_ref() == "deno.lock" { diff --git a/crates/tauri-cli/src/info/env_nodejs.rs b/crates/tauri-cli/src/info/env_nodejs.rs index 5d210429c..eb9938eee 100644 --- a/crates/tauri-cli/src/info/env_nodejs.rs +++ b/crates/tauri-cli/src/info/env_nodejs.rs @@ -5,23 +5,7 @@ use super::{ActionResult, SectionItem, VersionMetadata}; use colored::Colorize; -use crate::helpers::cross_command; - -pub fn manager_version(package_manager: &str) -> Option { - cross_command(package_manager) - .arg("-v") - .output() - .map(|o| { - if o.status.success() { - let v = String::from_utf8_lossy(o.stdout.as_slice()).to_string(); - Some(v.split('\n').next().unwrap().to_string()) - } else { - None - } - }) - .ok() - .unwrap_or_default() -} +use crate::helpers::{cross_command, npm::manager_version}; pub fn items(metadata: &VersionMetadata) -> Vec { let node_target_ver = metadata.js_cli.node.replace(">= ", ""); diff --git a/crates/tauri-cli/src/info/packages_nodejs.rs b/crates/tauri-cli/src/info/packages_nodejs.rs index f484ffd20..73b87d8b7 100644 --- a/crates/tauri-cli/src/info/packages_nodejs.rs +++ b/crates/tauri-cli/src/info/packages_nodejs.rs @@ -3,7 +3,7 @@ // SPDX-License-Identifier: MIT use super::SectionItem; -use super::{env_nodejs::manager_version, VersionMetadata}; +use super::VersionMetadata; use colored::Colorize; use serde::Deserialize; use std::path::PathBuf; @@ -77,7 +77,7 @@ pub fn npm_latest_version(pm: &PackageManager, name: &str) -> crate::Result PackageManager { - let found = PackageManager::from_project(frontend_dir); + let found = PackageManager::all_from_project(frontend_dir); if found.is_empty() { println!( @@ -98,15 +98,7 @@ pub fn package_manager(frontend_dir: &PathBuf) -> PackageManager { ); } - if pkg_manager == PackageManager::Yarn - && manager_version("yarn") - .map(|v| v.chars().next().map(|c| c > '1').unwrap_or_default()) - .unwrap_or(false) - { - PackageManager::YarnBerry - } else { - pkg_manager - } + pkg_manager } pub fn items( diff --git a/crates/tauri-cli/src/init.rs b/crates/tauri-cli/src/init.rs index cbd4ae1a0..f12bc4abf 100644 --- a/crates/tauri-cli/src/init.rs +++ b/crates/tauri-cli/src/init.rs @@ -131,10 +131,7 @@ impl Options { ) })?; - let detected_package_manager = match PackageManager::from_project(&self.directory).first() { - Some(&package_manager) => package_manager, - None => PackageManager::Npm, - }; + let detected_package_manager = PackageManager::from_project(&self.directory); self.before_dev_command = self .before_dev_command diff --git a/crates/tauri-cli/src/migrate/migrations/v1/frontend.rs b/crates/tauri-cli/src/migrate/migrations/v1/frontend.rs index 83f906a90..8ad2771f3 100644 --- a/crates/tauri-cli/src/migrate/migrations/v1/frontend.rs +++ b/crates/tauri-cli/src/migrate/migrations/v1/frontend.rs @@ -84,10 +84,7 @@ pub fn migrate(frontend_dir: &Path) -> Result> { ) }; - let pm = PackageManager::from_project(frontend_dir) - .into_iter() - .next() - .unwrap_or(PackageManager::Npm); + let pm = PackageManager::from_project(frontend_dir); for pkg in ["@tauri-apps/cli", "@tauri-apps/api"] { let version = pm diff --git a/crates/tauri-cli/src/migrate/migrations/v2_rc.rs b/crates/tauri-cli/src/migrate/migrations/v2_rc.rs index 50ce8a37b..844c7de04 100644 --- a/crates/tauri-cli/src/migrate/migrations/v2_rc.rs +++ b/crates/tauri-cli/src/migrate/migrations/v2_rc.rs @@ -35,10 +35,7 @@ pub fn run() -> Result<()> { } fn migrate_npm_dependencies(frontend_dir: &Path) -> Result<()> { - let pm = PackageManager::from_project(frontend_dir) - .into_iter() - .next() - .unwrap_or(PackageManager::Npm); + let pm = PackageManager::from_project(frontend_dir); let mut install_deps = Vec::new(); for pkg in [