Skip to content

Commit 5011728

Browse files
committed
Add var_guard and modify anchor_cli_lib to use it
1 parent 5f0cf0c commit 5011728

File tree

3 files changed

+48
-11
lines changed

3 files changed

+48
-11
lines changed

src/anchor_cli_lib/mod.rs

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -343,11 +343,9 @@ fn generate_idl(
343343
// smoelius: If `RUSTUP_TOOLCHAIN` is not cleared, `Span::unwrap` might not be found in
344344
// `proc-macro2`. The affected code is in `anchor-syn`:
345345
// https://github.com/solana-foundation/anchor/blob/38f2b554b2dc6632376241f94048639eaf33d7bd/lang/syn/src/idl/defined.rs#L498-L502
346-
let rustup_toolchain = std::env::var_os("RUSTUP_TOOLCHAIN");
347-
if rustup_toolchain.is_some() {
348-
unsafe {
349-
std::env::remove_var("RUSTUP_TOOLCHAIN");
350-
}
346+
let _guard: crate::util::var_guard::VarGuard;
347+
if std::env::var_os("RUSTUP_TOOLCHAIN").is_some() {
348+
_guard = crate::util::var_guard::VarGuard::set("RUSTUP_TOOLCHAIN", None);
351349
}
352350

353351
let result = anchor_lang_idl::build::IdlBuilder::new()
@@ -357,12 +355,6 @@ fn generate_idl(
357355
.cargo_args(cargo_args.into())
358356
.build();
359357

360-
if let Some(rustup_toolchain) = rustup_toolchain {
361-
unsafe {
362-
std::env::set_var("RUSTUP_TOOLCHAIN", rustup_toolchain);
363-
}
364-
}
365-
366358
result
367359
}
368360

src/util/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ use std::{
66
path::{Path, PathBuf},
77
};
88

9+
pub mod var_guard;
10+
911
pub fn files_with_extension(dir: impl AsRef<Path>, extension: &str) -> Result<Vec<PathBuf>> {
1012
let mut pcs_paths = Vec::new();
1113
for result in read_dir(dir)? {

src/util/var_guard.rs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// smoelius: `VarGuard` is based on a struct of the same name from Clippy's source code. The `set`
2+
// method was modified to accept an `Option` so that variables could be cleared. Also, `unsafe`
3+
// annotations were added to make the struct compile with Rust Edition 2024. See:
4+
// https://github.com/rust-lang/rust-clippy/blob/c51472b4b09d22bdbb46027f08be54c4b285a725/tests/compile-test.rs#L267-L289
5+
6+
use std::{
7+
env::{remove_var, set_var, var_os},
8+
ffi::{OsStr, OsString},
9+
marker::PhantomData,
10+
};
11+
12+
/// Restores an env var on drop
13+
#[must_use]
14+
pub struct VarGuard<T = OsString> {
15+
key: &'static str,
16+
value: Option<OsString>,
17+
_phantom: PhantomData<T>,
18+
}
19+
20+
impl<T: AsRef<OsStr>> VarGuard<T> {
21+
pub fn set(key: &'static str, val: Option<T>) -> Self {
22+
let value = var_os(key);
23+
if let Some(val) = val {
24+
unsafe { set_var(key, val) };
25+
} else {
26+
unsafe { remove_var(key) };
27+
}
28+
Self {
29+
key,
30+
value,
31+
_phantom: PhantomData,
32+
}
33+
}
34+
}
35+
36+
impl<T> Drop for VarGuard<T> {
37+
fn drop(&mut self) {
38+
match self.value.as_deref() {
39+
None => unsafe { remove_var(self.key) },
40+
Some(value) => unsafe { set_var(self.key, value) },
41+
}
42+
}
43+
}

0 commit comments

Comments
 (0)