From 3052e0ef116df6e7ac91bb943306c3453134344c Mon Sep 17 00:00:00 2001 From: imbolc Date: Mon, 21 Mar 2022 10:56:19 +0300 Subject: [PATCH] Fix buliding with redefined cargo target dir --- src/cargo.rs | 80 +++++++++++++++++++++++++++++++-------------------- src/config.rs | 5 ++-- 2 files changed, 52 insertions(+), 33 deletions(-) diff --git a/src/cargo.rs b/src/cargo.rs index 67a3e48f1..251e9d848 100644 --- a/src/cargo.rs +++ b/src/cargo.rs @@ -10,6 +10,12 @@ use std::{ /// How many parent folders are searched for a `Cargo.toml` const MAX_ANCESTORS: u32 = 10; +/// Some fields parsed from `cargo metadata` command +pub struct Metadata { + pub workspace_root: PathBuf, + pub target_directory: PathBuf, +} + /// Returns the root of the crate that the command is run from /// /// If the command is run from the workspace root, this will return the top-level Cargo.toml @@ -31,37 +37,6 @@ pub fn crate_root() -> Result { .ok_or_else(|| Error::CargoError("Failed to find the cargo directory".to_string())) } -/// Returns the root of a workspace -/// TODO @Jon, find a different way that doesn't rely on the cargo metadata command (it's slow) -pub fn workspace_root() -> Result { - let output = Command::new("cargo") - .args(&["metadata"]) - .output() - .map_err(|_| Error::CargoError("Manifset".to_string()))?; - - if !output.status.success() { - let mut msg = str::from_utf8(&output.stderr).unwrap().trim(); - if msg.starts_with("error: ") { - msg = &msg[7..]; - } - - return Err(Error::CargoError(msg.to_string())); - } - - let stdout = str::from_utf8(&output.stdout).unwrap(); - if let Some(line) = stdout.lines().next() { - let meta: serde_json::Value = serde_json::from_str(line) - .map_err(|_| Error::CargoError("InvalidOutput".to_string()))?; - - let root = meta["workspace_root"] - .as_str() - .ok_or_else(|| Error::CargoError("InvalidOutput".to_string()))?; - return Ok(root.into()); - } - - Err(Error::CargoError("InvalidOutput".to_string())) -} - /// Checks if the directory contains `Cargo.toml` fn contains_manifest(path: &Path) -> bool { fs::read_dir(path) @@ -72,3 +47,46 @@ fn contains_manifest(path: &Path) -> bool { }) .unwrap_or(false) } + +impl Metadata { + /// Returns the struct filled from `cargo metadata` output + /// TODO @Jon, find a different way that doesn't rely on the cargo metadata command (it's slow) + pub fn get() -> Result { + let output = Command::new("cargo") + .args(&["metadata"]) + .output() + .map_err(|_| Error::CargoError("Manifset".to_string()))?; + + if !output.status.success() { + let mut msg = str::from_utf8(&output.stderr).unwrap().trim(); + if msg.starts_with("error: ") { + msg = &msg[7..]; + } + + return Err(Error::CargoError(msg.to_string())); + } + + let stdout = str::from_utf8(&output.stdout).unwrap(); + if let Some(line) = stdout.lines().next() { + let meta: serde_json::Value = serde_json::from_str(line) + .map_err(|_| Error::CargoError("InvalidOutput".to_string()))?; + + let workspace_root = meta["workspace_root"] + .as_str() + .ok_or_else(|| Error::CargoError("InvalidOutput".to_string()))? + .into(); + + let target_directory = meta["target_directory"] + .as_str() + .ok_or_else(|| Error::CargoError("InvalidOutput".to_string()))? + .into(); + + return Ok(Self { + workspace_root, + target_directory, + }); + } + + Err(Error::CargoError("InvalidOutput".to_string())) + } +} diff --git a/src/config.rs b/src/config.rs index ba0427191..9d2bfb870 100644 --- a/src/config.rs +++ b/src/config.rs @@ -120,8 +120,9 @@ impl CrateConfig { let dioxus_config = DioxusConfig::load()?; let crate_dir = crate::cargo::crate_root()?; - let workspace_dir = crate::cargo::workspace_root()?; - let target_dir = workspace_dir.join("target"); + let meta = crate::cargo::Metadata::get()?; + let workspace_dir = meta.workspace_root; + let target_dir = meta.target_directory; let out_dir = match dioxus_config.application.out_dir { Some(ref v) => crate_dir.join(v),