Unnamed repository; edit this file 'description' to name the repository.
Set current working directory for procedural macros
| -rw-r--r-- | crates/proc_macro_api/src/lib.rs | 6 | ||||
| -rw-r--r-- | crates/proc_macro_api/src/msg.rs | 3 | ||||
| -rw-r--r-- | crates/proc_macro_srv/src/lib.rs | 19 |
3 files changed, 28 insertions, 0 deletions
diff --git a/crates/proc_macro_api/src/lib.rs b/crates/proc_macro_api/src/lib.rs index 9e50c1f83f..0b8a2b6f85 100644 --- a/crates/proc_macro_api/src/lib.rs +++ b/crates/proc_macro_api/src/lib.rs @@ -156,12 +156,18 @@ impl ProcMacro { attr: Option<&Subtree>, env: Vec<(String, String)>, ) -> Result<Result<Subtree, PanicMessage>, ServerError> { + let current_dir = env + .iter() + .find(|(name, _)| name == "CARGO_MANIFEST_DIR") + .map(|(_, value)| value.clone()); + let task = ExpandMacro { macro_body: FlatTree::new(subtree), macro_name: self.name.to_string(), attributes: attr.map(FlatTree::new), lib: self.dylib_path.to_path_buf().into(), env, + current_dir, }; let request = msg::Request::ExpandMacro(task); diff --git a/crates/proc_macro_api/src/msg.rs b/crates/proc_macro_api/src/msg.rs index e9764a7dc6..da96c81d49 100644 --- a/crates/proc_macro_api/src/msg.rs +++ b/crates/proc_macro_api/src/msg.rs @@ -48,6 +48,8 @@ pub struct ExpandMacro { /// Environment variables to set during macro expansion. pub env: Vec<(String, String)>, + + pub current_dir: Option<String>, } pub trait Message: Serialize + DeserializeOwned { @@ -143,6 +145,7 @@ mod tests { attributes: None, lib: std::env::current_dir().unwrap(), env: Default::default(), + current_dir: Default::default(), }; let json = serde_json::to_string(&task).unwrap(); diff --git a/crates/proc_macro_srv/src/lib.rs b/crates/proc_macro_srv/src/lib.rs index 6f3943870e..1698bc967d 100644 --- a/crates/proc_macro_srv/src/lib.rs +++ b/crates/proc_macro_srv/src/lib.rs @@ -43,6 +43,16 @@ impl ProcMacroSrv { prev_env.insert(k.as_str(), env::var_os(k)); env::set_var(k, v); } + let prev_working_dir = match task.current_dir { + Some(dir) => { + let prev_working_dir = std::env::current_dir().ok(); + if let Err(err) = std::env::set_current_dir(&dir) { + eprintln!("Failed to set the current working dir to {}. Error: {:?}", dir, err) + } + prev_working_dir + } + None => None, + }; let macro_body = task.macro_body.to_subtree(); let attributes = task.attributes.map(|it| it.to_subtree()); @@ -56,6 +66,15 @@ impl ProcMacroSrv { None => env::remove_var(k), } } + if let Some(dir) = prev_working_dir { + if let Err(err) = std::env::set_current_dir(&dir) { + eprintln!( + "Failed to set the current working dir to {}. Error: {:?}", + dir.display(), + err + ) + } + } result.map_err(PanicMessage) } |