From 9a85104d6753ff00a1ecd42de5e8f5648263cc35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Thu, 23 Jan 2025 20:26:06 +0100 Subject: [PATCH] Make virtualenv creation in tidy more robust --- src/tools/tidy/src/ext_tool_checks.rs | 30 +++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/src/tools/tidy/src/ext_tool_checks.rs b/src/tools/tidy/src/ext_tool_checks.rs index 00c349a13a49..6eef1c9648b6 100644 --- a/src/tools/tidy/src/ext_tool_checks.rs +++ b/src/tools/tidy/src/ext_tool_checks.rs @@ -360,22 +360,40 @@ fn create_venv_at_path(path: &Path) -> Result<(), Error> { return Err(ret); }; - eprintln!("creating virtual environment at '{}' using '{sys_py}'", path.display()); - let out = Command::new(sys_py).args(["-m", "virtualenv"]).arg(path).output().unwrap(); + // First try venv, which should be packaged in the Python3 standard library. + // If it is not available, try to create the virtual environment using the + // virtualenv package. + if try_create_venv(sys_py, path, "venv").is_ok() { + return Ok(()); + } + try_create_venv(sys_py, path, "virtualenv") +} + +fn try_create_venv(python: &str, path: &Path, module: &str) -> Result<(), Error> { + eprintln!( + "creating virtual environment at '{}' using '{python}' and '{module}'", + path.display() + ); + let out = Command::new(python).args(["-m", module]).arg(path).output().unwrap(); if out.status.success() { return Ok(()); } let stderr = String::from_utf8_lossy(&out.stderr); - let err = if stderr.contains("No module named virtualenv") { + let err = if stderr.contains(&format!("No module named {module}")) { Error::Generic(format!( - "virtualenv not found: you may need to install it \ - (`{sys_py} -m pip install virtualenv`)" + r#"{module} not found: you may need to install it: +`{python} -m pip install {module}` +If you see an error about "externally managed environment" when running the above command, +either install `{module}` using your system package manager +(e.g. `sudo apt-get install {python}-{module}`) or create a virtual environment manually, install +`{module}` in it and then activate it before running tidy. +"# )) } else { Error::Generic(format!( - "failed to create venv at '{}' using {sys_py}: {stderr}", + "failed to create venv at '{}' using {python} -m {module}: {stderr}", path.display() )) };