Sync a declarative package list with the pacman package manager
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

3.0 KiB

Context

Current implementation in pkg/pacman/pacman.go spawns shell processes for pacman queries:

  1. ValidatePackage: Calls pacman -Qip then pacman -Sip (2 processes per package) to check if package exists in sync databases
  2. MarkExplicit: Calls pacman -D --explicit <pkg> individually per package (N processes for N packages)
  3. AUR: Called individually per package not found in pacman databases

Performance issues scale with package count. No caching of package queries across calls.

Goals / Non-Goals

Goals:

  • Use Jguer/dyalpm library to query pacman databases without spawning processes
  • Add in-memory cache for ALL package query results (pacman + AUR), valid for entire job duration
  • Batch pacman -D --explicit calls to single process for multiple packages
  • Batch AUR HTTP queries to single request for all packages not found in pacman

Non-Goals:

  • Refactor AUR handling (already uses HTTP API - will batch it)
  • Add persistent cache (only job-duration in-memory)
  • Change other pacman operations (sync, cleanup)

Decisions

  1. dyalpm over go-alpm: dyalpm uses purego (no cgo), cleaner cross-compilation

    • Alternative: go-alpm (cgo-based) - rejected for compilation complexity
  2. Unified cache in Pac struct: Single cache map replaces separate aurCache

    • Alternative: keep separate caches - rejected, unnecessary complexity
    • Cache key: package name, value: PackageInfo struct
  3. Batch MarkExplicit: Accept []string packages, pass all to single pacman -D --explicit call

    • Note: pacman -D accepts multiple packages in single call
  4. Batch query strategy:

    • Query all packages against dyalpm local DB → returns found[]
    • Query not-found against dyalpm sync DBs → returns found[]
    • Query remaining not-found against AUR HTTP (single batched request)
    • Current: pacman -Qip → pacman -Sip → AUR (per-package)
    • New: Batch dyalpm local → Batch dyalpm sync → Batch AUR
  5. Fallback for dyalpm unavailable: If dyalpm init fails, fall back to:

    • pacman -Qip for all packages (single process, capture all)
    • pacman -Sip for remaining (single process, capture all)
    • AUR HTTP batch for remaining (already batched)

Risks / Trade-offs

  • Risk: dyalpm requires libalpm.so.15 on system

    • Mitigation: Check at runtime, fallback to process spawn if missing
  • Risk: Cache invalidation edge cases (e.g., package installed during job)

    • Mitigation: Acceptable for declpac use case; user runs sync after config changes
  • Risk: AUR API batch size limits

    • Mitigation: Chunk large batches if AUR has limits (TBD in implementation)

Migration Plan

  1. Add dyalpm dependency to go.mod
  2. Refactor Pac struct: replace aurCache with unified pkgCache map
  3. Change ValidatePackage to ValidatePackages (slice input, batch processing)
  4. Update MarkExplicit to accept slice
  5. Batch AUR HTTP calls in ensureAURCache
  6. Update call sites in Sync(), categorizePackages, DryRun()
  7. Test with existing test suite