mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-26 03:45:04 +00:00
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
1 changed files with 32 additions and 9 deletions
|
@ -16,7 +16,9 @@ mod abis;
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
collections::{hash_map::Entry, HashMap},
|
collections::{hash_map::Entry, HashMap},
|
||||||
env, fs,
|
env,
|
||||||
|
ffi::OsString,
|
||||||
|
fs,
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
time::SystemTime,
|
time::SystemTime,
|
||||||
};
|
};
|
||||||
|
@ -38,9 +40,8 @@ impl ProcMacroSrv {
|
||||||
PanicMessage(format!("failed to load macro: {}", err))
|
PanicMessage(format!("failed to load macro: {}", err))
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let mut prev_env = HashMap::new();
|
let prev_env = EnvSnapshot::new();
|
||||||
for (k, v) in &task.env {
|
for (k, v) in &task.env {
|
||||||
prev_env.insert(k.as_str(), env::var_os(k));
|
|
||||||
env::set_var(k, v);
|
env::set_var(k, v);
|
||||||
}
|
}
|
||||||
let prev_working_dir = match task.current_dir {
|
let prev_working_dir = match task.current_dir {
|
||||||
|
@ -60,12 +61,8 @@ impl ProcMacroSrv {
|
||||||
.expand(&task.macro_name, ¯o_body, attributes.as_ref())
|
.expand(&task.macro_name, ¯o_body, attributes.as_ref())
|
||||||
.map(|it| FlatTree::new(&it));
|
.map(|it| FlatTree::new(&it));
|
||||||
|
|
||||||
for (k, _) in &task.env {
|
prev_env.rollback();
|
||||||
match &prev_env[k.as_str()] {
|
|
||||||
Some(v) => env::set_var(k, v),
|
|
||||||
None => env::remove_var(k),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if let Some(dir) = prev_working_dir {
|
if let Some(dir) = prev_working_dir {
|
||||||
if let Err(err) = std::env::set_current_dir(&dir) {
|
if let Err(err) = std::env::set_current_dir(&dir) {
|
||||||
eprintln!(
|
eprintln!(
|
||||||
|
@ -101,6 +98,32 @@ impl ProcMacroSrv {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
pub mod cli;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
Loading…
Reference in a new issue