Tai Groot b443269594 feat: add integration tests and GitHub Actions CI
Add integration test files for all providers (apt, dpkg, pacman, apk,
dnf, rpm, flatpak, snap, pkg, detect) behind the 'integration' build
tag. Tests exercise real package operations: update, search, info,
install, verify, list, remove, and capability interfaces.

Add GitHub Actions workflow running unit tests on ubuntu-latest and
integration tests on Debian, Ubuntu, Fedora, Alpine, Arch Linux, and
Ubuntu+Flatpak containers/runners.
2026-02-26 01:42:19 +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%