Ver Fonte

fix(cli.rs): fix workspace detection, fixes #2614, closes #2515 (#2644)

Lucas Fernandes Nogueira há 3 anos atrás
pai
commit
8d630bc8c4

+ 5 - 0
.changes/fix-out-dir-detection.md

@@ -0,0 +1,5 @@
+---
+"cli.rs": patch
+---
+
+Fixes output directory detection when using Cargo workspaces.

+ 1 - 0
tooling/cli.rs/Cargo.lock

@@ -1922,6 +1922,7 @@ dependencies = [
  "clap",
  "colored",
  "encode_unicode",
+ "glob",
  "handlebars",
  "heck",
  "include_dir",

+ 1 - 0
tooling/cli.rs/Cargo.toml

@@ -46,6 +46,7 @@ terminal_size = "0.1"
 unicode-width = "0.1"
 tempfile = "3"
 zeroize = "1.4"
+glob = "0.3"
 
 [target."cfg(windows)".dependencies]
 winapi = { version = "0.3", features = [ "winbase", "winuser", "consoleapi", "processenv", "wincon" ] }

+ 5 - 1
tooling/cli.rs/src/build.rs

@@ -133,7 +133,11 @@ impl Build {
       .get_out_dir(self.target.clone(), self.debug)
       .with_context(|| "failed to get project out directory")?;
     if let Some(product_name) = config_.package.product_name.clone() {
-      let bin_name = app_settings.cargo_package_settings().name.clone();
+      let bin_name = app_settings
+        .cargo_package_settings()
+        .name
+        .clone()
+        .expect("Cargo manifest must have the `package.name` field");
       #[cfg(windows)]
       let (bin_path, product_path) = {
         (

+ 43 - 23
tooling/cli.rs/src/interface/rust.rs

@@ -15,7 +15,7 @@ use anyhow::Context;
 use heck::KebabCase;
 use serde::Deserialize;
 
-use crate::helpers::{app_paths::tauri_dir, config::Config, manifest::Manifest};
+use crate::helpers::{app_paths::tauri_dir, config::Config, manifest::Manifest, Logger};
 use tauri_bundler::{
   AppCategory, BundleBinary, BundleSettings, DebianSettings, MacOsSettings, PackageSettings,
   UpdaterSettings, WindowsSettings, WixSettings,
@@ -38,11 +38,11 @@ struct BinarySettings {
 #[derive(Debug, Clone, Deserialize)]
 pub struct CargoPackageSettings {
   /// the package's name.
-  pub name: String,
+  pub name: Option<String>,
   /// the package's version.
-  pub version: String,
+  pub version: Option<String>,
   /// the package's description.
-  pub description: String,
+  pub description: Option<String>,
   /// the package's homepage.
   pub homepage: Option<String>,
   /// the package's authors.
@@ -148,17 +148,22 @@ impl AppSettings {
     };
 
     let package_settings = PackageSettings {
-      product_name: config
-        .package
-        .product_name
-        .clone()
-        .unwrap_or_else(|| cargo_package_settings.name.clone()),
-      version: config
-        .package
-        .version
+      product_name: config.package.product_name.clone().unwrap_or_else(|| {
+        cargo_package_settings
+          .name
+          .clone()
+          .expect("Cargo manifest must have the `package.name` field")
+      }),
+      version: config.package.version.clone().unwrap_or_else(|| {
+        cargo_package_settings
+          .version
+          .clone()
+          .expect("Cargo manifest must have the `package.version` field")
+      }),
+      description: cargo_package_settings
+        .description
         .clone()
-        .unwrap_or_else(|| cargo_package_settings.version.clone()),
-      description: cargo_package_settings.description.clone(),
+        .unwrap_or_default(),
       homepage: cargo_package_settings.homepage.clone(),
       authors: cargo_package_settings.authors.clone(),
       default_run: cargo_package_settings.default_run.clone(),
@@ -208,7 +213,7 @@ impl AppSettings {
         .unwrap_or_else(|| "".to_string());
       for binary in bin {
         binaries.push(
-          if binary.name.as_str() == self.cargo_package_settings.name
+          if Some(&binary.name) == self.cargo_package_settings.name.as_ref()
             || binary.name.as_str() == default_run
           {
             BundleBinary::new(
@@ -333,18 +338,33 @@ fn get_target_dir(
 pub fn get_workspace_dir(current_dir: &Path) -> PathBuf {
   let mut dir = current_dir.to_path_buf();
   let project_path = dir.clone();
+  let logger = Logger::new("tauri:rust");
 
   while dir.pop() {
-    if let Ok(cargo_settings) = CargoSettings::load(&dir) {
-      if let Some(workspace_settings) = cargo_settings.workspace {
-        if let Some(members) = workspace_settings.members {
-          if members
-            .iter()
-            .any(|member| dir.join(member) == project_path)
-          {
-            return dir;
+    if dir.join("Cargo.toml").exists() {
+      match CargoSettings::load(&dir) {
+        Ok(cargo_settings) => {
+          if let Some(workspace_settings) = cargo_settings.workspace {
+            if let Some(members) = workspace_settings.members {
+              if members.iter().any(|member| {
+                glob::glob(&dir.join(member).to_string_lossy().into_owned())
+                  .unwrap()
+                  .any(|p| p.unwrap() == project_path)
+              }) {
+                return dir;
+              }
+            }
           }
         }
+        Err(e) => {
+          logger.warn(format!(
+            "Found `{}`, which may define a parent workspace, but \
+          failed to parse it. If this is indeed a parent workspace, undefined behavior may occur: \
+          \n    {:#}",
+            dir.display(),
+            e
+          ));
+        }
       }
     }
   }