Skip to content

Commit a8a58ed

Browse files
committed
Move Windows-only test code into windows module
1 parent c273144 commit a8a58ed

File tree

5 files changed

+83
-102
lines changed

5 files changed

+83
-102
lines changed

src/cli/self_update.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,6 @@ use crate::{
6969

7070
#[cfg(unix)]
7171
mod shell;
72-
#[cfg(feature = "test")]
73-
pub(crate) mod test;
7472

7573
#[cfg(unix)]
7674
mod unix;
@@ -85,6 +83,8 @@ mod windows;
8583
pub use windows::complete_windows_uninstall;
8684
#[cfg(windows)]
8785
use windows::{delete_rustup_and_cargo_home, do_add_to_path, do_remove_from_path};
86+
#[cfg(all(windows, feature = "test"))]
87+
pub use windows::{get_path, RegistryGuard, RegistryValueId, USER_PATH};
8888
#[cfg(windows)]
8989
pub(crate) use windows::{run_update, self_replace};
9090

src/cli/self_update/test.rs

-89
This file was deleted.

src/cli/self_update/windows.rs

+79-9
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
use std::env::{consts::EXE_SUFFIX, split_paths};
22
use std::ffi::{OsStr, OsString};
33
use std::fmt;
4-
use std::io::Write;
4+
use std::io::{self, Write};
55
use std::os::windows::ffi::{OsStrExt, OsStringExt};
66
use std::path::Path;
77
use std::process::Command;
8-
use std::sync::{Arc, Mutex};
8+
use std::sync::{Arc, LockResult, Mutex, MutexGuard};
99

1010
use anyhow::{anyhow, Context, Result};
1111
use tracing::{info, warn};
@@ -20,6 +20,7 @@ use crate::utils::utils;
2020
use crate::utils::Notification;
2121

2222
use winreg::enums::{RegType, HKEY_CURRENT_USER, KEY_READ, KEY_WRITE};
23+
use winreg::types::{FromRegValue, ToRegValue};
2324
use winreg::{RegKey, RegValue};
2425

2526
pub(crate) fn ensure_prompt(process: &Process) -> Result<()> {
@@ -807,16 +808,85 @@ pub(crate) fn delete_rustup_and_cargo_home(process: &Process) -> Result<()> {
807808
Ok(())
808809
}
809810

810-
#[cfg(test)]
811-
mod tests {
812-
use std::ffi::OsString;
813-
use std::os::windows::ffi::OsStrExt;
811+
#[cfg(any(test, feature = "test"))]
812+
pub fn get_path() -> io::Result<Option<RegValue>> {
813+
USER_PATH.get()
814+
}
815+
816+
#[cfg(any(test, feature = "test"))]
817+
pub struct RegistryGuard<'a> {
818+
_locked: LockResult<MutexGuard<'a, ()>>,
819+
id: &'static RegistryValueId,
820+
prev: Option<RegValue>,
821+
}
822+
823+
#[cfg(any(test, feature = "test"))]
824+
impl<'a> RegistryGuard<'a> {
825+
pub fn new(id: &'static RegistryValueId) -> io::Result<Self> {
826+
Ok(Self {
827+
_locked: REGISTRY_LOCK.lock(),
828+
id,
829+
prev: id.get()?,
830+
})
831+
}
832+
}
833+
834+
#[cfg(any(test, feature = "test"))]
835+
impl<'a> Drop for RegistryGuard<'a> {
836+
fn drop(&mut self) {
837+
self.id.set(self.prev.as_ref()).unwrap();
838+
}
839+
}
840+
841+
#[cfg(any(test, feature = "test"))]
842+
static REGISTRY_LOCK: Mutex<()> = Mutex::new(());
843+
844+
#[cfg(any(test, feature = "test"))]
845+
pub const USER_PATH: RegistryValueId = RegistryValueId {
846+
sub_key: "Environment",
847+
value_name: "PATH",
848+
};
814849

815-
use winreg::enums::{RegType, HKEY_CURRENT_USER, KEY_READ, KEY_WRITE};
816-
use winreg::{RegKey, RegValue};
850+
#[cfg(any(test, feature = "test"))]
851+
pub struct RegistryValueId {
852+
pub sub_key: &'static str,
853+
pub value_name: &'static str,
854+
}
855+
856+
#[cfg(any(test, feature = "test"))]
857+
impl RegistryValueId {
858+
pub fn get_value<T: FromRegValue>(&self) -> io::Result<Option<T>> {
859+
self.get()?.map(|v| T::from_reg_value(&v)).transpose()
860+
}
861+
862+
pub fn get(&self) -> io::Result<Option<RegValue>> {
863+
let sub_key = RegKey::predef(HKEY_CURRENT_USER)
864+
.open_subkey_with_flags(self.sub_key, KEY_READ | KEY_WRITE)?;
865+
match sub_key.get_raw_value(self.value_name) {
866+
Ok(val) => Ok(Some(val)),
867+
Err(ref e) if e.kind() == io::ErrorKind::NotFound => Ok(None),
868+
Err(e) => Err(e),
869+
}
870+
}
871+
872+
pub fn set_value(&self, new: Option<impl ToRegValue>) -> io::Result<()> {
873+
self.set(new.map(|s| s.to_reg_value()).as_ref())
874+
}
817875

876+
pub fn set(&self, new: Option<&RegValue>) -> io::Result<()> {
877+
let sub_key = RegKey::predef(HKEY_CURRENT_USER)
878+
.open_subkey_with_flags(self.sub_key, KEY_READ | KEY_WRITE)?;
879+
match new {
880+
Some(new) => sub_key.set_raw_value(self.value_name, new),
881+
None => sub_key.delete_value(self.value_name),
882+
}
883+
}
884+
}
885+
886+
#[cfg(test)]
887+
mod tests {
888+
use super::*;
818889
use crate::currentprocess::TestProcess;
819-
use crate::test::{RegistryGuard, USER_PATH};
820890

821891
fn wide(str: &str) -> Vec<u16> {
822892
OsString::from(str).encode_wide().collect()

src/env_var.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ mod tests {
4848

4949
use super::*;
5050
#[cfg(windows)]
51-
use crate::cli::self_update::test::{RegistryGuard, USER_PATH};
51+
use crate::cli::self_update::{RegistryGuard, USER_PATH};
5252
use crate::currentprocess::TestProcess;
5353
use crate::test::Env;
5454

src/test.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use crate::currentprocess::TestProcess;
1919
use crate::dist::TargetTriple;
2020

2121
#[cfg(windows)]
22-
pub use crate::cli::self_update::test::{get_path, RegistryGuard, RegistryValueId, USER_PATH};
22+
pub use crate::cli::self_update::{get_path, RegistryGuard, RegistryValueId, USER_PATH};
2323

2424
// Things that can have environment variables applied to them.
2525
pub trait Env {

0 commit comments

Comments
 (0)