askpass: Fix cli path when executed in a remote server (#39475)

Closes #39469
Closes #39438
Closes #39458

I'm not able to test it, i would appreciate if somebody could do it. I
think this bug was present also for SSH remote projects

Release Notes:

- Fixed an issue where zed bin was not found in remote servers for
askpass

---------

Signed-off-by: Marco Mihai Condrache <52580954+marcocondrache@users.noreply.github.com>
This commit is contained in:
Marco Mihai Condrache
2025-10-07 00:49:06 +02:00
committed by GitHub
parent e680dfb0a0
commit 4de13e06ec
7 changed files with 114 additions and 57 deletions
+45 -16
View File
@@ -1,3 +1,4 @@
use anyhow::Context;
use globset::{Glob, GlobSet, GlobSetBuilder};
use itertools::Itertools;
use regex::Regex;
@@ -35,8 +36,19 @@ pub fn home_dir() -> &'static PathBuf {
}
pub trait PathExt {
/// Compacts a given file path by replacing the user's home directory
/// prefix with a tilde (`~`).
///
/// # Returns
///
/// * A `PathBuf` containing the compacted file path. If the input path
/// does not have the user's home directory prefix, or if we are not on
/// Linux or macOS, the original path is returned unchanged.
fn compact(&self) -> PathBuf;
/// Returns a file's extension or, if the file is hidden, its name without the leading dot
fn extension_or_hidden_file_name(&self) -> Option<&str>;
fn try_from_bytes<'a>(bytes: &'a [u8]) -> anyhow::Result<Self>
where
Self: From<&'a Path>,
@@ -48,7 +60,6 @@ pub trait PathExt {
}
#[cfg(windows)]
{
use anyhow::Context as _;
use tendril::fmt::{Format, WTF8};
WTF8::validate(bytes)
.then(|| {
@@ -60,19 +71,24 @@ pub trait PathExt {
.with_context(|| format!("Invalid WTF-8 sequence: {bytes:?}"))
}
}
/// Converts a local path to one that can be used inside of WSL.
/// Returns `None` if the path cannot be converted into a WSL one (network share).
fn local_to_wsl(&self) -> Option<PathBuf>;
/// Returns a file's "full" joined collection of extensions, in the case where a file does not
/// just have a singular extension but instead has multiple (e.g File.tar.gz, Component.stories.tsx)
///
/// Will provide back the extensions joined together such as tar.gz or stories.tsx
fn multiple_extensions(&self) -> Option<String>;
/// Try to make a shell-safe representation of the path.
///
/// For Unix, the path is escaped to be safe for POSIX shells
fn try_shell_safe(&self) -> anyhow::Result<String>;
}
impl<T: AsRef<Path>> PathExt for T {
/// Compacts a given file path by replacing the user's home directory
/// prefix with a tilde (`~`).
///
/// # Returns
///
/// * A `PathBuf` containing the compacted file path. If the input path
/// does not have the user's home directory prefix, or if we are not on
/// Linux or macOS, the original path is returned unchanged.
fn compact(&self) -> PathBuf {
if cfg!(any(target_os = "linux", target_os = "freebsd")) || cfg!(target_os = "macos") {
match self.as_ref().strip_prefix(home_dir().as_path()) {
@@ -89,7 +105,6 @@ impl<T: AsRef<Path>> PathExt for T {
}
}
/// Returns a file's extension or, if the file is hidden, its name without the leading dot
fn extension_or_hidden_file_name(&self) -> Option<&str> {
let path = self.as_ref();
let file_name = path.file_name()?.to_str()?;
@@ -102,8 +117,6 @@ impl<T: AsRef<Path>> PathExt for T {
.or_else(|| path.file_stem()?.to_str())
}
/// Converts a local path to one that can be used inside of WSL.
/// Returns `None` if the path cannot be converted into a WSL one (network share).
fn local_to_wsl(&self) -> Option<PathBuf> {
// quite sketchy to convert this back to path at the end, but a lot of functions only accept paths
// todo: ideally rework them..?
@@ -133,10 +146,6 @@ impl<T: AsRef<Path>> PathExt for T {
Some(new_path.into())
}
/// Returns a file's "full" joined collection of extensions, in the case where a file does not
/// just have a singular extension but instead has multiple (e.g File.tar.gz, Component.stories.tsx)
///
/// Will provide back the extensions joined together such as tar.gz or stories.tsx
fn multiple_extensions(&self) -> Option<String> {
let path = self.as_ref();
let file_name = path.file_name()?.to_str()?;
@@ -153,6 +162,26 @@ impl<T: AsRef<Path>> PathExt for T {
Some(parts.into_iter().join("."))
}
fn try_shell_safe(&self) -> anyhow::Result<String> {
#[cfg(target_os = "windows")]
{
Ok(self.as_ref().to_string_lossy().to_string())
}
#[cfg(not(target_os = "windows"))]
{
let path_str = self
.as_ref()
.to_str()
.with_context(|| "Path contains invalid UTF-8")?;
// As of writing, this can only be fail if the path contains a null byte, which shouldn't be possible
// but shlex has annotated the error as #[non_exhaustive] so we can't make it a compile error if other
// errors are introduced in the future :(
Ok(shlex::try_quote(path_str)?.into_owned())
}
}
}
/// In memory, this is identical to `Path`. On non-Windows conversions to this type are no-ops. On