Pass project environment to runInTerminal requests (#32720)

Closes #ISSUE

Release Notes:

- debugger: Pass environment to run in terminal requests
This commit is contained in:
Conrad Irwin 2025-06-16 09:34:50 -06:00 committed by GitHub
parent d7db4d4e0a
commit 92addb005a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 29 additions and 7 deletions

View file

@ -1,4 +1,5 @@
use anyhow::{Context as _, bail}; use anyhow::{Context as _, bail};
use collections::HashMap;
use dap::{ use dap::{
StartDebuggingRequestArguments, StartDebuggingRequestArguments,
adapters::{ adapters::{
@ -9,7 +10,7 @@ use dap::{
use gpui::{AsyncApp, SharedString}; use gpui::{AsyncApp, SharedString};
use language::LanguageName; use language::LanguageName;
use std::{collections::HashMap, env::consts, ffi::OsStr, path::PathBuf, sync::OnceLock}; use std::{env::consts, ffi::OsStr, path::PathBuf, sync::OnceLock};
use task::TcpArgumentsTemplate; use task::TcpArgumentsTemplate;
use util; use util;

View file

@ -176,6 +176,7 @@ impl DebugPanel {
dap_store.new_session( dap_store.new_session(
scenario.label.clone(), scenario.label.clone(),
DebugAdapterName(scenario.adapter.clone()), DebugAdapterName(scenario.adapter.clone()),
task_context.clone(),
None, None,
cx, cx,
) )
@ -338,12 +339,13 @@ impl DebugPanel {
let adapter = curr_session.read(cx).adapter().clone(); let adapter = curr_session.read(cx).adapter().clone();
let binary = curr_session.read(cx).binary().cloned().unwrap(); let binary = curr_session.read(cx).binary().cloned().unwrap();
let task = curr_session.update(cx, |session, cx| session.shutdown(cx)); let task = curr_session.update(cx, |session, cx| session.shutdown(cx));
let task_context = curr_session.read(cx).task_context().clone();
cx.spawn_in(window, async move |this, cx| { cx.spawn_in(window, async move |this, cx| {
task.await; task.await;
let (session, task) = dap_store_handle.update(cx, |dap_store, cx| { let (session, task) = dap_store_handle.update(cx, |dap_store, cx| {
let session = dap_store.new_session(label, adapter, None, cx); let session = dap_store.new_session(label, adapter, task_context, None, cx);
let task = session.update(cx, |session, cx| { let task = session.update(cx, |session, cx| {
session.boot(binary, worktree, dap_store_handle.downgrade(), cx) session.boot(binary, worktree, dap_store_handle.downgrade(), cx)
@ -393,11 +395,17 @@ impl DebugPanel {
log::error!("Attempted to start a child-session without a binary"); log::error!("Attempted to start a child-session without a binary");
return; return;
}; };
let task_context = parent_session.read(cx).task_context().clone();
binary.request_args = request.clone(); binary.request_args = request.clone();
cx.spawn_in(window, async move |this, cx| { cx.spawn_in(window, async move |this, cx| {
let (session, task) = dap_store_handle.update(cx, |dap_store, cx| { let (session, task) = dap_store_handle.update(cx, |dap_store, cx| {
let session = let session = dap_store.new_session(
dap_store.new_session(label, adapter, Some(parent_session.clone()), cx); label,
adapter,
task_context,
Some(parent_session.clone()),
cx,
);
let task = session.update(cx, |session, cx| { let task = session.update(cx, |session, cx| {
session.boot(binary, worktree, dap_store_handle.downgrade(), cx) session.boot(binary, worktree, dap_store_handle.downgrade(), cx)

View file

@ -1012,7 +1012,8 @@ impl RunningState {
None None
}; };
let mut envs: HashMap<String, String> = Default::default(); let mut envs: HashMap<String, String> =
self.session.read(cx).task_context().project_env.clone();
if let Some(Value::Object(env)) = &request.env { if let Some(Value::Object(env)) = &request.env {
for (key, value) in env { for (key, value) in env {
let value_str = match (key.as_str(), value) { let value_str = match (key.as_str(), value) {

View file

@ -49,7 +49,7 @@ use std::{
path::{Path, PathBuf}, path::{Path, PathBuf},
sync::{Arc, Once}, sync::{Arc, Once},
}; };
use task::{DebugScenario, SpawnInTerminal, TaskTemplate}; use task::{DebugScenario, SpawnInTerminal, TaskContext, TaskTemplate};
use util::ResultExt as _; use util::ResultExt as _;
use worktree::Worktree; use worktree::Worktree;
@ -362,6 +362,7 @@ impl DapStore {
&mut self, &mut self,
label: SharedString, label: SharedString,
adapter: DebugAdapterName, adapter: DebugAdapterName,
task_context: TaskContext,
parent_session: Option<Entity<Session>>, parent_session: Option<Entity<Session>>,
cx: &mut Context<Self>, cx: &mut Context<Self>,
) -> Entity<Session> { ) -> Entity<Session> {
@ -379,6 +380,7 @@ impl DapStore {
parent_session, parent_session,
label, label,
adapter, adapter,
task_context,
cx, cx,
); );
@ -889,7 +891,9 @@ impl dap::adapters::DapDelegate for DapAdapterDelegate {
} }
async fn which(&self, command: &OsStr) -> Option<PathBuf> { async fn which(&self, command: &OsStr) -> Option<PathBuf> {
which::which(command).ok() let worktree_abs_path = self.worktree.abs_path();
let shell_path = self.shell_env().await.get("PATH").cloned();
which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
} }
async fn shell_env(&self) -> HashMap<String, String> { async fn shell_env(&self) -> HashMap<String, String> {

View file

@ -49,6 +49,7 @@ use std::{
path::Path, path::Path,
sync::Arc, sync::Arc,
}; };
use task::TaskContext;
use text::{PointUtf16, ToPointUtf16}; use text::{PointUtf16, ToPointUtf16};
use util::ResultExt; use util::ResultExt;
use worktree::Worktree; use worktree::Worktree;
@ -619,6 +620,7 @@ pub struct Session {
ignore_breakpoints: bool, ignore_breakpoints: bool,
exception_breakpoints: BTreeMap<String, (ExceptionBreakpointsFilter, IsEnabled)>, exception_breakpoints: BTreeMap<String, (ExceptionBreakpointsFilter, IsEnabled)>,
background_tasks: Vec<Task<()>>, background_tasks: Vec<Task<()>>,
task_context: TaskContext,
} }
trait CacheableCommand: Any + Send + Sync { trait CacheableCommand: Any + Send + Sync {
@ -733,6 +735,7 @@ impl Session {
parent_session: Option<Entity<Session>>, parent_session: Option<Entity<Session>>,
label: SharedString, label: SharedString,
adapter: DebugAdapterName, adapter: DebugAdapterName,
task_context: TaskContext,
cx: &mut App, cx: &mut App,
) -> Entity<Self> { ) -> Entity<Self> {
cx.new::<Self>(|cx| { cx.new::<Self>(|cx| {
@ -783,12 +786,17 @@ impl Session {
exception_breakpoints: Default::default(), exception_breakpoints: Default::default(),
label, label,
adapter, adapter,
task_context,
}; };
this this
}) })
} }
pub fn task_context(&self) -> &TaskContext {
&self.task_context
}
pub fn worktree(&self) -> Option<Entity<Worktree>> { pub fn worktree(&self) -> Option<Entity<Worktree>> {
match &self.mode { match &self.mode {
Mode::Building => None, Mode::Building => None,