Improve invalid environment warning messages (#7544)

Adds display of the target path of the link (since the link filename
itself is basically static) and distinguishes between broken links and
missing files.
This commit is contained in:
Zanie Blue 2024-09-19 09:11:17 -05:00 committed by GitHub
parent 248bef13bd
commit 99d57ca80e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 131 additions and 9 deletions

View File

@ -213,10 +213,20 @@ impl InstalledTools {
Err(uv_python::Error::Query(uv_python::InterpreterError::NotFound(
interpreter_path,
))) => {
warn!(
"Ignoring existing virtual environment linked to non-existent Python interpreter: {}",
interpreter_path.user_display()
);
if interpreter_path.is_symlink() {
let target_path = fs_err::read_link(&interpreter_path)?;
warn!(
"Ignoring existing virtual environment linked to non-existent Python interpreter: {} -> {}",
interpreter_path.user_display(),
target_path.user_display()
);
} else {
warn!(
"Ignoring existing virtual environment with missing Python interpreter: {}",
interpreter_path.user_display()
);
}
Ok(None)
}
Err(err) => Err(err.into()),

View File

@ -401,10 +401,19 @@ impl FoundInterpreter {
}
}
Err(uv_python::Error::Query(uv_python::InterpreterError::NotFound(path))) => {
warn_user!(
"Ignoring existing virtual environment linked to non-existent Python interpreter: {}",
path.user_display().cyan()
);
if path.is_symlink() {
let target_path = fs_err::read_link(&path)?;
warn_user!(
"Ignoring existing virtual environment linked to non-existent Python interpreter: {} -> {}",
path.user_display().cyan(),
target_path.user_display().cyan(),
);
} else {
warn_user!(
"Ignoring existing virtual environment with missing Python interpreter: {}",
path.user_display().cyan()
);
}
}
Err(err) => return Err(err.into()),
};

View File

@ -5,7 +5,7 @@ use assert_cmd::prelude::*;
use assert_fs::{fixture::ChildPath, prelude::*};
use insta::assert_snapshot;
use common::{uv_snapshot, TestContext};
use common::{uv_snapshot, venv_bin_path, TestContext};
use predicates::prelude::predicate;
use tempfile::tempdir_in;
@ -2613,3 +2613,106 @@ fn sync_scripts_project_not_packaged() -> Result<()> {
Ok(())
}
#[test]
fn sync_invalid_environment() -> Result<()> {
let context = TestContext::new_with_versions(&["3.11", "3.12"])
.with_filtered_virtualenv_bin()
.with_filtered_python_names();
let pyproject_toml = context.temp_dir.child("pyproject.toml");
pyproject_toml.write_str(
r#"
[project]
name = "project"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = ["iniconfig"]
"#,
)?;
// If the directory already exists and is not a virtual environment we should fail with an error
fs_err::create_dir(context.temp_dir.join(".venv"))?;
fs_err::write(context.temp_dir.join(".venv").join("file"), b"")?;
uv_snapshot!(context.filters(), context.sync(), @r###"
success: false
exit_code: 2
----- stdout -----
----- stderr -----
error: Project virtual environment directory `[VENV]/` cannot be used because it is not a virtual environment and is non-empty
"###);
// But if it's just an incompatible virtual environment...
fs_err::remove_dir_all(context.temp_dir.join(".venv"))?;
uv_snapshot!(context.filters(), context.venv().arg("--python").arg("3.11"), @r###"
success: true
exit_code: 0
----- stdout -----
----- stderr -----
Using Python 3.11.[X] interpreter at: [PYTHON-3.11]
Creating virtual environment at: .venv
Activate with: source .venv/[BIN]/activate
"###);
// Even with some extraneous content...
fs_err::write(context.temp_dir.join(".venv").join("file"), b"")?;
// We can delete and use it
uv_snapshot!(context.filters(), context.sync(), @r###"
success: true
exit_code: 0
----- stdout -----
----- stderr -----
Using Python 3.12.[X] interpreter at: [PYTHON-3.12]
Removed virtual environment at: .venv
Creating virtual environment at: .venv
Resolved 2 packages in [TIME]
Prepared 1 package in [TIME]
Installed 1 package in [TIME]
+ iniconfig==2.0.0
"###);
let bin = venv_bin_path(context.temp_dir.join(".venv"));
// If it's there's a broken symlink, we should warn
#[cfg(unix)]
{
fs_err::remove_file(bin.join("python"))?;
uv_snapshot!(context.filters(), context.sync(), @r###"
success: true
exit_code: 0
----- stdout -----
----- stderr -----
warning: Ignoring existing virtual environment linked to non-existent Python interpreter: .venv/[BIN]/python -> python
Using Python 3.12.[X] interpreter at: [PYTHON-3.12]
Removed virtual environment at: .venv
Creating virtual environment at: .venv
Resolved 2 packages in [TIME]
Installed 1 package in [TIME]
+ iniconfig==2.0.0
"###);
}
// And if the Python executable is missing entirely we should warn
fs_err::remove_dir_all(&bin)?;
uv_snapshot!(context.filters(), context.sync(), @r###"
success: true
exit_code: 0
----- stdout -----
----- stderr -----
warning: Ignoring existing virtual environment with missing Python interpreter: .venv/[BIN]/python
Using Python 3.12.[X] interpreter at: [PYTHON-3.12]
Removed virtual environment at: .venv
Creating virtual environment at: .venv
Resolved 2 packages in [TIME]
Installed 1 package in [TIME]
+ iniconfig==2.0.0
"###);
Ok(())
}