Skip to content

Commit c5db902

Browse files
committed
Rollback env vars changed by a proc macro
1 parent b55a1c5 commit c5db902

File tree

1 file changed

+32
-9
lines changed
  • crates/proc_macro_srv/src

1 file changed

+32
-9
lines changed

crates/proc_macro_srv/src/lib.rs

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@ mod abis;
1616

1717
use std::{
1818
collections::{hash_map::Entry, HashMap},
19-
env, fs,
19+
env,
20+
ffi::OsString,
21+
fs,
2022
path::{Path, PathBuf},
2123
time::SystemTime,
2224
};
@@ -38,9 +40,8 @@ impl ProcMacroSrv {
3840
PanicMessage(format!("failed to load macro: {}", err))
3941
})?;
4042

41-
let mut prev_env = HashMap::new();
43+
let prev_env = EnvSnapshot::new();
4244
for (k, v) in &task.env {
43-
prev_env.insert(k.as_str(), env::var_os(k));
4445
env::set_var(k, v);
4546
}
4647
let prev_working_dir = match task.current_dir {
@@ -60,12 +61,8 @@ impl ProcMacroSrv {
6061
.expand(&task.macro_name, &macro_body, attributes.as_ref())
6162
.map(|it| FlatTree::new(&it));
6263

63-
for (k, _) in &task.env {
64-
match &prev_env[k.as_str()] {
65-
Some(v) => env::set_var(k, v),
66-
None => env::remove_var(k),
67-
}
68-
}
64+
prev_env.rollback();
65+
6966
if let Some(dir) = prev_working_dir {
7067
if let Err(err) = std::env::set_current_dir(&dir) {
7168
eprintln!(
@@ -101,6 +98,32 @@ impl ProcMacroSrv {
10198
}
10299
}
103100

101+
struct EnvSnapshot {
102+
vars: Vec<(OsString, OsString)>,
103+
}
104+
105+
impl EnvSnapshot {
106+
fn new() -> EnvSnapshot {
107+
EnvSnapshot { vars: env::vars_os().collect() }
108+
}
109+
110+
fn rollback(self) {
111+
let mut old_vars = self.vars.into_iter().collect::<HashMap<OsString, OsString>>();
112+
for (name, value) in env::vars_os() {
113+
let old_value = old_vars.remove(&name);
114+
if old_value != Some(value) {
115+
match old_value {
116+
None => env::remove_var(name),
117+
Some(old_value) => env::set_var(name, old_value),
118+
}
119+
}
120+
}
121+
for (name, old_value) in old_vars {
122+
env::set_var(name, old_value)
123+
}
124+
}
125+
}
126+
104127
pub mod cli;
105128

106129
#[cfg(test)]

0 commit comments

Comments
 (0)