feat: Enhance executable resolution by refreshing PATH (#1098)
* Refresh path on executable lookup * Make resolve_executable_path async * Handle task attempt start failure gracefully * clippy fix * Remove unused to_shell_string * Lint --------- Co-authored-by: Alex Netsch <alex@bloop.ai>
This commit is contained in:
@@ -23,7 +23,7 @@ use std::{
|
||||
|
||||
use base64::{Engine, engine::general_purpose::STANDARD as BASE64_STANDARD};
|
||||
use thiserror::Error;
|
||||
use utils::shell::resolve_executable_path;
|
||||
use utils::shell::resolve_executable_path_blocking; // TODO: make GitCli async
|
||||
|
||||
use crate::services::git::Commit;
|
||||
|
||||
@@ -497,14 +497,15 @@ impl GitCli {
|
||||
/// Return true if there are staged changes (index differs from HEAD)
|
||||
pub fn has_staged_changes(&self, repo_path: &Path) -> Result<bool, GitCliError> {
|
||||
// `git diff --cached --quiet` returns exit code 1 if there are differences
|
||||
let out = Command::new(resolve_executable_path("git").ok_or(GitCliError::NotAvailable)?)
|
||||
.arg("-C")
|
||||
.arg(repo_path)
|
||||
.arg("diff")
|
||||
.arg("--cached")
|
||||
.arg("--quiet")
|
||||
.output()
|
||||
.map_err(|e| GitCliError::CommandFailed(e.to_string()))?;
|
||||
let out =
|
||||
Command::new(resolve_executable_path_blocking("git").ok_or(GitCliError::NotAvailable)?)
|
||||
.arg("-C")
|
||||
.arg(repo_path)
|
||||
.arg("diff")
|
||||
.arg("--cached")
|
||||
.arg("--quiet")
|
||||
.output()
|
||||
.map_err(|e| GitCliError::CommandFailed(e.to_string()))?;
|
||||
match out.status.code() {
|
||||
Some(0) => Ok(false),
|
||||
Some(1) => Ok(true),
|
||||
@@ -625,7 +626,7 @@ impl GitCli {
|
||||
|
||||
/// Ensure `git` is available on PATH
|
||||
fn ensure_available(&self) -> Result<(), GitCliError> {
|
||||
let git = resolve_executable_path("git").ok_or(GitCliError::NotAvailable)?;
|
||||
let git = resolve_executable_path_blocking("git").ok_or(GitCliError::NotAvailable)?;
|
||||
let out = Command::new(&git)
|
||||
.arg("--version")
|
||||
.output()
|
||||
@@ -656,7 +657,7 @@ impl GitCli {
|
||||
S: AsRef<OsStr>,
|
||||
{
|
||||
self.ensure_available()?;
|
||||
let git = resolve_executable_path("git").ok_or(GitCliError::NotAvailable)?;
|
||||
let git = resolve_executable_path_blocking("git").ok_or(GitCliError::NotAvailable)?;
|
||||
let mut cmd = Command::new(&git);
|
||||
cmd.arg("-C").arg(repo_path);
|
||||
for a in args {
|
||||
@@ -684,7 +685,7 @@ impl GitCli {
|
||||
S: AsRef<OsStr>,
|
||||
{
|
||||
self.ensure_available()?;
|
||||
let git = resolve_executable_path("git").ok_or(GitCliError::NotAvailable)?;
|
||||
let git = resolve_executable_path_blocking("git").ok_or(GitCliError::NotAvailable)?;
|
||||
let mut cmd = Command::new(&git);
|
||||
cmd.arg("-C").arg(repo_path);
|
||||
for (k, v) in envs {
|
||||
|
||||
@@ -7,7 +7,7 @@ use std::{
|
||||
use git2::{Error as GitError, Repository};
|
||||
use thiserror::Error;
|
||||
use tracing::{debug, info};
|
||||
use utils::shell::get_shell_command;
|
||||
use utils::shell::resolve_executable_path;
|
||||
|
||||
use super::{
|
||||
git::{GitService, GitServiceError},
|
||||
@@ -429,35 +429,30 @@ impl WorktreeManager {
|
||||
// Try using git rev-parse --git-common-dir from within the worktree
|
||||
let worktree_path_owned = worktree_path.to_path_buf();
|
||||
|
||||
tokio::task::spawn_blocking(move || {
|
||||
let (shell_cmd, shell_arg) = get_shell_command();
|
||||
let git_command = "git rev-parse --git-common-dir";
|
||||
let git_path = resolve_executable_path("git").await?;
|
||||
|
||||
let output = std::process::Command::new(shell_cmd)
|
||||
.args([shell_arg, git_command])
|
||||
.current_dir(&worktree_path_owned)
|
||||
.output()
|
||||
.ok()?;
|
||||
let output = tokio::process::Command::new(git_path)
|
||||
.args(["rev-parse", "--git-common-dir"])
|
||||
.current_dir(&worktree_path_owned)
|
||||
.output()
|
||||
.await
|
||||
.ok()?;
|
||||
|
||||
if output.status.success() {
|
||||
let git_common_dir = String::from_utf8(output.stdout).ok()?.trim().to_string();
|
||||
if output.status.success() {
|
||||
let git_common_dir = String::from_utf8(output.stdout).ok()?.trim().to_string();
|
||||
|
||||
// git-common-dir gives us the path to the .git directory
|
||||
// We need the working directory (parent of .git)
|
||||
let git_dir_path = Path::new(&git_common_dir);
|
||||
if git_dir_path.file_name() == Some(std::ffi::OsStr::new(".git")) {
|
||||
git_dir_path.parent()?.to_str().map(PathBuf::from)
|
||||
} else {
|
||||
// In case of bare repo or unusual setup, use the git-common-dir as is
|
||||
Some(PathBuf::from(git_common_dir))
|
||||
}
|
||||
// git-common-dir gives us the path to the .git directory
|
||||
// We need the working directory (parent of .git)
|
||||
let git_dir_path = Path::new(&git_common_dir);
|
||||
if git_dir_path.file_name() == Some(std::ffi::OsStr::new(".git")) {
|
||||
git_dir_path.parent()?.to_str().map(PathBuf::from)
|
||||
} else {
|
||||
None
|
||||
// In case of bare repo or unusual setup, use the git-common-dir as is
|
||||
Some(PathBuf::from(git_common_dir))
|
||||
}
|
||||
})
|
||||
.await
|
||||
.ok()
|
||||
.flatten()
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// Simple worktree cleanup when we can't determine the main repo
|
||||
|
||||
Reference in New Issue
Block a user