From 55787c2e7d9a3ebe393ee4ca22e14e6561311abd Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Sun, 26 Feb 2023 18:42:14 -0600 Subject: [PATCH] fix hot reloading in a workspace --- packages/rsx/Cargo.toml | 1 + .../src/hot_reload/hot_reloading_file_map.rs | 36 ++++++++++++++++++- 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/packages/rsx/Cargo.toml b/packages/rsx/Cargo.toml index 5aea4d03e..055a97132 100644 --- a/packages/rsx/Cargo.toml +++ b/packages/rsx/Cargo.toml @@ -18,3 +18,4 @@ syn = { version = "1.0", features = ["full", "extra-traits"] } quote = { version = "1.0" } serde = { version = "1.0", features = ["derive"] } internment = "0.7.0" +krates = "0.12.6" \ No newline at end of file diff --git a/packages/rsx/src/hot_reload/hot_reloading_file_map.rs b/packages/rsx/src/hot_reload/hot_reloading_file_map.rs index 38c1d9105..2f0cc5246 100644 --- a/packages/rsx/src/hot_reload/hot_reloading_file_map.rs +++ b/packages/rsx/src/hot_reload/hot_reloading_file_map.rs @@ -1,5 +1,7 @@ use crate::{CallBody, HotReloadingContext}; use dioxus_core::Template; +use krates::cm::MetadataCommand; +use krates::Cmd; pub use proc_macro2::TokenStream; pub use std::collections::HashMap; use std::path::PathBuf; @@ -27,6 +29,7 @@ pub struct FileMapBuildResult { pub struct FileMap { pub map: HashMap>)>, + in_workspace: HashMap, phantom: std::marker::PhantomData, } @@ -76,6 +79,7 @@ impl FileMap { let FileMapSearchResult { map, errors } = find_rs_files(path, &mut filter)?; let result = Self { map, + in_workspace: HashMap::new(), phantom: std::marker::PhantomData, }; Ok(FileMapBuildResult { @@ -90,6 +94,7 @@ impl FileMap { let mut src = String::new(); file.read_to_string(&mut src)?; if let Ok(syntax) = syn::parse_file(&src) { + let in_workspace = self.child_in_workspace(crate_dir)?; if let Some((old_src, template_slot)) = self.map.get_mut(file_path) { if let Ok(old) = syn::parse_file(old_src) { match find_rsx(&syntax, &old) { @@ -105,7 +110,17 @@ impl FileMap { syn::parse2::(old.tokens), syn::parse2::(new), ) { - if let Ok(file) = file_path.strip_prefix(crate_dir) { + // if the file!() macro is invoked in a workspace, the path is relative to the workspace root, otherwise it's relative to the crate root + // we need to check if the file is in a workspace or not and strip the prefix accordingly + let prefix = if in_workspace { + crate_dir.parent().ok_or(io::Error::new( + io::ErrorKind::Other, + "Could not load workspace", + ))? + } else { + crate_dir + }; + if let Ok(file) = file_path.strip_prefix(prefix) { let line = old_start.line; let column = old_start.column + 1; let location = file.display().to_string() @@ -157,4 +172,23 @@ impl FileMap { } Ok(UpdateResult::NeedsRebuild) } + + fn child_in_workspace(&mut self, crate_dir: &Path) -> io::Result { + if let Some(in_workspace) = self.in_workspace.get(crate_dir) { + Ok(*in_workspace) + } else { + let mut cmd = Cmd::new(); + let manafest_path = crate_dir.join("Cargo.toml"); + cmd.manifest_path(&manafest_path); + let cmd: MetadataCommand = cmd.into(); + let metadata = cmd + .exec() + .map_err(|err| io::Error::new(io::ErrorKind::Other, err))?; + + let in_workspace = metadata.workspace_root != crate_dir; + self.in_workspace + .insert(crate_dir.to_path_buf(), in_workspace); + Ok(in_workspace) + } + } }