diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 94671db..6309a5f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -182,6 +182,20 @@ jobs: PYMANAGER_DEBUG: true shell: powershell + - name: 'Test purge' + run: | + $env:PYTHON_MANAGER_CONFIG = (gi $env:PYTHON_MANAGER_CONFIG).FullName + pymanager uninstall --purge -y + if (Test-Path test_installs) { + dir -r test_installs + } else { + Write-Host "test_installs directory has been deleted" + } + env: + PYTHON_MANAGER_INCLUDE_UNMANAGED: false + PYTHON_MANAGER_CONFIG: .\test-config.json + PYMANAGER_DEBUG: true + - name: 'Offline bundle download and install' run: | pymanager list --online 3 3-32 3-64 3-arm64 diff --git a/ci/release.yml b/ci/release.yml index 01336fe..d2fcbcd 100644 --- a/ci/release.yml +++ b/ci/release.yml @@ -323,6 +323,21 @@ stages: PYTHON_MANAGER_CONFIG: .\test-config.json PYMANAGER_DEBUG: true + - powershell: | + $env:PYTHON_MANAGER_CONFIG = (gi $env:PYTHON_MANAGER_CONFIG).FullName + pymanager uninstall --purge -y + if (Test-Path test_installs) { + dir -r test_installs + } else { + Write-Host "test_installs directory has been deleted" + } + displayName: 'Test purge' + timeoutInMinutes: 5 + env: + PYTHON_MANAGER_INCLUDE_UNMANAGED: false + PYTHON_MANAGER_CONFIG: .\test-config.json + PYMANAGER_DEBUG: true + - powershell: | pymanager list --online 3 3-32 3-64 3-arm64 pymanager install --download .\bundle 3 3-32 3-64 3-arm64 diff --git a/src/manage/installs.py b/src/manage/installs.py index 4b1dfa5..f8150cd 100644 --- a/src/manage/installs.py +++ b/src/manage/installs.py @@ -23,6 +23,14 @@ def _get_installs(install_dir): try: with p.open() as f: j = json.load(f) + except ValueError: + LOGGER.warn( + "Failed to read install at %s. You may have a broken " + "install, which can be cleaned up by deleting the directory.", + d + ) + LOGGER.debug("ERROR", exc_info=True) + continue except FileNotFoundError: continue diff --git a/src/manage/uninstall_command.py b/src/manage/uninstall_command.py index 8fefa6c..28735fd 100644 --- a/src/manage/uninstall_command.py +++ b/src/manage/uninstall_command.py @@ -66,9 +66,7 @@ def _do_purge_global_dir(global_dir, warn_msg, *, hive=None, subkey="Environment if not global_dir.is_dir(): return LOGGER.info("Purging global commands from %s", global_dir) - for f in _iterdir(global_dir): - LOGGER.debug("Purging %s", f) - rmtree(f, after_5s_warning=warn_msg) + rmtree(global_dir, after_5s_warning=warn_msg) def execute(cmd): diff --git a/tests/conftest.py b/tests/conftest.py index c4ec097..a927495 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -152,11 +152,11 @@ def localserver(): class FakeConfig: - def __init__(self, global_dir, installs=[]): - self.global_dir = global_dir - self.root = global_dir.parent if global_dir else None - self.download_dir = self.root / "_cache" if self.root else None - self.start_folder = self.root / "_start" if self.root else None + def __init__(self, root, installs=[]): + self.root = self.install_dir = root + self.global_dir = root / "bin" if root else None + self.download_dir = root / "_cache" if root else None + self.start_folder = root / "_start" if root else None self.pep514_root = REG_TEST_ROOT self.confirm = False self.installs = list(installs) @@ -186,7 +186,7 @@ def ask_yn(self, question): @pytest.fixture def fake_config(tmp_path): - return FakeConfig(tmp_path / "bin") + return FakeConfig(tmp_path) class RegistryFixture: diff --git a/tests/test_uninstall_command.py b/tests/test_uninstall_command.py index a106d61..050a808 100644 --- a/tests/test_uninstall_command.py +++ b/tests/test_uninstall_command.py @@ -16,7 +16,7 @@ def test_purge_global_dir(monkeypatch, registry, tmp_path): UC._do_purge_global_dir(tmp_path, "SLOW WARNING", hive=registry.hive, subkey=registry.root) assert registry.getvalueandkind("", "Path") == ( rf"C:\A;{tmp_path}\X;C:\B;%PTH%;C:\%D%\E", winreg.REG_SZ) - assert not list(tmp_path.iterdir()) + assert not tmp_path.is_dir() or not list(tmp_path.iterdir()) def test_null_purge(fake_config):