Merge #11356
11356: Rollback env vars changed by a proc macro r=vlad20012 a=vlad20012 Fixes #11355 Co-authored-by: vlad20012 <beskvlad@gmail.com>
This commit is contained in:
commit
6010431a0b
@ -16,7 +16,9 @@
|
||||
|
||||
use std::{
|
||||
collections::{hash_map::Entry, HashMap},
|
||||
env, fs,
|
||||
env,
|
||||
ffi::OsString,
|
||||
fs,
|
||||
path::{Path, PathBuf},
|
||||
time::SystemTime,
|
||||
};
|
||||
@ -38,9 +40,8 @@ pub fn expand(&mut self, task: ExpandMacro) -> Result<FlatTree, PanicMessage> {
|
||||
PanicMessage(format!("failed to load macro: {}", err))
|
||||
})?;
|
||||
|
||||
let mut prev_env = HashMap::new();
|
||||
let prev_env = EnvSnapshot::new();
|
||||
for (k, v) in &task.env {
|
||||
prev_env.insert(k.as_str(), env::var_os(k));
|
||||
env::set_var(k, v);
|
||||
}
|
||||
let prev_working_dir = match task.current_dir {
|
||||
@ -60,12 +61,8 @@ pub fn expand(&mut self, task: ExpandMacro) -> Result<FlatTree, PanicMessage> {
|
||||
.expand(&task.macro_name, ¯o_body, attributes.as_ref())
|
||||
.map(|it| FlatTree::new(&it));
|
||||
|
||||
for (k, _) in &task.env {
|
||||
match &prev_env[k.as_str()] {
|
||||
Some(v) => env::set_var(k, v),
|
||||
None => env::remove_var(k),
|
||||
}
|
||||
}
|
||||
prev_env.rollback();
|
||||
|
||||
if let Some(dir) = prev_working_dir {
|
||||
if let Err(err) = std::env::set_current_dir(&dir) {
|
||||
eprintln!(
|
||||
@ -101,6 +98,32 @@ fn expander(&mut self, path: &Path) -> Result<&dylib::Expander, String> {
|
||||
}
|
||||
}
|
||||
|
||||
struct EnvSnapshot {
|
||||
vars: HashMap<OsString, OsString>,
|
||||
}
|
||||
|
||||
impl EnvSnapshot {
|
||||
fn new() -> EnvSnapshot {
|
||||
EnvSnapshot { vars: env::vars_os().collect() }
|
||||
}
|
||||
|
||||
fn rollback(self) {
|
||||
let mut old_vars = self.vars;
|
||||
for (name, value) in env::vars_os() {
|
||||
let old_value = old_vars.remove(&name);
|
||||
if old_value != Some(value) {
|
||||
match old_value {
|
||||
None => env::remove_var(name),
|
||||
Some(old_value) => env::set_var(name, old_value),
|
||||
}
|
||||
}
|
||||
}
|
||||
for (name, old_value) in old_vars {
|
||||
env::set_var(name, old_value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub mod cli;
|
||||
|
||||
#[cfg(test)]
|
||||
|
Loading…
Reference in New Issue
Block a user