From 24caacdd1db853578beb049e8082dbd8bac40d62 Mon Sep 17 00:00:00 2001 From: Nick Sweeting Date: Thu, 11 Jun 2026 01:16:02 -0700 Subject: [PATCH] Invalidate stale binary paths after lib moves --- archivebox/machine/models.py | 14 +++++++++++++- archivebox/tests/test_machine_models.py | 18 +++++++++--------- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/archivebox/machine/models.py b/archivebox/machine/models.py index fa82ca7e..f35beb56 100755 --- a/archivebox/machine/models.py +++ b/archivebox/machine/models.py @@ -588,7 +588,19 @@ class Binary(ModelWithHealthStats, ModelWithStateMachine): @property def is_valid(self) -> bool: """A binary is valid if it has a resolved path and is marked installed.""" - return bool(self.abspath) and self.status == self.StatusChoices.INSTALLED + if not self.abspath or self.status != self.StatusChoices.INSTALLED: + return False + try: + abspath = Path(self.abspath).expanduser().resolve(strict=False) + if not abspath.exists(): + return False + if self.binprovider not in {"", "env", "apt", "brew"}: + from archivebox.config.common import get_config + + abspath.relative_to(get_config(include_machine=False).LIB_DIR) + except (OSError, ValueError): + return False + return True @cached_property def binary_info(self) -> dict: diff --git a/archivebox/tests/test_machine_models.py b/archivebox/tests/test_machine_models.py index 9a8c24d7..19e6e0d5 100644 --- a/archivebox/tests/test_machine_models.py +++ b/archivebox/tests/test_machine_models.py @@ -337,9 +337,9 @@ class TestBinaryModel: """Binary.is_valid should be True for installed binaries with a resolved path.""" binary = Binary.objects.create( machine=self.machine, - name="wget", - abspath="/usr/bin/wget", - version="1.21", + name="python", + abspath=sys.executable, + version=f"{sys.version_info.major}.{sys.version_info.minor}", status=Binary.StatusChoices.INSTALLED, ) @@ -348,21 +348,21 @@ class TestBinaryModel: def test_binary_manager_get_valid_binary(self): """BinaryManager.get_valid_binary() should find valid binaries.""" # Create invalid binary (no abspath) - Binary.objects.create(machine=self.machine, name="wget") + Binary.objects.create(machine=self.machine, name="python") # Create valid binary Binary.objects.create( machine=self.machine, - name="wget", - abspath="/usr/bin/wget", - version="1.21", + name="python", + abspath=sys.executable, + version=f"{sys.version_info.major}.{sys.version_info.minor}", status=Binary.StatusChoices.INSTALLED, ) - result = cast(BinaryManager, Binary.objects).get_valid_binary("wget") + result = cast(BinaryManager, Binary.objects).get_valid_binary("python") assert result is not None - assert result.abspath == "/usr/bin/wget" + assert result.abspath == sys.executable def test_binary_update_and_requeue(self): """Binary.update_and_requeue() should update fields and save."""