140 lines
4.2 KiB
Go
140 lines
4.2 KiB
Go
package dnf
|
|
|
|
import (
|
|
"fmt"
|
|
"regexp"
|
|
"strings"
|
|
|
|
"git.andrewnw.xyz/CyberShell/backy/pkg/pkgman/pkgcommon"
|
|
)
|
|
|
|
// DnfManager implements PackageManager for systems using YUM.
|
|
type DnfManager struct {
|
|
useAuth bool // Whether to use an authentication command
|
|
authCommand string // The authentication command, e.g., "sudo"
|
|
}
|
|
|
|
// DefaultAuthCommand is the default command used for authentication.
|
|
const DefaultAuthCommand = "sudo"
|
|
|
|
// NewDnfManager creates a new DnfManager with default settings.
|
|
func NewDnfManager() *DnfManager {
|
|
return &DnfManager{
|
|
useAuth: true,
|
|
authCommand: DefaultAuthCommand,
|
|
}
|
|
}
|
|
|
|
// Configure applies functional options to customize the package manager.
|
|
func (y *DnfManager) Configure(options ...pkgcommon.PackageManagerOption) {
|
|
for _, opt := range options {
|
|
opt(y)
|
|
}
|
|
}
|
|
|
|
// Install returns the command and arguments for installing a package.
|
|
func (y *DnfManager) Install(pkg, version string, args []string) (string, []string) {
|
|
baseCmd := y.prependAuthCommand("dnf")
|
|
baseArgs := []string{"install", "-y"}
|
|
if version != "" {
|
|
baseArgs = append(baseArgs, fmt.Sprintf("%s-%s", pkg, version))
|
|
} else {
|
|
baseArgs = append(baseArgs, pkg)
|
|
}
|
|
if args != nil {
|
|
baseArgs = append(baseArgs, args...)
|
|
}
|
|
return baseCmd, baseArgs
|
|
}
|
|
|
|
// Remove returns the command and arguments for removing a package.
|
|
func (y *DnfManager) Remove(pkg string, args []string) (string, []string) {
|
|
baseCmd := y.prependAuthCommand("dnf")
|
|
baseArgs := []string{"remove", "-y", pkg}
|
|
if args != nil {
|
|
baseArgs = append(baseArgs, args...)
|
|
}
|
|
return baseCmd, baseArgs
|
|
}
|
|
|
|
// Upgrade returns the command and arguments for upgrading a specific package.
|
|
func (y *DnfManager) Upgrade(pkg, version string) (string, []string) {
|
|
baseCmd := y.prependAuthCommand("dnf")
|
|
baseArgs := []string{"update", "-y"}
|
|
if version != "" {
|
|
baseArgs = append(baseArgs, fmt.Sprintf("%s-%s", pkg, version))
|
|
} else {
|
|
baseArgs = append(baseArgs, pkg)
|
|
}
|
|
return baseCmd, baseArgs
|
|
}
|
|
|
|
// UpgradeAll returns the command and arguments for upgrading all packages.
|
|
func (y *DnfManager) UpgradeAll() (string, []string) {
|
|
baseCmd := y.prependAuthCommand("dnf")
|
|
baseArgs := []string{"update", "-y"}
|
|
return baseCmd, baseArgs
|
|
}
|
|
|
|
// CheckVersion returns the command and arguments for checking the info of a specific package.
|
|
func (d *DnfManager) CheckVersion(pkg, version string) (string, []string) {
|
|
baseCmd := d.prependAuthCommand("dnf")
|
|
baseArgs := []string{"info", pkg}
|
|
|
|
return baseCmd, baseArgs
|
|
}
|
|
|
|
// Parse parses the dnf info output to extract Installed and Candidate versions.
|
|
func (d DnfManager) Parse(output string) (*pkgcommon.PackageVersion, error) {
|
|
|
|
// Check for error message in the output
|
|
if strings.Contains(output, "No matching packages to list") {
|
|
return nil, fmt.Errorf("error: package not listed")
|
|
}
|
|
|
|
// Define regular expressions to capture installed and available versions
|
|
reInstalled := regexp.MustCompile(`(?m)^Installed packages\s*Name\s*:\s*\S+\s*Epoch\s*:\s*\S+\s*Version\s*:\s*([^\s]+)\s*Release\s*:\s*([^\s]+)`)
|
|
reAvailable := regexp.MustCompile(`(?m)^Available packages\s*Name\s*:\s*\S+\s*Epoch\s*:\s*\S+\s*Version\s*:\s*([^\s]+)\s*Release\s*:\s*([^\s]+)`)
|
|
|
|
installedMatch := reInstalled.FindStringSubmatch(output)
|
|
candidateMatch := reAvailable.FindStringSubmatch(output)
|
|
|
|
installedVersion := ""
|
|
candidateVersion := ""
|
|
|
|
if len(installedMatch) >= 3 {
|
|
installedVersion = fmt.Sprintf("%s-%s", installedMatch[1], installedMatch[2])
|
|
}
|
|
|
|
if len(candidateMatch) >= 3 {
|
|
candidateVersion = fmt.Sprintf("%s-%s", candidateMatch[1], candidateMatch[2])
|
|
}
|
|
|
|
if installedVersion == "" && candidateVersion == "" {
|
|
return nil, fmt.Errorf("failed to parse versions from dnf output")
|
|
}
|
|
|
|
return &pkgcommon.PackageVersion{
|
|
Installed: installedVersion,
|
|
Candidate: candidateVersion,
|
|
}, nil
|
|
}
|
|
|
|
// prependAuthCommand prepends the authentication command if UseAuth is true.
|
|
func (y *DnfManager) prependAuthCommand(baseCmd string) string {
|
|
if y.useAuth {
|
|
return y.authCommand + " " + baseCmd
|
|
}
|
|
return baseCmd
|
|
}
|
|
|
|
// SetUseAuth enables or disables authentication.
|
|
func (y *DnfManager) SetUseAuth(useAuth bool) {
|
|
y.useAuth = useAuth
|
|
}
|
|
|
|
// SetAuthCommand sets the authentication command.
|
|
func (y *DnfManager) SetAuthCommand(authCommand string) {
|
|
y.authCommand = authCommand
|
|
}
|