mirror of
https://github.com/gogrlx/snack.git
synced 2026-04-02 05:08:42 -07:00
feat: add Target type for per-package version/repo/source constraints
Breaking change to Manager interface: Install/Remove/Purge now accept []Target instead of []string. Target supports Version pinning, FromRepo constraints, and Source paths — matching SaltStack's pkgs list semantics. Also adds WithRefresh, WithFromRepo, WithReinstall options.
This commit is contained in:
45
snack.go
45
snack.go
@@ -7,16 +7,55 @@ package snack
|
|||||||
|
|
||||||
import "context"
|
import "context"
|
||||||
|
|
||||||
|
// Target represents a package to install, remove, or otherwise act on.
|
||||||
|
// At minimum, Name must be set. Version and other fields constrain the action.
|
||||||
|
//
|
||||||
|
// Modeled after SaltStack's pkgs list, which accepts both plain names
|
||||||
|
// and name:version mappings:
|
||||||
|
//
|
||||||
|
// pkgs:
|
||||||
|
// - nginx
|
||||||
|
// - redis: ">=7.0"
|
||||||
|
// - curl: "8.5.0-1"
|
||||||
|
type Target struct {
|
||||||
|
// Name is the package name (required).
|
||||||
|
Name string
|
||||||
|
|
||||||
|
// Version pins a specific version. If empty, the latest is used.
|
||||||
|
// Comparison operators are supported where the backend allows them
|
||||||
|
// (e.g. ">=1.2.3", "<2.0", "1.2.3-4").
|
||||||
|
Version string
|
||||||
|
|
||||||
|
// FromRepo constrains the install to a specific repository
|
||||||
|
// (e.g. "unstable", "community", "epel").
|
||||||
|
FromRepo string
|
||||||
|
|
||||||
|
// Source is a local file path or URL for package files
|
||||||
|
// (e.g. .deb, .rpm, .pkg.tar.zst). When set, Name is used only
|
||||||
|
// for display/logging.
|
||||||
|
Source string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Targets is a convenience constructor for a slice of [Target] from
|
||||||
|
// plain package names (no version constraint).
|
||||||
|
func Targets(names ...string) []Target {
|
||||||
|
targets := make([]Target, len(names))
|
||||||
|
for i, name := range names {
|
||||||
|
targets[i] = Target{Name: name}
|
||||||
|
}
|
||||||
|
return targets
|
||||||
|
}
|
||||||
|
|
||||||
// Manager is the common interface implemented by all package manager wrappers.
|
// Manager is the common interface implemented by all package manager wrappers.
|
||||||
type Manager interface {
|
type Manager interface {
|
||||||
// Install one or more packages.
|
// Install one or more packages.
|
||||||
Install(ctx context.Context, pkgs []string, opts ...Option) error
|
Install(ctx context.Context, pkgs []Target, opts ...Option) error
|
||||||
|
|
||||||
// Remove one or more packages.
|
// Remove one or more packages.
|
||||||
Remove(ctx context.Context, pkgs []string, opts ...Option) error
|
Remove(ctx context.Context, pkgs []Target, opts ...Option) error
|
||||||
|
|
||||||
// Purge one or more packages (remove including config files).
|
// Purge one or more packages (remove including config files).
|
||||||
Purge(ctx context.Context, pkgs []string, opts ...Option) error
|
Purge(ctx context.Context, pkgs []Target, opts ...Option) error
|
||||||
|
|
||||||
// Upgrade all installed packages to their latest versions.
|
// Upgrade all installed packages to their latest versions.
|
||||||
Upgrade(ctx context.Context, opts ...Option) error
|
Upgrade(ctx context.Context, opts ...Option) error
|
||||||
|
|||||||
20
types.go
20
types.go
@@ -17,6 +17,9 @@ type Options struct {
|
|||||||
DryRun bool
|
DryRun bool
|
||||||
Root string // alternate root filesystem
|
Root string // alternate root filesystem
|
||||||
Verbose bool
|
Verbose bool
|
||||||
|
Refresh bool // refresh package index before operation
|
||||||
|
FromRepo string // constrain operation to a specific repository
|
||||||
|
Reinstall bool // reinstall already-installed packages
|
||||||
}
|
}
|
||||||
|
|
||||||
// Option is a functional option for package manager operations.
|
// Option is a functional option for package manager operations.
|
||||||
@@ -47,6 +50,23 @@ func WithVerbose() Option {
|
|||||||
return func(o *Options) { o.Verbose = true }
|
return func(o *Options) { o.Verbose = true }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithRefresh refreshes the package database before the operation.
|
||||||
|
// Equivalent to pacman -Sy, apt-get update, apk update, etc.
|
||||||
|
func WithRefresh() Option {
|
||||||
|
return func(o *Options) { o.Refresh = true }
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithFromRepo constrains the operation to a specific repository.
|
||||||
|
// e.g. "unstable" for apt, "community" for pacman.
|
||||||
|
func WithFromRepo(repo string) Option {
|
||||||
|
return func(o *Options) { o.FromRepo = repo }
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithReinstall forces reinstallation of already-installed packages.
|
||||||
|
func WithReinstall() Option {
|
||||||
|
return func(o *Options) { o.Reinstall = true }
|
||||||
|
}
|
||||||
|
|
||||||
// ApplyOptions processes functional options into an Options struct.
|
// ApplyOptions processes functional options into an Options struct.
|
||||||
func ApplyOptions(opts ...Option) Options {
|
func ApplyOptions(opts ...Option) Options {
|
||||||
var o Options
|
var o Options
|
||||||
|
|||||||
Reference in New Issue
Block a user