Tai Groot 2685dd945c feat: add dnf and rpm package manager implementations
Implements the dnf sub-package with Manager, VersionQuerier, Holder,
Cleaner, FileOwner, RepoManager, KeyManager, Grouper, and NameNormalizer
interfaces.

Implements the rpm sub-package with Manager, FileOwner, and
NameNormalizer interfaces.

Both follow the existing pattern: exported methods on struct delegate to
unexported functions, _linux.go for real implementations, _other.go with
build-tag stubs, embedded snack.Locker for mutating operations, and
compile-time interface checks.

Includes parser tests for all output formats.
2026-02-25 22:30:16 +00:00
2026-02-25 20:01:51 +00:00
2026-02-25 20:01:51 +00:00
2026-02-25 20:01:51 +00:00
2026-02-25 20:01:51 +00:00
2026-02-25 20:01:51 +00:00
2026-02-25 20:01:51 +00:00
2026-02-25 20:01:51 +00:00
2026-02-25 20:01:51 +00:00

snack 🍿

Idiomatic Go wrappers for system package managers.

License 0BSD GoDoc

snack provides thin, context-aware Go bindings for system package managers. Think taigrr/systemctl but for package management.

Part of the grlx ecosystem.

Supported Package Managers

Package Manager Platform Status
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 🚧

Install

go get github.com/gogrlx/snack

Usage

package main

import (
    "context"
    "fmt"
    "log"

    "github.com/gogrlx/snack"
    "github.com/gogrlx/snack/apt"
)

func main() {
    ctx := context.Background()
    mgr := apt.New()

    // Install a package
    err := mgr.Install(ctx, []string{"nginx"}, snack.WithSudo(), snack.WithAssumeYes())
    if err != nil {
        log.Fatal(err)
    }

    // Check if installed
    installed, err := mgr.IsInstalled(ctx, "nginx")
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println("nginx installed:", installed)
}

Auto-detection

import "github.com/gogrlx/snack/detect"

mgr, err := detect.Default()
if err != nil {
    log.Fatal(err)
}
fmt.Println("Detected:", mgr.Name())

Interfaces

snack uses a layered interface design. Every provider implements Manager (the base). Extended capabilities are optional β€” use type assertions to check support:

// Base β€” every provider
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

Check capabilities at runtime:

caps := snack.GetCapabilities(mgr)
if caps.Hold {
    mgr.(snack.Holder).Hold(ctx, []string{"nginx"})
}

Design

  • Thin CLI wrappers β€” each sub-package wraps a package manager's CLI tools. No FFI, no library bindings.
  • Common interface β€” all managers implement snack.Manager, making them interchangeable.
  • Capability interfaces β€” extended features via type assertion, so providers aren't forced to stub unsupported operations.
  • Per-provider mutex β€” each provider serializes mutating operations independently; apt + snap can run in parallel.
  • Context-aware β€” all operations accept context.Context for cancellation and timeouts.
  • 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:

snack install nginx
snack remove nginx
snack search redis
snack list
snack upgrade

License

0BSD β€” see LICENSE.

Description
No description provided
Readme 0BSD 492 KiB
Languages
Go 99.8%
Shell 0.2%