Skip to content

Commit

Permalink
fix(cli): properly read info when using yarn 2+, closes #4106 (#4193)
Browse files Browse the repository at this point in the history
  • Loading branch information
lucasfernog authored May 23, 2022
1 parent 55892c3 commit cdfa625
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 49 deletions.
6 changes: 6 additions & 0 deletions .changes/fix-berry-info-cli.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"cli.rs": patch
"cli.js": patch
---

Properly fetch the NPM dependency information when using Yarn 2+.
117 changes: 77 additions & 40 deletions tooling/cli/src/info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,12 @@ struct CargoManifest {
dependencies: HashMap<String, CargoManifestDependency>,
}

#[derive(Debug, PartialEq, Eq)]
enum PackageManager {
Npm,
Pnpm,
Yarn,
Berry,
}

#[derive(Debug, Parser)]
Expand Down Expand Up @@ -165,6 +167,23 @@ fn npm_latest_version(pm: &PackageManager, name: &str) -> crate::Result<Option<S
Ok(None)
}
}
PackageManager::Berry => {
let mut cmd = cross_command("yarn");

let output = cmd
.arg("npm")
.arg("info")
.arg(name)
.args(["--fields", "version", "--json"])
.output()?;
if output.status.success() {
let info: crate::PackageJson =
serde_json::from_reader(std::io::Cursor::new(output.stdout)).unwrap();
Ok(info.version)
} else {
Ok(None)
}
}
PackageManager::Npm => {
let mut cmd = cross_command("npm");

Expand Down Expand Up @@ -195,29 +214,46 @@ fn npm_package_version<P: AsRef<Path>>(
name: &str,
app_dir: P,
) -> crate::Result<Option<String>> {
let output = match pm {
PackageManager::Yarn => cross_command("yarn")
.args(&["list", "--pattern"])
.arg(name)
.args(&["--depth", "0"])
.current_dir(app_dir)
.output()?,
PackageManager::Npm => cross_command("npm")
.arg("list")
.arg(name)
.args(&["version", "--depth", "0"])
.current_dir(app_dir)
.output()?,
PackageManager::Pnpm => cross_command("pnpm")
.arg("list")
.arg(name)
.args(&["--parseable", "--depth", "0"])
.current_dir(app_dir)
.output()?,
let (output, regex) = match pm {
PackageManager::Yarn => (
cross_command("yarn")
.args(&["list", "--pattern"])
.arg(name)
.args(&["--depth", "0"])
.current_dir(app_dir)
.output()?,
None,
),
PackageManager::Berry => (
cross_command("yarn")
.arg("info")
.arg(name)
.current_dir(app_dir)
.output()?,
Some(regex::Regex::new("Version: ([\\da-zA-Z\\-\\.]+)").unwrap()),
),
PackageManager::Npm => (
cross_command("npm")
.arg("list")
.arg(name)
.args(&["version", "--depth", "0"])
.current_dir(app_dir)
.output()?,
None,
),
PackageManager::Pnpm => (
cross_command("pnpm")
.arg("list")
.arg(name)
.args(&["--parseable", "--depth", "0"])
.current_dir(app_dir)
.output()?,
None,
),
};
if output.status.success() {
let stdout = String::from_utf8_lossy(&output.stdout);
let regex = regex::Regex::new("@([\\da-zA-Z\\-\\.]+)").unwrap();
let regex = regex.unwrap_or_else(|| regex::Regex::new("@([\\da-zA-Z\\-\\.]+)").unwrap());
Ok(
regex
.captures_iter(&stdout)
Expand Down Expand Up @@ -530,7 +566,7 @@ impl VersionBlock {
let target_version = semver::Version::parse(self.target_version.as_str()).unwrap();
if version < target_version {
print!(
"({}, latest: {})",
" ({}, latest: {})",
"outdated".red(),
self.target_version.green()
);
Expand Down Expand Up @@ -613,6 +649,10 @@ pub fn command(_options: Options) -> Result<()> {
.unwrap_or_default();
panic::set_hook(hook);

let yarn_version = get_version("yarn", &[])
.unwrap_or_default()
.unwrap_or_default();

let metadata = version_metadata()?;
VersionBlock::new(
"Node.js",
Expand Down Expand Up @@ -640,13 +680,7 @@ pub fn command(_options: Options) -> Result<()> {
.unwrap_or_default(),
)
.display();
VersionBlock::new(
"yarn",
get_version("yarn", &[])
.unwrap_or_default()
.unwrap_or_default(),
)
.display();
VersionBlock::new("yarn", &yarn_version).display();
VersionBlock::new(
"rustup",
get_version("rustup", &[])
Expand Down Expand Up @@ -695,20 +729,23 @@ pub fn command(_options: Options) -> Result<()> {

let mut package_manager = PackageManager::Npm;
if let Some(app_dir) = &app_dir {
let file_names = read_dir(app_dir)
let app_dir_entries = read_dir(app_dir)
.unwrap()
.filter(|e| {
e.as_ref()
.unwrap()
.metadata()
.unwrap()
.file_type()
.is_file()
})
.map(|e| e.unwrap().file_name().to_string_lossy().into_owned())
.collect::<Vec<String>>();
package_manager = get_package_manager(&file_names)?;
package_manager = get_package_manager(&app_dir_entries)?;
}

if package_manager == PackageManager::Yarn
&& yarn_version
.chars()
.next()
.map(|c| c > '1')
.unwrap_or_default()
{
package_manager = PackageManager::Berry;
}

VersionBlock::new(
format!("{} {}", "@tauri-apps/cli", "[NPM]".dimmed()),
metadata.js_cli.version,
Expand Down Expand Up @@ -852,12 +889,12 @@ pub fn command(_options: Options) -> Result<()> {
Ok(())
}

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

for name in file_names {
for name in app_dir_entries {
if name.as_ref() == "package-lock.json" {
use_npm = true;
} else if name.as_ref() == "pnpm-lock.yaml" {
Expand Down
9 changes: 1 addition & 8 deletions tooling/cli/src/init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ use dialoguer::Input;
use handlebars::{to_json, Handlebars};
use include_dir::{include_dir, Dir};
use log::warn;
use serde::Deserialize;

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

#[derive(Deserialize)]
struct PackageJson {
name: Option<String>,
product_name: Option<String>,
}

#[derive(Default)]
struct InitDefaults {
app_name: Option<String>,
Expand All @@ -82,7 +75,7 @@ impl Options {

let init_defaults = if package_json_path.exists() {
let package_json_text = read_to_string(package_json_path)?;
let package_json: PackageJson = serde_json::from_str(&package_json_text)?;
let package_json: crate::PackageJson = serde_json::from_str(&package_json_text)?;
let (framework, _) = infer_framework(&package_json_text);
InitDefaults {
app_name: package_json.product_name.or(package_json.name),
Expand Down
10 changes: 9 additions & 1 deletion tooling/cli/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,25 @@ use clap::{FromArgMatches, IntoApp, Parser, Subcommand};
use env_logger::fmt::Color;
use env_logger::Builder;
use log::{debug, log_enabled, Level};
use serde::Deserialize;
use std::ffi::OsString;
use std::io::Write;
use std::process::{Command, Output};

#[derive(serde::Deserialize)]
#[derive(Deserialize)]
pub struct VersionMetadata {
tauri: String,
#[serde(rename = "tauri-build")]
tauri_build: String,
}

#[derive(Deserialize)]
pub struct PackageJson {
name: Option<String>,
version: Option<String>,
product_name: Option<String>,
}

#[derive(Parser)]
#[clap(
author,
Expand Down

0 comments on commit cdfa625

Please sign in to comment.