Skip to content

Commit cdfa625

Browse files
authored
fix(cli): properly read info when using yarn 2+, closes #4106 (#4193)
1 parent 55892c3 commit cdfa625

File tree

4 files changed

+93
-49
lines changed

4 files changed

+93
-49
lines changed

.changes/fix-berry-info-cli.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"cli.rs": patch
3+
"cli.js": patch
4+
---
5+
6+
Properly fetch the NPM dependency information when using Yarn 2+.

tooling/cli/src/info.rs

Lines changed: 77 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -75,10 +75,12 @@ struct CargoManifest {
7575
dependencies: HashMap<String, CargoManifestDependency>,
7676
}
7777

78+
#[derive(Debug, PartialEq, Eq)]
7879
enum PackageManager {
7980
Npm,
8081
Pnpm,
8182
Yarn,
83+
Berry,
8284
}
8385

8486
#[derive(Debug, Parser)]
@@ -165,6 +167,23 @@ fn npm_latest_version(pm: &PackageManager, name: &str) -> crate::Result<Option<S
165167
Ok(None)
166168
}
167169
}
170+
PackageManager::Berry => {
171+
let mut cmd = cross_command("yarn");
172+
173+
let output = cmd
174+
.arg("npm")
175+
.arg("info")
176+
.arg(name)
177+
.args(["--fields", "version", "--json"])
178+
.output()?;
179+
if output.status.success() {
180+
let info: crate::PackageJson =
181+
serde_json::from_reader(std::io::Cursor::new(output.stdout)).unwrap();
182+
Ok(info.version)
183+
} else {
184+
Ok(None)
185+
}
186+
}
168187
PackageManager::Npm => {
169188
let mut cmd = cross_command("npm");
170189

@@ -195,29 +214,46 @@ fn npm_package_version<P: AsRef<Path>>(
195214
name: &str,
196215
app_dir: P,
197216
) -> crate::Result<Option<String>> {
198-
let output = match pm {
199-
PackageManager::Yarn => cross_command("yarn")
200-
.args(&["list", "--pattern"])
201-
.arg(name)
202-
.args(&["--depth", "0"])
203-
.current_dir(app_dir)
204-
.output()?,
205-
PackageManager::Npm => cross_command("npm")
206-
.arg("list")
207-
.arg(name)
208-
.args(&["version", "--depth", "0"])
209-
.current_dir(app_dir)
210-
.output()?,
211-
PackageManager::Pnpm => cross_command("pnpm")
212-
.arg("list")
213-
.arg(name)
214-
.args(&["--parseable", "--depth", "0"])
215-
.current_dir(app_dir)
216-
.output()?,
217+
let (output, regex) = match pm {
218+
PackageManager::Yarn => (
219+
cross_command("yarn")
220+
.args(&["list", "--pattern"])
221+
.arg(name)
222+
.args(&["--depth", "0"])
223+
.current_dir(app_dir)
224+
.output()?,
225+
None,
226+
),
227+
PackageManager::Berry => (
228+
cross_command("yarn")
229+
.arg("info")
230+
.arg(name)
231+
.current_dir(app_dir)
232+
.output()?,
233+
Some(regex::Regex::new("Version: ([\\da-zA-Z\\-\\.]+)").unwrap()),
234+
),
235+
PackageManager::Npm => (
236+
cross_command("npm")
237+
.arg("list")
238+
.arg(name)
239+
.args(&["version", "--depth", "0"])
240+
.current_dir(app_dir)
241+
.output()?,
242+
None,
243+
),
244+
PackageManager::Pnpm => (
245+
cross_command("pnpm")
246+
.arg("list")
247+
.arg(name)
248+
.args(&["--parseable", "--depth", "0"])
249+
.current_dir(app_dir)
250+
.output()?,
251+
None,
252+
),
217253
};
218254
if output.status.success() {
219255
let stdout = String::from_utf8_lossy(&output.stdout);
220-
let regex = regex::Regex::new("@([\\da-zA-Z\\-\\.]+)").unwrap();
256+
let regex = regex.unwrap_or_else(|| regex::Regex::new("@([\\da-zA-Z\\-\\.]+)").unwrap());
221257
Ok(
222258
regex
223259
.captures_iter(&stdout)
@@ -530,7 +566,7 @@ impl VersionBlock {
530566
let target_version = semver::Version::parse(self.target_version.as_str()).unwrap();
531567
if version < target_version {
532568
print!(
533-
"({}, latest: {})",
569+
" ({}, latest: {})",
534570
"outdated".red(),
535571
self.target_version.green()
536572
);
@@ -613,6 +649,10 @@ pub fn command(_options: Options) -> Result<()> {
613649
.unwrap_or_default();
614650
panic::set_hook(hook);
615651

652+
let yarn_version = get_version("yarn", &[])
653+
.unwrap_or_default()
654+
.unwrap_or_default();
655+
616656
let metadata = version_metadata()?;
617657
VersionBlock::new(
618658
"Node.js",
@@ -640,13 +680,7 @@ pub fn command(_options: Options) -> Result<()> {
640680
.unwrap_or_default(),
641681
)
642682
.display();
643-
VersionBlock::new(
644-
"yarn",
645-
get_version("yarn", &[])
646-
.unwrap_or_default()
647-
.unwrap_or_default(),
648-
)
649-
.display();
683+
VersionBlock::new("yarn", &yarn_version).display();
650684
VersionBlock::new(
651685
"rustup",
652686
get_version("rustup", &[])
@@ -695,20 +729,23 @@ pub fn command(_options: Options) -> Result<()> {
695729

696730
let mut package_manager = PackageManager::Npm;
697731
if let Some(app_dir) = &app_dir {
698-
let file_names = read_dir(app_dir)
732+
let app_dir_entries = read_dir(app_dir)
699733
.unwrap()
700-
.filter(|e| {
701-
e.as_ref()
702-
.unwrap()
703-
.metadata()
704-
.unwrap()
705-
.file_type()
706-
.is_file()
707-
})
708734
.map(|e| e.unwrap().file_name().to_string_lossy().into_owned())
709735
.collect::<Vec<String>>();
710-
package_manager = get_package_manager(&file_names)?;
736+
package_manager = get_package_manager(&app_dir_entries)?;
737+
}
738+
739+
if package_manager == PackageManager::Yarn
740+
&& yarn_version
741+
.chars()
742+
.next()
743+
.map(|c| c > '1')
744+
.unwrap_or_default()
745+
{
746+
package_manager = PackageManager::Berry;
711747
}
748+
712749
VersionBlock::new(
713750
format!("{} {}", "@tauri-apps/cli", "[NPM]".dimmed()),
714751
metadata.js_cli.version,
@@ -852,12 +889,12 @@ pub fn command(_options: Options) -> Result<()> {
852889
Ok(())
853890
}
854891

855-
fn get_package_manager<T: AsRef<str>>(file_names: &[T]) -> crate::Result<PackageManager> {
892+
fn get_package_manager<T: AsRef<str>>(app_dir_entries: &[T]) -> crate::Result<PackageManager> {
856893
let mut use_npm = false;
857894
let mut use_pnpm = false;
858895
let mut use_yarn = false;
859896

860-
for name in file_names {
897+
for name in app_dir_entries {
861898
if name.as_ref() == "package-lock.json" {
862899
use_npm = true;
863900
} else if name.as_ref() == "pnpm-lock.yaml" {

tooling/cli/src/init.rs

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ use dialoguer::Input;
2525
use handlebars::{to_json, Handlebars};
2626
use include_dir::{include_dir, Dir};
2727
use log::warn;
28-
use serde::Deserialize;
2928

3029
const TEMPLATE_DIR: Dir<'_> = include_dir!("templates/app");
3130
const TAURI_CONF_TEMPLATE: &str = include_str!("../templates/tauri.conf.json");
@@ -63,12 +62,6 @@ pub struct Options {
6362
dev_path: Option<String>,
6463
}
6564

66-
#[derive(Deserialize)]
67-
struct PackageJson {
68-
name: Option<String>,
69-
product_name: Option<String>,
70-
}
71-
7265
#[derive(Default)]
7366
struct InitDefaults {
7467
app_name: Option<String>,
@@ -82,7 +75,7 @@ impl Options {
8275

8376
let init_defaults = if package_json_path.exists() {
8477
let package_json_text = read_to_string(package_json_path)?;
85-
let package_json: PackageJson = serde_json::from_str(&package_json_text)?;
78+
let package_json: crate::PackageJson = serde_json::from_str(&package_json_text)?;
8679
let (framework, _) = infer_framework(&package_json_text);
8780
InitDefaults {
8881
app_name: package_json.product_name.or(package_json.name),

tooling/cli/src/lib.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,25 @@ use clap::{FromArgMatches, IntoApp, Parser, Subcommand};
1717
use env_logger::fmt::Color;
1818
use env_logger::Builder;
1919
use log::{debug, log_enabled, Level};
20+
use serde::Deserialize;
2021
use std::ffi::OsString;
2122
use std::io::Write;
2223
use std::process::{Command, Output};
2324

24-
#[derive(serde::Deserialize)]
25+
#[derive(Deserialize)]
2526
pub struct VersionMetadata {
2627
tauri: String,
2728
#[serde(rename = "tauri-build")]
2829
tauri_build: String,
2930
}
3031

32+
#[derive(Deserialize)]
33+
pub struct PackageJson {
34+
name: Option<String>,
35+
version: Option<String>,
36+
product_name: Option<String>,
37+
}
38+
3139
#[derive(Parser)]
3240
#[clap(
3341
author,

0 commit comments

Comments
 (0)