diff --git a/.changes/fix-out-dir-detection.md b/.changes/fix-out-dir-detection.md new file mode 100644 index 000000000..4d58c009a --- /dev/null +++ b/.changes/fix-out-dir-detection.md @@ -0,0 +1,5 @@ +--- +"cli.rs": patch +--- + +Fixes output directory detection when using Cargo workspaces. diff --git a/tooling/cli.rs/Cargo.lock b/tooling/cli.rs/Cargo.lock index 5df89d299..6052550d3 100755 --- a/tooling/cli.rs/Cargo.lock +++ b/tooling/cli.rs/Cargo.lock @@ -1922,6 +1922,7 @@ dependencies = [ "clap", "colored", "encode_unicode", + "glob", "handlebars", "heck", "include_dir", diff --git a/tooling/cli.rs/Cargo.toml b/tooling/cli.rs/Cargo.toml index 2392827ac..190512e94 100644 --- a/tooling/cli.rs/Cargo.toml +++ b/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" ] } diff --git a/tooling/cli.rs/src/build.rs b/tooling/cli.rs/src/build.rs index 0abc6a825..5c6ad58f4 100644 --- a/tooling/cli.rs/src/build.rs +++ b/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) = { ( diff --git a/tooling/cli.rs/src/interface/rust.rs b/tooling/cli.rs/src/interface/rust.rs index 85b9903d4..0d1edebe8 100644 --- a/tooling/cli.rs/src/interface/rust.rs +++ b/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, /// the package's version. - pub version: String, + pub version: Option, /// the package's description. - pub description: String, + pub description: Option, /// the package's homepage. pub homepage: Option, /// the package's authors. @@ -148,17 +148,22 @@ impl AppSettings { }; let package_settings = PackageSettings { - product_name: config - .package - .product_name + 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.name.clone()), - version: config - .package - .version - .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 + )); + } } } }