debugger: Install debugpy into user's venv if there's one selected (#35617)
Closes #35388 Release Notes: - debugger: Fixed Python debug sessions failing to launch due to a missing debugpy installation. Debugpy is now installed into user's venv if there's one available.
This commit is contained in:
parent
182edbf526
commit
91bbdb7002
1 changed files with 40 additions and 21 deletions
|
@ -126,38 +126,42 @@ impl PythonDebugAdapter {
|
|||
}
|
||||
None
|
||||
}
|
||||
|
||||
const BINARY_DIR: &str = if cfg!(target_os = "windows") {
|
||||
"Scripts"
|
||||
} else {
|
||||
"bin"
|
||||
};
|
||||
async fn base_venv(&self, delegate: &dyn DapDelegate) -> Result<Arc<Path>, String> {
|
||||
const BINARY_DIR: &str = if cfg!(target_os = "windows") {
|
||||
"Scripts"
|
||||
} else {
|
||||
"bin"
|
||||
};
|
||||
self.python_venv_base
|
||||
.get_or_init(move || async move {
|
||||
let venv_base = Self::ensure_venv(delegate)
|
||||
.await
|
||||
.map_err(|e| format!("{e}"))?;
|
||||
let pip_path = venv_base.join(BINARY_DIR).join("pip3");
|
||||
let installation_succeeded = util::command::new_smol_command(pip_path.as_path())
|
||||
.arg("install")
|
||||
.arg("debugpy")
|
||||
.arg("-U")
|
||||
.output()
|
||||
.await
|
||||
.map_err(|e| format!("{e}"))?
|
||||
.status
|
||||
.success();
|
||||
if !installation_succeeded {
|
||||
return Err("debugpy installation failed".into());
|
||||
}
|
||||
|
||||
Self::install_debugpy_into_venv(&venv_base).await?;
|
||||
Ok(venv_base)
|
||||
})
|
||||
.await
|
||||
.clone()
|
||||
}
|
||||
|
||||
async fn install_debugpy_into_venv(venv_path: &Path) -> Result<(), String> {
|
||||
let pip_path = venv_path.join(Self::BINARY_DIR).join("pip3");
|
||||
let installation_succeeded = util::command::new_smol_command(pip_path.as_path())
|
||||
.arg("install")
|
||||
.arg("debugpy")
|
||||
.arg("-U")
|
||||
.output()
|
||||
.await
|
||||
.map_err(|e| format!("{e}"))?
|
||||
.status
|
||||
.success();
|
||||
if !installation_succeeded {
|
||||
return Err("debugpy installation failed".into());
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn get_installed_binary(
|
||||
&self,
|
||||
delegate: &Arc<dyn DapDelegate>,
|
||||
|
@ -629,11 +633,22 @@ impl DebugAdapter for PythonDebugAdapter {
|
|||
.await;
|
||||
}
|
||||
|
||||
let base_path = config
|
||||
.config
|
||||
.get("cwd")
|
||||
.and_then(|cwd| {
|
||||
cwd.as_str()
|
||||
.map(Path::new)?
|
||||
.strip_prefix(delegate.worktree_root_path())
|
||||
.ok()
|
||||
})
|
||||
.unwrap_or_else(|| "".as_ref())
|
||||
.into();
|
||||
let toolchain = delegate
|
||||
.toolchain_store()
|
||||
.active_toolchain(
|
||||
delegate.worktree_id(),
|
||||
Arc::from("".as_ref()),
|
||||
base_path,
|
||||
language::LanguageName::new(Self::LANGUAGE_NAME),
|
||||
cx,
|
||||
)
|
||||
|
@ -641,6 +656,10 @@ impl DebugAdapter for PythonDebugAdapter {
|
|||
|
||||
if let Some(toolchain) = &toolchain {
|
||||
if let Some(path) = Path::new(&toolchain.path.to_string()).parent() {
|
||||
if let Some(parent) = path.parent() {
|
||||
Self::install_debugpy_into_venv(parent).await.ok();
|
||||
}
|
||||
|
||||
let debugpy_path = path.join("debugpy");
|
||||
if delegate.fs().is_file(&debugpy_path).await {
|
||||
log::debug!(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue