Fix hanging of tool executions that use shell execution #212

Affected ExecuteShellCommandTool and GetCurrentConfigTool (because of git status).
Solution: Adjust parameters for subprocess creation
This commit is contained in:
Dominik Jain
2025-06-22 01:19:02 +02:00
parent 772bc56fc3
commit ceae28d286
3 changed files with 47 additions and 6 deletions
+7 -5
View File
@@ -1,17 +1,19 @@
__version__ = "2025-05-21"
import logging
log = logging.getLogger(__name__)
def serena_version() -> str:
"""
:return: the version of the package, including git status if available.
"""
from serena.util.git import get_git_status
version = __version__
try:
from sensai.util.git import git_status
from sensai.util.logging import LoggingDisabledContext
with LoggingDisabledContext():
git_status = git_status()
git_status = get_git_status()
version += f"-{git_status.commit[:8]}"
if not git_status.is_clean:
version += "-dirty"
+21
View File
@@ -0,0 +1,21 @@
import logging
from sensai.util.git import GitStatus
from .shell import subprocess_check_output
log = logging.getLogger(__name__)
def get_git_status() -> GitStatus | None:
try:
commit_hash = subprocess_check_output(["git", "rev-parse", "HEAD"])
unstaged = bool(subprocess_check_output(["git", "diff", "--name-only"]))
staged = bool(subprocess_check_output(["git", "diff", "--staged", "--name-only"]))
untracked = bool(subprocess_check_output(["git", "ls-files", "--others", "--exclude-standard"]))
return GitStatus(
commit=commit_hash, has_unstaged_changes=unstaged, has_staged_uncommitted_changes=staged, has_untracked_files=untracked
)
except Exception as e:
log.error("Error determining Git status", exc_info=e)
return None
+19 -1
View File
@@ -24,11 +24,14 @@ def execute_shell_command(command: str, cwd: str | None = None, capture_stderr:
if cwd is None:
cwd = os.getcwd()
is_windows = platform.system() == "Windows"
process = subprocess.Popen(
command,
shell=platform.system() != "Windows",
shell=not is_windows,
stdin=subprocess.DEVNULL,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE if capture_stderr else None,
creationflags=subprocess.CREATE_NO_WINDOW if is_windows else 0,
text=True,
encoding="utf-8",
errors="replace",
@@ -37,3 +40,18 @@ def execute_shell_command(command: str, cwd: str | None = None, capture_stderr:
stdout, stderr = process.communicate()
return ShellCommandResult(stdout=stdout, stderr=stderr, return_code=process.returncode, cwd=cwd)
def subprocess_check_output(args: list[str], encoding: str = "utf-8", strip: bool = True, timeout: float | None = None) -> str:
kwargs = {
"stdin": subprocess.DEVNULL,
"stderr": subprocess.PIPE,
"timeout": timeout,
"env": os.environ.copy(),
}
if platform.system() == "Windows":
kwargs["creationflags"] = subprocess.CREATE_NO_WINDOW
output = subprocess.check_output(args, **kwargs).decode(encoding)
if strip:
output = output.strip()
return output