Replace a smol::block_on
This commit is contained in:
parent
dc0e81b13b
commit
7030465d04
2 changed files with 95 additions and 104 deletions
|
@ -1008,6 +1008,7 @@ const BINARY_DIR: &str = if cfg!(target_os = "windows") {
|
||||||
"bin"
|
"bin"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// TODO lw: this depends on the shell?
|
||||||
const ACTIVATE_PATH: &str = if cfg!(target_os = "windows") {
|
const ACTIVATE_PATH: &str = if cfg!(target_os = "windows") {
|
||||||
"Scripts/activate.bat"
|
"Scripts/activate.bat"
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::{Project, ProjectPath};
|
use crate::{Project, ProjectPath};
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use collections::HashMap;
|
use collections::HashMap;
|
||||||
use gpui::{App, AppContext as _, Context, Entity, Task, WeakEntity};
|
use gpui::{App, AppContext as _, AsyncApp, Context, Entity, Task, WeakEntity};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use language::LanguageName;
|
use language::LanguageName;
|
||||||
use remote::ssh_session::SshArgs;
|
use remote::ssh_session::SshArgs;
|
||||||
|
@ -122,12 +122,12 @@ impl Project {
|
||||||
|
|
||||||
cx.spawn(async move |project, cx| {
|
cx.spawn(async move |project, cx| {
|
||||||
let python_venv_directory = if let Some(path) = path {
|
let python_venv_directory = if let Some(path) = path {
|
||||||
project
|
match project.upgrade() {
|
||||||
.update(cx, |this, cx| {
|
Some(project) => Self::python_venv_directory(project, path, venv.clone(), cx)
|
||||||
this.python_venv_directory(path, venv.clone(), cx)
|
.await?
|
||||||
})?
|
.zip(Some(venv)),
|
||||||
.await
|
None => None,
|
||||||
.zip(Some(venv))
|
}
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
@ -166,27 +166,18 @@ impl Project {
|
||||||
};
|
};
|
||||||
|
|
||||||
let activate_keyword = match venv_settings.activate_script {
|
let activate_keyword = match venv_settings.activate_script {
|
||||||
terminal_settings::ActivateScript::Default => match std::env::consts::OS {
|
terminal_settings::ActivateScript::Default => ".",
|
||||||
"windows" => ".",
|
|
||||||
_ => ".",
|
|
||||||
},
|
|
||||||
terminal_settings::ActivateScript::Nushell => "overlay use",
|
terminal_settings::ActivateScript::Nushell => "overlay use",
|
||||||
terminal_settings::ActivateScript::PowerShell => ".",
|
terminal_settings::ActivateScript::PowerShell => ".",
|
||||||
terminal_settings::ActivateScript::Pyenv => "pyenv",
|
terminal_settings::ActivateScript::Pyenv => "pyenv",
|
||||||
_ => "source",
|
_ => "source",
|
||||||
};
|
};
|
||||||
|
|
||||||
let line_ending = match std::env::consts::OS {
|
let line_ending = if cfg!(windows) { '\r' } else { 'n' };
|
||||||
"windows" => "\r",
|
|
||||||
_ => "\n",
|
|
||||||
};
|
|
||||||
|
|
||||||
if venv_settings.venv_name.is_empty() {
|
if venv_settings.venv_name.is_empty() {
|
||||||
let path = python_venv_directory
|
let path = python_venv_directory
|
||||||
.join(match std::env::consts::OS {
|
.join(BINARY_DIR)
|
||||||
"windows" => "Scripts",
|
|
||||||
_ => "bin",
|
|
||||||
})
|
|
||||||
.join(activate_script_name)
|
.join(activate_script_name)
|
||||||
.to_string_lossy()
|
.to_string_lossy()
|
||||||
.to_string();
|
.to_string();
|
||||||
|
@ -486,98 +477,91 @@ impl Project {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn python_venv_directory(
|
async fn python_venv_directory(
|
||||||
&self,
|
this: Entity<Self>,
|
||||||
abs_path: Arc<Path>,
|
abs_path: Arc<Path>,
|
||||||
venv_settings: VenvSettings,
|
venv_settings: VenvSettings,
|
||||||
cx: &Context<Project>,
|
cx: &mut AsyncApp,
|
||||||
) -> Task<Option<PathBuf>> {
|
) -> Result<Option<PathBuf>> {
|
||||||
cx.spawn(async move |this, cx| {
|
let Some((worktree, relative_path)) =
|
||||||
if let Some((worktree, relative_path)) = this
|
this.update(cx, |this, cx| this.find_worktree(&abs_path, cx))?
|
||||||
.update(cx, |this, cx| this.find_worktree(&abs_path, cx))
|
else {
|
||||||
.ok()?
|
return Ok(None);
|
||||||
{
|
};
|
||||||
let toolchain = this
|
let toolchain = this
|
||||||
.update(cx, |this, cx| {
|
.update(cx, |this, cx| {
|
||||||
this.active_toolchain(
|
this.active_toolchain(
|
||||||
ProjectPath {
|
ProjectPath {
|
||||||
worktree_id: worktree.read(cx).id(),
|
worktree_id: worktree.read(cx).id(),
|
||||||
path: relative_path.into(),
|
path: relative_path.into(),
|
||||||
},
|
},
|
||||||
LanguageName::new("Python"),
|
LanguageName::new("Python"),
|
||||||
cx,
|
cx,
|
||||||
)
|
)
|
||||||
})
|
})?
|
||||||
.ok()?
|
.await;
|
||||||
.await;
|
|
||||||
|
|
||||||
if let Some(toolchain) = toolchain {
|
if let Some(toolchain) = toolchain {
|
||||||
let toolchain_path = Path::new(toolchain.path.as_ref());
|
let toolchain_path = Path::new(toolchain.path.as_ref());
|
||||||
return Some(toolchain_path.parent()?.parent()?.to_path_buf());
|
return Ok(toolchain_path
|
||||||
|
.parent()
|
||||||
|
.and_then(|p| Some(p.parent()?.to_path_buf())));
|
||||||
|
}
|
||||||
|
|
||||||
|
let Some(venv_settings) = venv_settings.as_option() else {
|
||||||
|
return Ok(None);
|
||||||
|
};
|
||||||
|
|
||||||
|
let tool = this.update(cx, |this, cx| {
|
||||||
|
venv_settings
|
||||||
|
.directories
|
||||||
|
.iter()
|
||||||
|
.map(|name| abs_path.join(name))
|
||||||
|
.find(|venv_path| {
|
||||||
|
let bin_path = venv_path.join(BINARY_DIR);
|
||||||
|
this.find_worktree(&bin_path, cx)
|
||||||
|
.and_then(|(worktree, relative_path)| {
|
||||||
|
worktree.read(cx).entry_for_path(&relative_path)
|
||||||
|
})
|
||||||
|
.is_some_and(|entry| entry.is_dir())
|
||||||
|
})
|
||||||
|
})?;
|
||||||
|
|
||||||
|
if let Some(toolchain_path) = tool {
|
||||||
|
return Ok(Some(toolchain_path));
|
||||||
|
}
|
||||||
|
|
||||||
|
let r = this.update(cx, move |_, cx| {
|
||||||
|
let fs = worktree.read(cx).as_local()?.fs().clone();
|
||||||
|
let map: Vec<_> = venv_settings
|
||||||
|
.directories
|
||||||
|
.iter()
|
||||||
|
.map(|name| abs_path.join(name))
|
||||||
|
.collect();
|
||||||
|
Some(cx.spawn(async move |_, _| {
|
||||||
|
for venv_path in map {
|
||||||
|
let bin_path = venv_path.join(BINARY_DIR);
|
||||||
|
// One-time synchronous check is acceptable for terminal/task initialization
|
||||||
|
// we are within a spawned future anyways
|
||||||
|
let exists = fs
|
||||||
|
.metadata(&bin_path)
|
||||||
|
.await
|
||||||
|
.ok()
|
||||||
|
.flatten()
|
||||||
|
.map_or(false, |meta| meta.is_dir);
|
||||||
|
if exists {
|
||||||
|
return Some(venv_path);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
None
|
||||||
let venv_settings = venv_settings.as_option()?;
|
}))
|
||||||
this.update(cx, move |this, cx| {
|
})?;
|
||||||
if let Some(path) = this.find_venv_in_worktree(&abs_path, &venv_settings, cx) {
|
Ok(match r {
|
||||||
return Some(path);
|
Some(task) => task.await,
|
||||||
}
|
None => None,
|
||||||
this.find_venv_on_filesystem(&abs_path, &venv_settings, cx)
|
|
||||||
})
|
|
||||||
.ok()
|
|
||||||
.flatten()
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_venv_in_worktree(
|
|
||||||
&self,
|
|
||||||
abs_path: &Path,
|
|
||||||
venv_settings: &terminal_settings::VenvSettingsContent,
|
|
||||||
cx: &App,
|
|
||||||
) -> Option<PathBuf> {
|
|
||||||
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);
|
|
||||||
self.find_worktree(&bin_path, cx)
|
|
||||||
.and_then(|(worktree, relative_path)| {
|
|
||||||
worktree.read(cx).entry_for_path(&relative_path)
|
|
||||||
})
|
|
||||||
.is_some_and(|entry| entry.is_dir())
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn find_venv_on_filesystem(
|
|
||||||
&self,
|
|
||||||
abs_path: &Path,
|
|
||||||
venv_settings: &terminal_settings::VenvSettingsContent,
|
|
||||||
cx: &App,
|
|
||||||
) -> 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 activate_script_kind(shell: Option<&str>) -> ActivateScript {
|
fn activate_script_kind(shell: Option<&str>) -> ActivateScript {
|
||||||
let shell_env = std::env::var("SHELL").ok();
|
let shell_env = std::env::var("SHELL").ok();
|
||||||
let shell_path = shell.or_else(|| shell_env.as_deref());
|
let shell_path = shell.or_else(|| shell_env.as_deref());
|
||||||
|
@ -599,6 +583,12 @@ impl Project {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const BINARY_DIR: &str = if cfg!(target_os = "windows") {
|
||||||
|
"Scripts"
|
||||||
|
} else {
|
||||||
|
"bin"
|
||||||
|
};
|
||||||
|
|
||||||
pub fn wrap_for_ssh(
|
pub fn wrap_for_ssh(
|
||||||
ssh_command: &SshCommand,
|
ssh_command: &SshCommand,
|
||||||
command: Option<(&String, &Vec<String>)>,
|
command: Option<(&String, &Vec<String>)>,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue