mirror of
https://github.com/trustedsec/hate_crack.git
synced 2026-04-28 12:03:11 -07:00
fix: locate uv binary before upgrade to handle non-standard PATH
When running as root or via sudo, /root/.local/bin may not be in PATH. Use shutil.which with fallback to ~/.local/bin/uv, and fail clearly if uv can't be found.
This commit is contained in:
@@ -831,11 +831,23 @@ def _run_upgrade():
|
||||
)
|
||||
raise SystemExit(1)
|
||||
repo_root = git_root_result.stdout.strip()
|
||||
|
||||
# Locate the uv binary. It may not be in PATH when running as root or via sudo.
|
||||
import shutil
|
||||
|
||||
uv = shutil.which("uv") or os.path.expanduser("~/.local/bin/uv")
|
||||
if not os.path.isfile(uv):
|
||||
print(
|
||||
"\n Could not find the uv binary."
|
||||
"\n Run manually: git pull && git fetch --tags && uv sync --reinstall-package hate_crack\n"
|
||||
)
|
||||
raise SystemExit(1)
|
||||
|
||||
result = subprocess.run(
|
||||
# git fetch --tags ensures new release tags are visible to setuptools-scm.
|
||||
# uv sync --reinstall-package forces hate_crack to be rebuilt from
|
||||
# current source so setuptools-scm generates the correct version.
|
||||
"git pull && git fetch --tags && uv sync --reinstall-package hate_crack",
|
||||
f"git pull && git fetch --tags && {uv} sync --reinstall-package hate_crack",
|
||||
shell=True,
|
||||
cwd=repo_root,
|
||||
)
|
||||
|
||||
@@ -151,7 +151,9 @@ class TestCheckForUpdates:
|
||||
hc_module, "REQUESTS_AVAILABLE", True
|
||||
), patch("builtins.input", return_value="y"), patch(
|
||||
"subprocess.run", side_effect=[git_root_proc, make_proc]
|
||||
) as mock_run, pytest.raises(
|
||||
) as mock_run, patch("shutil.which", return_value="/usr/local/bin/uv"), patch(
|
||||
"os.path.isfile", return_value=True
|
||||
), pytest.raises(
|
||||
SystemExit
|
||||
):
|
||||
mock_requests.get.return_value = mock_resp
|
||||
@@ -181,6 +183,8 @@ class TestCheckForUpdates:
|
||||
hc_module, "REQUESTS_AVAILABLE", True
|
||||
), patch("builtins.input", return_value="y"), patch(
|
||||
"subprocess.run", side_effect=[git_root_proc, make_proc]
|
||||
), patch("shutil.which", return_value="/usr/local/bin/uv"), patch(
|
||||
"os.path.isfile", return_value=True
|
||||
), pytest.raises(
|
||||
SystemExit
|
||||
):
|
||||
@@ -216,6 +220,14 @@ class TestCheckForUpdates:
|
||||
class TestRunUpgrade:
|
||||
"""Tests for _run_upgrade() called directly via --update flag."""
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def mock_uv(self):
|
||||
"""Patch shutil.which and os.path.isfile so uv is always 'found'."""
|
||||
with patch("shutil.which", return_value="/usr/local/bin/uv"), patch(
|
||||
"os.path.isfile", return_value=True
|
||||
):
|
||||
yield
|
||||
|
||||
def test_run_upgrade_success(self, hc_module, capsys):
|
||||
git_root_proc = MagicMock()
|
||||
git_root_proc.returncode = 0
|
||||
@@ -263,6 +275,20 @@ class TestRunUpgrade:
|
||||
output = capsys.readouterr().out
|
||||
assert "Run manually" in output
|
||||
|
||||
def test_run_upgrade_uv_not_found(self, hc_module, capsys):
|
||||
git_root_proc = MagicMock()
|
||||
git_root_proc.returncode = 0
|
||||
git_root_proc.stdout = "/fake/repo\n"
|
||||
|
||||
with patch("subprocess.run", return_value=git_root_proc), patch(
|
||||
"shutil.which", return_value=None
|
||||
), patch("os.path.isfile", return_value=False), pytest.raises(SystemExit) as exc:
|
||||
hc_module._run_upgrade()
|
||||
|
||||
assert exc.value.code == 1
|
||||
output = capsys.readouterr().out
|
||||
assert "uv binary" in output
|
||||
|
||||
def test_upgrade_prompt_ctrl_c_continues(self, hc_module, capsys):
|
||||
mock_resp = MagicMock()
|
||||
mock_resp.json.return_value = {"tag_name": "v99.0.0"}
|
||||
|
||||
Reference in New Issue
Block a user