From 85e06ffc44e9faf02d8042eb8c5d3b3d63e6b73c Mon Sep 17 00:00:00 2001 From: Tai Groot Date: Fri, 6 Mar 2026 00:14:27 +0000 Subject: [PATCH] docs: rewrite README with current API, capabilities table, CLI docs - Fix usage examples to use snack.Targets() and snack.Target - Replace construction emoji status with actual extras per provider - Document all interfaces including PackageUpgrader and DryRunner - Add Options section documenting all functional options - Add full CLI command reference with examples - Remove implementation priority (everything is implemented) --- README.md | 132 +++++++++++++++++++++++++++++++++++------------------- 1 file changed, 86 insertions(+), 46 deletions(-) diff --git a/README.md b/README.md index b8a24d5..3ecfef4 100644 --- a/README.md +++ b/README.md @@ -11,20 +11,22 @@ Part of the [grlx](https://github.com/gogrlx/grlx) ecosystem. ## Supported Package Managers -| Package | Manager | Platform | Status | +| Package | Manager | Platform | Extras | |---------|---------|----------|--------| -| `pacman` | pacman | Arch Linux | 🚧 | -| `aur` | AUR (makepkg) | Arch Linux | 🚧 | -| `apk` | apk-tools | Alpine Linux | 🚧 | -| `apt` | APT (apt-get/apt-cache) | Debian/Ubuntu | 🚧 | -| `dpkg` | dpkg | Debian/Ubuntu | 🚧 | -| `dnf` | DNF | Fedora/RHEL | 🚧 | -| `rpm` | RPM | Fedora/RHEL | 🚧 | -| `flatpak` | Flatpak | Cross-distro | 🚧 | -| `snap` | snapd | Cross-distro | 🚧 | -| `pkg` | pkg(8) | FreeBSD | 🚧 | -| `ports` | ports/packages | OpenBSD | 🚧 | -| `detect` | Auto-detection | All | 🚧 | +| `apt` | APT (apt-get/apt-cache) | Debian/Ubuntu | DryRun, FileOwner, Holder, KeyManager, NameNormalizer, RepoManager | +| `dpkg` | dpkg | Debian/Ubuntu | DryRun, FileOwner, NameNormalizer | +| `dnf` | DNF 4/5 | Fedora/RHEL | DryRun, FileOwner, Grouper, Holder, KeyManager, NameNormalizer, RepoManager | +| `rpm` | RPM | Fedora/RHEL | FileOwner, NameNormalizer | +| `pacman` | pacman | Arch Linux | DryRun, FileOwner, Grouper | +| `aur` | AUR (makepkg) | Arch Linux | — | +| `apk` | apk-tools | Alpine Linux | DryRun, FileOwner | +| `flatpak` | Flatpak | Cross-distro | RepoManager | +| `snap` | snapd | Cross-distro | — | +| `pkg` | pkg(8) | FreeBSD | FileOwner | +| `ports` | ports/packages | OpenBSD | FileOwner | +| `detect` | Auto-detection | All | — | + +All providers implement `Manager`, `VersionQuerier`, `Cleaner`, and `PackageUpgrader`. The **Extras** column lists additional capabilities beyond that baseline. ## Install @@ -50,11 +52,12 @@ func main() { ctx := context.Background() mgr := apt.New() - // Install a package - err := mgr.Install(ctx, []string{"nginx"}, snack.WithSudo(), snack.WithAssumeYes()) + // Install packages + result, err := mgr.Install(ctx, snack.Targets("nginx", "curl"), snack.WithSudo(), snack.WithAssumeYes()) if err != nil { log.Fatal(err) } + fmt.Printf("Installed: %d, Unchanged: %d\n", len(result.Installed), len(result.Unchanged)) // Check if installed installed, err := mgr.IsInstalled(ctx, "nginx") @@ -62,6 +65,14 @@ func main() { log.Fatal(err) } fmt.Println("nginx installed:", installed) + + // Upgrade specific packages + if up, ok := mgr.(snack.PackageUpgrader); ok { + _, err := up.UpgradePackages(ctx, snack.Targets("nginx"), snack.WithSudo(), snack.WithAssumeYes()) + if err != nil { + log.Fatal(err) + } + } } ``` @@ -75,6 +86,11 @@ if err != nil { log.Fatal(err) } fmt.Println("Detected:", mgr.Name()) + +// All available managers +for _, m := range detect.All() { + fmt.Println(m.Name()) +} ``` ## Interfaces @@ -83,17 +99,21 @@ snack uses a layered interface design. Every provider implements `Manager` (the ```go // Base — every provider -snack.Manager // Install, Remove, Purge, Upgrade, Update, List, Search, Info, IsInstalled, Version +snack.Manager // Install, Remove, Purge, Upgrade, Update, List, Search, Info, IsInstalled, Version -// Optional capabilities — type-assert to check -snack.VersionQuerier // LatestVersion, ListUpgrades, UpgradeAvailable, VersionCmp -snack.Holder // Hold, Unhold, ListHeld (version pinning) -snack.Cleaner // Autoremove, Clean (orphan/cache cleanup) -snack.FileOwner // FileList, Owner (file-to-package queries) -snack.RepoManager // ListRepos, AddRepo, RemoveRepo -snack.KeyManager // AddKey, RemoveKey, ListKeys (GPG keys) -snack.Grouper // GroupList, GroupInfo, GroupInstall -snack.NameNormalizer // NormalizeName, ParseArch +// Core optional — implemented by all providers +snack.VersionQuerier // LatestVersion, ListUpgrades, UpgradeAvailable, VersionCmp +snack.Cleaner // Autoremove, Clean (orphan/cache cleanup) +snack.PackageUpgrader // UpgradePackages (upgrade specific packages) + +// Provider-specific — type-assert to check +snack.Holder // Hold, Unhold, ListHeld, IsHeld (version pinning) +snack.FileOwner // FileList, Owner (file-to-package queries) +snack.RepoManager // ListRepos, AddRepo, RemoveRepo +snack.KeyManager // AddKey, RemoveKey, ListKeys (GPG keys) +snack.Grouper // GroupList, GroupInfo, GroupInstall, GroupIsInstalled +snack.NameNormalizer // NormalizeName, ParseArch +snack.DryRunner // SupportsDryRun (honors WithDryRun option) ``` Check capabilities at runtime: @@ -103,8 +123,49 @@ caps := snack.GetCapabilities(mgr) if caps.Hold { mgr.(snack.Holder).Hold(ctx, []string{"nginx"}) } +if caps.FileOwnership { + owner, _ := mgr.(snack.FileOwner).Owner(ctx, "/usr/bin/curl") + fmt.Println("Owned by:", owner) +} ``` +## Options + +All mutating operations accept functional options: + +```go +snack.WithSudo() // prepend sudo +snack.WithAssumeYes() // auto-confirm prompts +snack.WithDryRun() // simulate (if DryRunner) +snack.WithVerbose() // verbose output +snack.WithRefresh() // refresh index before operation +snack.WithReinstall() // reinstall even if current +snack.WithRoot("/mnt") // alternate root filesystem +snack.WithFromRepo("sid") // install from specific repository +``` + +## CLI + +A companion CLI is included at `cmd/snack`: + +```bash +snack install nginx curl # install packages +snack remove nginx # remove packages +snack upgrade # upgrade all packages +snack update # refresh package index +snack search redis # search for packages +snack info nginx # show package details +snack list # list installed packages +snack which /usr/bin/curl # find owning package +snack hold nginx # pin package version +snack unhold nginx # unpin package version +snack clean # autoremove + clean cache +snack detect # show detected managers + capabilities +snack version # show version +``` + +Global flags: `--manager `, `--sudo`, `--yes`, `--dry-run` + ## Design - **Thin CLI wrappers** — each sub-package wraps a package manager's CLI tools. No FFI, no library bindings. @@ -115,27 +176,6 @@ if caps.Hold { - **Platform-safe** — build tags ensure packages compile everywhere but only run where appropriate. - **No root assumption** — use `snack.WithSudo()` when elevated privileges are needed. -## Implementation Priority - -1. pacman + AUR (Arch Linux) -2. apk (Alpine Linux) -3. apt + dpkg (Debian/Ubuntu) -4. dnf + rpm (Fedora/RHEL) -5. flatpak + snap (cross-distro) -6. pkg + ports (BSD) - -## CLI - -A companion CLI tool is planned for direct terminal usage: - -```bash -snack install nginx -snack remove nginx -snack search redis -snack list -snack upgrade -``` - ## License 0BSD — see [LICENSE](LICENSE).