Files
pkgmgr/src/pkgmgr/actions/install/installers/nix/profile/matcher.py
Kevin Veen-Birkenbach 06a6a77a48
Some checks failed
Mark stable commit / test-unit (push) Has been cancelled
Mark stable commit / test-integration (push) Has been cancelled
Mark stable commit / test-env-virtual (push) Has been cancelled
Mark stable commit / test-env-nix (push) Has been cancelled
Mark stable commit / test-e2e (push) Has been cancelled
Mark stable commit / test-virgin-user (push) Has been cancelled
Mark stable commit / test-virgin-root (push) Has been cancelled
Mark stable commit / linter-shell (push) Has been cancelled
Mark stable commit / linter-python (push) Has been cancelled
Mark stable commit / mark-stable (push) Has been cancelled
*fix(nix): resolve nix profile conflicts without numeric indices and fix update pkgmgr system test*
* Switch conflict handling from index-based removal to token-based removal (*nix profile remove <name>*) for newer nix versions
* Add robust parsing of *nix profile list --json* with normalization and heuristics for output/name matching
* Detect at runtime whether numeric profile indices are supported and fall back automatically when they are not
* Ensure *pkgmgr* / *package-manager* flake outputs are correctly identified and cleaned up during reinstall
* Fix failing E2E test *test_update_pkgmgr_shallow_pkgmgr_with_system* by reliably removing conflicting profile entries before reinstall

https://chatgpt.com/share/693efae5-b8bc-800f-94e3-28c93b74ed7b
2025-12-14 18:58:29 +01:00

63 lines
1.5 KiB
Python

from __future__ import annotations
from typing import List
from .models import NixProfileEntry
def entry_matches_output(entry: NixProfileEntry, output: str) -> bool:
"""
Heuristic matcher: output is typically a flake output name (e.g. "pkgmgr"),
and we match against name/attrPath patterns.
"""
out = (output or "").strip()
if not out:
return False
candidates = [entry.name, entry.attr_path]
for c in candidates:
c = (c or "").strip()
if not c:
continue
# Direct match
if c == out:
return True
# AttrPath contains "#<output>"
if f"#{out}" in c:
return True
# AttrPath ends with ".<output>"
if c.endswith(f".{out}"):
return True
# Name pattern "<output>-<n>" (common, e.g. pkgmgr-1)
if c.startswith(f"{out}-"):
return True
# Historical special case: repo is "package-manager" but output is "pkgmgr"
if out == "pkgmgr" and c.startswith("package-manager-"):
return True
return False
def entry_matches_store_path(entry: NixProfileEntry, store_path: str) -> bool:
needle = (store_path or "").strip()
if not needle:
return False
return any((p or "") == needle for p in entry.store_paths)
def stable_unique_ints(values: List[int]) -> List[int]:
seen: set[int] = set()
uniq: List[int] = []
for v in values:
if v in seen:
continue
uniq.append(v)
seen.add(v)
return uniq