terminal: Fix detection of ignored python venv (#20227)

Closes #19227

Since items listed in `.gitignore` file are not included in a worktree,
python virtual environment cannot be detected until venv directory is
unfolded from project panel and forcefully added into worktree. I didn't
come up with anything better than scanning fs directly. I'm not sure how
it will affect remote development. if at all.

Release Notes:

- Fixed detection of `detect_venv.directories` ignored by a worktree
This commit is contained in:
Askar 2024-11-13 21:19:25 +05:00 committed by GitHub
parent eb4e7472e6
commit 7832883c74
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -276,6 +276,18 @@ impl Project {
cx: &AppContext,
) -> Option<PathBuf> {
let venv_settings = settings.detect_venv.as_option()?;
if let Some(path) = self.find_venv_in_worktree(abs_path, &venv_settings, cx) {
return Some(path);
}
self.find_venv_on_filesystem(abs_path, &venv_settings, cx)
}
fn find_venv_in_worktree(
&self,
abs_path: &Path,
venv_settings: &terminal_settings::VenvSettingsContent,
cx: &AppContext,
) -> Option<PathBuf> {
let bin_dir_name = match std::env::consts::OS {
"windows" => "Scripts",
_ => "bin",
@ -283,7 +295,7 @@ impl Project {
venv_settings
.directories
.iter()
.map(|virtual_environment_name| abs_path.join(virtual_environment_name))
.map(|name| abs_path.join(name))
.find(|venv_path| {
let bin_path = venv_path.join(bin_dir_name);
self.find_worktree(&bin_path, cx)
@ -294,6 +306,32 @@ impl Project {
})
}
fn find_venv_on_filesystem(
&self,
abs_path: &Path,
venv_settings: &terminal_settings::VenvSettingsContent,
cx: &AppContext,
) -> Option<PathBuf> {
let (worktree, _) = self.find_worktree(abs_path, cx)?;
let fs = worktree.read(cx).as_local()?.fs();
let bin_dir_name = match std::env::consts::OS {
"windows" => "Scripts",
_ => "bin",
};
venv_settings
.directories
.iter()
.map(|name| abs_path.join(name))
.find(|venv_path| {
let bin_path = venv_path.join(bin_dir_name);
// One-time synchronous check is acceptable for terminal/task initialization
smol::block_on(fs.metadata(&bin_path))
.ok()
.flatten()
.map_or(false, |meta| meta.is_dir)
})
}
fn python_activate_command(
&self,
venv_base_directory: &Path,