python: Init venv/virtualenv activation scripts during list/resolve (#40816)

This means that existence of activation scripts for venv/virtualenv will
be checked locally either on the host if editing locally, or the remote
by the remote proxy if editing a remote project.

Closes https://github.com/zed-industries/zed/issues/40263

Release Notes:

- N/A
This commit is contained in:
Jakub Konka
2025-10-21 22:57:31 +02:00
committed by GitHub
parent fd10017837
commit e49edfac74
8 changed files with 131 additions and 72 deletions
+1
View File
@@ -1060,6 +1060,7 @@ impl Project {
worktree_store.clone(),
environment.clone(),
manifest_tree.clone(),
fs.clone(),
cx,
)
});
+3 -1
View File
@@ -9653,6 +9653,7 @@ fn python_lang(fs: Arc<FakeFs>) -> Arc<Language> {
worktree_root: PathBuf,
subroot_relative_path: Arc<RelPath>,
_: Option<HashMap<String, String>>,
_: &dyn Fs,
) -> ToolchainList {
// This lister will always return a path .venv directories within ancestors
let ancestors = subroot_relative_path.ancestors().collect::<Vec<_>>();
@@ -9677,6 +9678,7 @@ fn python_lang(fs: Arc<FakeFs>) -> Arc<Language> {
&self,
_: PathBuf,
_: Option<HashMap<String, String>>,
_: &dyn Fs,
) -> anyhow::Result<Toolchain> {
Err(anyhow::anyhow!("Not implemented"))
}
@@ -9689,7 +9691,7 @@ fn python_lang(fs: Arc<FakeFs>) -> Arc<Language> {
manifest_name: ManifestName::from(SharedString::new_static("pyproject.toml")),
}
}
async fn activation_script(&self, _: &Toolchain, _: ShellKind, _: &dyn Fs) -> Vec<String> {
fn activation_script(&self, _: &Toolchain, _: ShellKind) -> Vec<String> {
vec![]
}
}
+2 -12
View File
@@ -120,7 +120,6 @@ impl Project {
.map(|p| self.active_toolchain(p, LanguageName::new("Python"), cx))
.collect::<Vec<_>>();
let lang_registry = self.languages.clone();
let fs = self.fs.clone();
cx.spawn(async move |project, cx| {
let shell_kind = ShellKind::new(&shell, is_windows);
let activation_script = maybe!(async {
@@ -133,11 +132,7 @@ impl Project {
.await
.ok();
let lister = language?.toolchain_lister();
return Some(
lister?
.activation_script(&toolchain, shell_kind, fs.as_ref())
.await,
);
return Some(lister?.activation_script(&toolchain, shell_kind));
}
None
})
@@ -347,7 +342,6 @@ impl Project {
let shell_kind = ShellKind::new(&shell, self.path_style(cx).is_windows());
let lang_registry = self.languages.clone();
let fs = self.fs.clone();
cx.spawn(async move |project, cx| {
let activation_script = maybe!(async {
for toolchain in toolchains {
@@ -359,11 +353,7 @@ impl Project {
.await
.ok();
let lister = language?.toolchain_lister();
return Some(
lister?
.activation_script(&toolchain, shell_kind, fs.as_ref())
.await,
);
return Some(lister?.activation_script(&toolchain, shell_kind));
}
None
})
+18 -3
View File
@@ -4,6 +4,7 @@ use anyhow::{Context as _, Result, bail};
use async_trait::async_trait;
use collections::{BTreeMap, IndexSet};
use fs::Fs;
use gpui::{
App, AppContext as _, AsyncApp, Context, Entity, EventEmitter, Subscription, Task, WeakEntity,
};
@@ -60,6 +61,7 @@ impl ToolchainStore {
worktree_store: Entity<WorktreeStore>,
project_environment: Entity<ProjectEnvironment>,
manifest_tree: Entity<ManifestTree>,
fs: Arc<dyn Fs>,
cx: &mut Context<Self>,
) -> Self {
let entity = cx.new(|_| LocalToolchainStore {
@@ -68,6 +70,7 @@ impl ToolchainStore {
project_environment,
active_toolchains: Default::default(),
manifest_tree,
fs,
});
let _sub = cx.subscribe(&entity, |_, _, e: &ToolchainStoreEvent, cx| {
cx.emit(e.clone())
@@ -397,6 +400,7 @@ pub struct LocalToolchainStore {
project_environment: Entity<ProjectEnvironment>,
active_toolchains: BTreeMap<(WorktreeId, LanguageName), BTreeMap<Arc<RelPath>, Toolchain>>,
manifest_tree: Entity<ManifestTree>,
fs: Arc<dyn Fs>,
}
#[async_trait(?Send)]
@@ -485,6 +489,7 @@ impl LocalToolchainStore {
let registry = self.languages.clone();
let manifest_tree = self.manifest_tree.downgrade();
let fs = self.fs.clone();
let environment = self.project_environment.clone();
cx.spawn(async move |this, cx| {
@@ -534,7 +539,12 @@ impl LocalToolchainStore {
cx.background_spawn(async move {
Some((
toolchains
.list(worktree_root, relative_path.path.clone(), project_env)
.list(
worktree_root,
relative_path.path.clone(),
project_env,
fs.as_ref(),
)
.await,
relative_path.path,
))
@@ -568,6 +578,7 @@ impl LocalToolchainStore {
) -> Task<Result<Toolchain>> {
let registry = self.languages.clone();
let environment = self.project_environment.clone();
let fs = self.fs.clone();
cx.spawn(async move |_, cx| {
let language = cx
.background_spawn(registry.language_for_name(&language_name.0))
@@ -586,8 +597,12 @@ impl LocalToolchainStore {
)
})?
.await;
cx.background_spawn(async move { toolchain_lister.resolve(path, project_env).await })
.await
cx.background_spawn(async move {
toolchain_lister
.resolve(path, project_env, fs.as_ref())
.await
})
.await
})
}
}