Files
snack/README.md
Tai Groot ac15ab5a49 feat(winget): add integration tests, CI, and README updates
- Add winget_integration_test.go for Windows integration testing
- Add Windows CI job (windows-latest) for unit + detect tests
- Add cross-compile CI matrix (windows, darwin, freebsd, openbsd)
- Update README with winget in supported managers and capability matrix
- Include Windows coverage in codecov upload
2026-03-06 03:40:13 +00:00

5.1 KiB

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 Linux
snap snapd Linux
brew Homebrew macOS/Linux
pkg pkg(8) FreeBSD
ports ports/packages OpenBSD
winget Windows Package Manager Windows
detect Auto-detection All

Capability Matrix

Provider VersionQuery Hold Clean FileOwner RepoMgmt KeyMgmt Groups NameNorm DryRun PkgUpgrade
apt -
pacman - - -
aur - - - - - -
apk - - - -
dnf - -
flatpak - - - -
snap - - - - - - -
brew - - - - -
pkg - -
ports - - - - -
winget - - - - - -

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, snack.Targets("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)
  7. winget (Windows)

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.