A Go wrapper for the Arch Linux Package Manager (ALPM) library using purego.
- Dynamic FFI: Calls libalpm through purego
- Eager Symbol Resolution: Resolves the libalpm 16 bindings on first use
- Typed Interfaces: Go wrappers for supported ALPM operations
- Maintainable Structure: Well-organized codebase with clear separation of concerns
- Error Handling: Go errors with access to libalpm error details
- Go 1.26 or later
- libalpm.so.16
- Linux system with ALPM installed
go get github.com/Hayao0819/dyalpmpackage main
import (
"fmt"
"log"
alpm "github.com/Hayao0819/dyalpm"
)
func main() {
handle, err := alpm.Initialize("/", "/var/lib/pacman")
if err != nil {
log.Fatal(err)
}
defer func() {
if err := handle.Release(); err != nil {
log.Printf("release ALPM handle: %v", err)
}
}()
localDB, err := handle.LocalDB()
if err != nil {
log.Fatal(err)
}
pkg := localDB.Pkg("pacman")
if pkg == nil {
log.Fatal("package pacman not found")
}
fmt.Printf("Package: %s\n", pkg.Name())
fmt.Printf("Version: %s\n", pkg.Version())
fmt.Printf("Description: %s\n", pkg.Description())
}syncDBs, err := handle.SyncDBs()
if err != nil {
log.Fatal(err)
}
for _, db := range syncDBs {
fmt.Printf("%s\n", db.Name())
}trans := alpm.NewTransaction(handle)
err := trans.Init(0)
if err != nil {
log.Fatal(err)
}
defer func() {
if err := trans.Release(); err != nil {
log.Printf("release transaction: %v", err)
}
}()
syncDB, err := handle.SyncDBByName("core")
if err != nil {
log.Fatal(err)
}
pkg := syncDB.Pkg("vim")
if pkg == nil {
log.Fatal("package vim not found")
}
err = trans.AddPkg(pkg)
if err != nil {
log.Fatal(err)
}
missing, err := trans.Prepare()
if len(missing) > 0 {
fmt.Println("Missing dependencies:")
for _, dep := range missing {
fmt.Printf(" %s requires %s\n", dep.GetTarget(), dep.GetDepend().GetName())
}
}
if err != nil {
log.Fatal(err)
}
conflicts, err := trans.Commit()
if len(conflicts) > 0 {
fmt.Println("File conflicts detected!")
}
if err != nil {
log.Fatal(err)
}Prepare and Commit return copied diagnostics with the error. Use
errors.As to obtain *alpm.TransactionError and inspect architecture,
dependency, package conflict, file conflict, and invalid package details.
On first use, dyalpm opens the exact libalpm.so.16 SONAME, verifies that
alpm_version reports ABI major 16, and eagerly resolves its bindings. It does
not fall back to an unversioned libalpm.so. A failed load is retried by the
next operation.
libalpm errors are exposed by github.com/Hayao0819/dyalpm/errors:
import (
stderrors "errors"
alpmerrors "github.com/Hayao0819/dyalpm/errors"
)
if errno := handle.Errno(); errno != alpmerrors.ErrOK {
fmt.Printf("Error: %s\n", handle.StrError(errno))
}
if stderrors.Is(err, alpmerrors.ErrPkgNotFound) {
fmt.Println("Package not found")
}
var alpmErr *alpmerrors.ALPMError
if stderrors.As(err, &alpmErr) {
fmt.Printf("libalpm error %d: %s\n", alpmErr.Errno, alpmErr)
}