fix(install): delay PATH cleanup until after verified install

Do not remove pipx or other strix copies before checksum and
provenance succeed, so a failed verify cannot leave the user
with no working binary (#1267).
This commit is contained in:
mohammad junayd 2026-09-14 18:09:49 +04:00
parent dbb0a58466
commit a91b390b44
2 changed files with 38 additions and 2 deletions

View file

@ -105,6 +105,9 @@ print_message() {
echo -e "${color}${message}${NC}"
}
# Remove other copies of strix from PATH (pipx, leftover binaries) only after
# a verified install has been written to INSTALL_DIR. Calling this earlier
# would leave the user with no working Strix if checksum/provenance then fail.
check_existing_installation() {
local found_paths=()
while IFS= read -r -d '' path; do
@ -257,8 +260,6 @@ verify_provenance() {
}
check_version() {
check_existing_installation
if [[ -x "$INSTALL_DIR/strix" ]]; then
installed_version=$("$INSTALL_DIR/strix" --version 2>/dev/null | awk '{print $2}' || echo "")
if [[ "$installed_version" == "$specific_version" ]]; then
@ -332,6 +333,7 @@ download_and_install() {
cleanup_install_temps
echo -e "${GREEN}✓ Strix installed to $INSTALL_DIR${NC}"
check_existing_installation
}
check_docker() {

View file

@ -235,6 +235,40 @@ def test_installer_rejects_unsupported_architecture(tmp_path: Path) -> None:
assert not (home_path / ".strix").exists()
def test_installer_leaves_external_strix_on_checksum_failure(tmp_path: Path) -> None:
repository_root = Path(__file__).resolve().parents[1]
archive_path = _create_release_archive(tmp_path)
mock_bin = _create_mock_commands(tmp_path, machine="aarch64")
environment, home_path, _curl_log_path = _create_installer_environment(
tmp_path,
archive_path,
mock_bin,
)
environment["STRIX_TEST_BAD_CHECKSUM"] = "1"
other_bin = tmp_path / "other-bin"
other_bin.mkdir()
external = other_bin / "strix"
_write_executable(external, "#!/bin/sh\nprintf 'strix 1.0.0\\n'\n")
environment["PATH"] = f"{other_bin}:{environment['PATH']}"
before = external.read_bytes()
result = _run_installer(repository_root, environment)
assert result.returncode != 0
assert "Checksum mismatch" in result.stdout
assert external.exists()
assert external.read_bytes() == before
assert not (home_path / ".strix/bin/strix").exists()
installed_result = subprocess.run( # noqa: S603
[str(external), "--version"],
capture_output=True,
text=True,
check=True,
)
assert installed_result.stdout.strip() == "strix 1.0.0"
def test_installer_leaves_existing_install_on_checksum_failure(tmp_path: Path) -> None:
repository_root = Path(__file__).resolve().parents[1]
archive_path = _create_release_archive(tmp_path)