python: Use pip provided by our 'base' venv (#36414)
Closes #36218 Release Notes: - Debugger: Python debugger installation no longer assumes that pip is available in global Python installation
This commit is contained in:
parent
db31fa67f3
commit
9b78c46902
1 changed files with 48 additions and 10 deletions
|
@ -24,6 +24,7 @@ use util::{ResultExt, maybe};
|
|||
|
||||
#[derive(Default)]
|
||||
pub(crate) struct PythonDebugAdapter {
|
||||
base_venv_path: OnceCell<Result<Arc<Path>, String>>,
|
||||
debugpy_whl_base_path: OnceCell<Result<Arc<Path>, String>>,
|
||||
}
|
||||
|
||||
|
@ -91,14 +92,12 @@ impl PythonDebugAdapter {
|
|||
})
|
||||
}
|
||||
|
||||
async fn fetch_wheel(delegate: &Arc<dyn DapDelegate>) -> Result<Arc<Path>, String> {
|
||||
let system_python = Self::system_python_name(delegate)
|
||||
.await
|
||||
.ok_or_else(|| String::from("Could not find a Python installation"))?;
|
||||
let command: &OsStr = system_python.as_ref();
|
||||
async fn fetch_wheel(&self, delegate: &Arc<dyn DapDelegate>) -> Result<Arc<Path>, String> {
|
||||
let download_dir = debug_adapters_dir().join(Self::ADAPTER_NAME).join("wheels");
|
||||
std::fs::create_dir_all(&download_dir).map_err(|e| e.to_string())?;
|
||||
let installation_succeeded = util::command::new_smol_command(command)
|
||||
let system_python = self.base_venv_path(delegate).await?;
|
||||
|
||||
let installation_succeeded = util::command::new_smol_command(system_python.as_ref())
|
||||
.args([
|
||||
"-m",
|
||||
"pip",
|
||||
|
@ -114,7 +113,7 @@ impl PythonDebugAdapter {
|
|||
.status
|
||||
.success();
|
||||
if !installation_succeeded {
|
||||
return Err("debugpy installation failed".into());
|
||||
return Err("debugpy installation failed (could not fetch Debugpy's wheel)".into());
|
||||
}
|
||||
|
||||
let wheel_path = std::fs::read_dir(&download_dir)
|
||||
|
@ -139,7 +138,7 @@ impl PythonDebugAdapter {
|
|||
Ok(Arc::from(wheel_path.path()))
|
||||
}
|
||||
|
||||
async fn maybe_fetch_new_wheel(delegate: &Arc<dyn DapDelegate>) {
|
||||
async fn maybe_fetch_new_wheel(&self, delegate: &Arc<dyn DapDelegate>) {
|
||||
let latest_release = delegate
|
||||
.http_client()
|
||||
.get(
|
||||
|
@ -191,7 +190,7 @@ impl PythonDebugAdapter {
|
|||
)
|
||||
.await
|
||||
.ok()?;
|
||||
Self::fetch_wheel(delegate).await.ok()?;
|
||||
self.fetch_wheel(delegate).await.ok()?;
|
||||
}
|
||||
Some(())
|
||||
})
|
||||
|
@ -204,7 +203,7 @@ impl PythonDebugAdapter {
|
|||
) -> Result<Arc<Path>, String> {
|
||||
self.debugpy_whl_base_path
|
||||
.get_or_init(|| async move {
|
||||
Self::maybe_fetch_new_wheel(delegate).await;
|
||||
self.maybe_fetch_new_wheel(delegate).await;
|
||||
Ok(Arc::from(
|
||||
debug_adapters_dir()
|
||||
.join(Self::ADAPTER_NAME)
|
||||
|
@ -217,6 +216,45 @@ impl PythonDebugAdapter {
|
|||
.clone()
|
||||
}
|
||||
|
||||
async fn base_venv_path(&self, delegate: &Arc<dyn DapDelegate>) -> Result<Arc<Path>, String> {
|
||||
self.base_venv_path
|
||||
.get_or_init(|| async {
|
||||
let base_python = Self::system_python_name(delegate)
|
||||
.await
|
||||
.ok_or_else(|| String::from("Could not find a Python installation"))?;
|
||||
|
||||
let did_succeed = util::command::new_smol_command(base_python)
|
||||
.args(["-m", "venv", "zed_base_venv"])
|
||||
.current_dir(
|
||||
paths::debug_adapters_dir().join(Self::DEBUG_ADAPTER_NAME.as_ref()),
|
||||
)
|
||||
.spawn()
|
||||
.map_err(|e| format!("{e:#?}"))?
|
||||
.status()
|
||||
.await
|
||||
.map_err(|e| format!("{e:#?}"))?
|
||||
.success();
|
||||
if !did_succeed {
|
||||
return Err("Failed to create base virtual environment".into());
|
||||
}
|
||||
|
||||
const DIR: &'static str = if cfg!(target_os = "windows") {
|
||||
"Scripts"
|
||||
} else {
|
||||
"bin"
|
||||
};
|
||||
Ok(Arc::from(
|
||||
paths::debug_adapters_dir()
|
||||
.join(Self::DEBUG_ADAPTER_NAME.as_ref())
|
||||
.join("zed_base_venv")
|
||||
.join(DIR)
|
||||
.join("python3")
|
||||
.as_ref(),
|
||||
))
|
||||
})
|
||||
.await
|
||||
.clone()
|
||||
}
|
||||
async fn system_python_name(delegate: &Arc<dyn DapDelegate>) -> Option<String> {
|
||||
const BINARY_NAMES: [&str; 3] = ["python3", "python", "py"];
|
||||
let mut name = None;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue