This commit is contained in:
konsti 2025-07-06 13:36:03 +02:00 committed by GitHub
commit c3e74fbd7a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 93 additions and 28 deletions

View file

@ -611,7 +611,7 @@ impl TestContext {
"Activate with: source $1/[BIN]/activate".to_string(), "Activate with: source $1/[BIN]/activate".to_string(),
)); ));
filters.push(( filters.push((
r"Activate with: source (.*)/bin/activate(?:\.\w+)?".to_string(), r"Activate with: source (.*)/bin/activate".to_string(),
"Activate with: source $1/[BIN]/activate".to_string(), "Activate with: source $1/[BIN]/activate".to_string(),
)); ));
@ -722,8 +722,6 @@ impl TestContext {
.unwrap(); .unwrap();
command command
// When running the tests in a venv, ignore that venv, otherwise we'll capture warnings.
.env_remove(EnvVars::VIRTUAL_ENV)
// Disable wrapping of uv output for readability / determinism in snapshots. // Disable wrapping of uv output for readability / determinism in snapshots.
.env(EnvVars::UV_NO_WRAP, "1") .env(EnvVars::UV_NO_WRAP, "1")
// While we disable wrapping in uv above, invoked tools may still wrap their output so // While we disable wrapping in uv above, invoked tools may still wrap their output so
@ -741,10 +739,6 @@ impl TestContext {
// Since downloads, fetches and builds run in parallel, their message output order is // Since downloads, fetches and builds run in parallel, their message output order is
// non-deterministic, so can't capture them in test output. // non-deterministic, so can't capture them in test output.
.env(EnvVars::UV_TEST_NO_CLI_PROGRESS, "1") .env(EnvVars::UV_TEST_NO_CLI_PROGRESS, "1")
.env_remove(EnvVars::UV_CACHE_DIR)
.env_remove(EnvVars::UV_TOOL_BIN_DIR)
.env_remove(EnvVars::XDG_CONFIG_HOME)
.env_remove(EnvVars::XDG_DATA_HOME)
.current_dir(self.temp_dir.path()); .current_dir(self.temp_dir.path());
for (key, value) in &self.extra_env { for (key, value) in &self.extra_env {
@ -754,11 +748,6 @@ impl TestContext {
if activate_venv { if activate_venv {
command.env(EnvVars::VIRTUAL_ENV, self.venv.as_os_str()); command.env(EnvVars::VIRTUAL_ENV, self.venv.as_os_str());
} }
if cfg!(unix) {
// Avoid locale issues in tests
command.env(EnvVars::LC_ALL, "C");
}
} }
/// Create a `pip compile` command for testing. /// Create a `pip compile` command for testing.
@ -1089,6 +1078,9 @@ impl TestContext {
command command
} }
/// The path to the Python interpreter in the venv.
///
/// Don't use this for `Command::new`, use `Self::python_command` instead.
pub fn interpreter(&self) -> PathBuf { pub fn interpreter(&self) -> PathBuf {
let venv = &self.venv; let venv = &self.venv;
if cfg!(unix) { if cfg!(unix) {
@ -1245,7 +1237,17 @@ impl TestContext {
.as_ref() .as_ref()
.expect("A Python version must be provided to create a test virtual environment"), .expect("A Python version must be provided to create a test virtual environment"),
); );
create_venv_from_executable(&self.venv, &self.cache_dir, &executable); assert_cmd::Command::from(self.new_command())
.arg("venv")
.arg(self.venv.as_ref().as_os_str())
.arg("--cache-dir")
.arg(self.cache_dir.path())
.arg("--python")
.arg(executable)
.current_dir(self.venv.as_ref().parent().unwrap())
.assert()
.success();
ChildPath::new(self.venv.as_ref()).assert(predicate::path::is_dir());
} }
/// Copies the files from the ecosystem project given into this text /// Copies the files from the ecosystem project given into this text
@ -1310,8 +1312,13 @@ impl TestContext {
/// Creates a new `Command` that is intended to be suitable for use in /// Creates a new `Command` that is intended to be suitable for use in
/// all tests, but with the given binary. /// all tests, but with the given binary.
///
/// The command contains only essential env vars to avoid the tests getting
/// influenced by host `UV_*`, XDG, or other environment variables.
fn new_command_with(&self, bin: &Path) -> Command { fn new_command_with(&self, bin: &Path) -> Command {
let mut command = Command::new(bin); let mut command = Command::new(bin);
command.env_clear();
// I believe the intent of all tests is that they are run outside the // I believe the intent of all tests is that they are run outside the
// context of an existing git repository. And when they aren't, state // context of an existing git repository. And when they aren't, state
// from the parent git repository can bleed into the behavior of `uv // from the parent git repository can bleed into the behavior of `uv
@ -1326,6 +1333,76 @@ impl TestContext {
// impact it, since it only prevents git from discovering repositories // impact it, since it only prevents git from discovering repositories
// at or above the root. // at or above the root.
command.env(EnvVars::GIT_CEILING_DIRECTORIES, self.root.path()); command.env(EnvVars::GIT_CEILING_DIRECTORIES, self.root.path());
if cfg!(unix) {
// For Unix, we pretend the tests run in a bash for the activate hint, for Windows, shell
// detection assumes PowerShell if `PROMPT` is not set.
command.env("SHELL", "/bin/bash");
// Avoid locale issues in tests
command.env(EnvVars::LC_ALL, "C");
}
// Standard Windows environment variables
//
// Sources:
// - https://ss64.com/nt/syntax-variables.html
// - https://learn.microsoft.com/en-us/windows/win32/procthread/environment-variables
// - https://en.wikipedia.org/wiki/Environment_variable
// - https://www.elevenforum.com/t/complete-list-of-environment-variables-in-windows-11.11212/
let env_vars = &[
"ALLUSERSPROFILE", // C:\ProgramData
"APPDATA", // C:\Users\{username}\AppData\Roaming
"CD", // Current directory (dynamic, cmd.exe only)
"CMDCMDLINE", // Command line that started cmd.exe (dynamic)
"CMDEXTVERSION", // Command extensions version (dynamic)
"COMPUTERNAME", // Computer name
"COMSPEC", // C:\Windows\system32\cmd.exe
"CommonProgramFiles", // C:\Program Files\Common Files
"CommonProgramFiles(x86)", // C:\Program Files (x86)\Common Files (64-bit only)
"CommonProgramW6432", // C:\Program Files\Common Files (64-bit only)
"DATE", // Current date (dynamic, cmd.exe only)
"DIRCMD", // Directory listing format
"DriverData", // C:\Windows\System32\Drivers\DriverData
"ERRORLEVEL", // Exit code of last command (dynamic)
"HOMEDRIVE", // C:
"HOMEPATH", // \Users\{username}
"LOCALAPPDATA", // C:\Users\{username}\AppData\Local
"LOGONSERVER", // \\{servername} (volatile)
"NUMBER_OF_PROCESSORS", // Number of processors
"OS", // Windows_NT
"PATH", // Executable search paths
"PATHEXT", // Executable file extensions
"PROCESSOR_ARCHITECTURE", // AMD64, x86, etc.
"PROCESSOR_IDENTIFIER", // Processor description
"PROCESSOR_LEVEL", // Processor level
"PROCESSOR_REVISION", // Processor revision
"PROMPT", // Command prompt format
"PSModulePath", // PowerShell module paths
"PUBLIC", // C:\Users\Public
"ProgramData", // C:\ProgramData
"ProgramFiles", // C:\Program Files
"ProgramFiles(x86)", // C:\Program Files (x86) (64-bit only)
"ProgramW6432", // C:\Program Files (64-bit only)
"RANDOM", // Random 0-32767 (dynamic, cmd.exe only)
"SystemDrive", // C:
"SystemRoot", // C:\Windows
"SYSTEMROOT", // C:\Windows
"TEMP", // C:\Users\{username}\AppData\Local\Temp
"TIME", // Current time (dynamic, cmd.exe only)
"TMP", // Same as TEMP
"USERDOMAIN", // User domain (volatile)
"USERDOMAIN_ROAMINGPROFILE", // User domain for roaming profile (volatile)
"USERNAME", // Current username
"USERPROFILE", // C:\Users\{username}
"windir", // C:\Windows (same as SystemRoot)
];
for env_var in env_vars {
if let Some(system_root) = env::var_os(env_var) {
command.env(env_var, system_root);
}
}
command command
} }
} }
@ -1387,21 +1464,6 @@ pub fn get_python(version: &PythonVersion) -> PathBuf {
.unwrap_or(PathBuf::from(version.to_string())) .unwrap_or(PathBuf::from(version.to_string()))
} }
/// Create a virtual environment at the given path.
pub fn create_venv_from_executable<P: AsRef<Path>>(path: P, cache_dir: &ChildPath, python: &Path) {
assert_cmd::Command::new(get_bin())
.arg("venv")
.arg(path.as_ref().as_os_str())
.arg("--cache-dir")
.arg(cache_dir.path())
.arg("--python")
.arg(python)
.current_dir(path.as_ref().parent().unwrap())
.assert()
.success();
ChildPath::new(path.as_ref()).assert(predicate::path::is_dir());
}
/// Returns the uv binary that cargo built before launching the tests. /// Returns the uv binary that cargo built before launching the tests.
/// ///
/// <https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-crates> /// <https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-crates>

View file

@ -5802,6 +5802,8 @@ fn deptry_gitignore() {
uv_snapshot!(context.filters(), context.pip_install() uv_snapshot!(context.filters(), context.pip_install()
.arg(format!("deptry_reproducer @ {}", source_dist_dir.join("deptry_reproducer-0.1.0.tar.gz").simplified_display())) .arg(format!("deptry_reproducer @ {}", source_dist_dir.join("deptry_reproducer-0.1.0.tar.gz").simplified_display()))
.arg("--strict") .arg("--strict")
// Set by the test harness, needed by the test
.env("RUSTUP_TOOLCHAIN", std::env::var("RUSTUP_TOOLCHAIN").unwrap())
.current_dir(source_dist_dir), @r###" .current_dir(source_dist_dir), @r###"
success: true success: true
exit_code: 0 exit_code: 0

View file

@ -1,3 +1,4 @@
use std::env;
use std::path::Path; use std::path::Path;
use std::process::Command; use std::process::Command;