Init commit

This commit is contained in:
e 2025-01-21 16:59:43 -05:00
commit 981dc3d2ff
7 changed files with 869 additions and 0 deletions

13
.gitignore vendored Normal file
View File

@ -0,0 +1,13 @@
# Binaries
upm
*.exe
# IDE specific files
.idea/
.vscode/
*.swp
*.swo
# OS specific files
.DS_Store
Thumbs.db

16
Makefile Normal file
View File

@ -0,0 +1,16 @@
.PHONY: build clean install
build:
go build -o upm
clean:
rm -f upm
install: build
sudo mv upm /usr/local/bin/
test:
go test ./...
deps:
go mod tidy

145
README.md Normal file
View File

@ -0,0 +1,145 @@
# Universal Package Manager (UPM)
A unified command-line interface for managing packages across different Linux distributions. UPM provides a consistent interface for package management operations regardless of the underlying package manager (apt, dnf, pacman, etc.).
## Features
- 🔄 Universal syntax across package managers
- 📦 Support for multiple package managers:
- apt (Debian/Ubuntu)
- dnf/yum (RHEL/Fedora)
- pacman (Arch)
- zypper (openSUSE)
- apk (Alpine)
- xbps (Void Linux)
- emerge (Gentoo)
- 🚀 Support for universal package managers:
- snap
- flatpak
- 🔍 Version-specific package installation
- 📋 Repository management
- 🧹 Cache cleaning
- 🔗 Dependency handling
## Installation
### Prerequisites
- Go 1.22 or newer
- Git
### Building from Source
1. Clone the repository and enter the directory:
git clone https://git.supernets.org/e/managerofmanagers
cd upm
2. Install dependencies:
go mod download
3. Build the binary:
go build -o upm
4. (Optional) Install system-wide:
sudo mv upm /usr/local/bin/
## Usage
### Basic Commands
Install packages:
upm install nginx
upm install nginx@1.18.0 # Install specific version
Remove packages:
upm remove nginx
Search for packages:
upm search nginx
Update package lists:
upm update
Upgrade installed packages:
upm upgrade
List installed packages:
upm list
Show package information:
upm info nginx
### Repository Management
Add a repository:
upm repo add https://repo.example.com
Remove a repository:
upm repo remove example-repo
List repositories:
upm repo list
### Maintenance
Clean package cache:
upm clean
Remove unused dependencies:
upm autoremove
### Dependency Management
Check dependencies:
upm check-deps
Check dependencies for specific package:
upm check-deps nginx
Show package dependencies:
upm show-deps nginx
### Using Universal Package Managers
Install using snap:
upm -u snap install firefox
Install using flatpak:
upm -u flatpak install org.mozilla.firefox
## Project Structure
upm/
├── main.go # Main application entry point
├── pkg_manager/
│ └── pkg_manager.go # Core package manager implementation
├── go.mod
├── go.sum
└── README.md
## Dependencies
Required Go packages:
- github.com/fatih/color - For colorized terminal output
- github.com/briandowns/spinner - For progress indicators
## Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
## License
This project is licensed under the MIT License - see the LICENSE file for details.
## Acknowledgments
- Thanks to all the Linux distribution maintainers for their package managers
- The Go community for the excellent standard library and third-party packages
## Support
If you encounter any issues or have questions, please file an issue on the GitHub repository.

15
go.mod Normal file
View File

@ -0,0 +1,15 @@
module git.supernets.org/e/managerofmanagers
go 1.22
require (
github.com/briandowns/spinner v1.23.0
github.com/fatih/color v1.16.0
)
require (
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
golang.org/x/sys v0.14.0 // indirect
golang.org/x/term v0.1.0 // indirect
)

15
go.sum Normal file
View File

@ -0,0 +1,15 @@
github.com/briandowns/spinner v1.23.0 h1:alDF2guRWqa/FOZZYWjlMIx2L6H0wyewPxo/CH4Pt2A=
github.com/briandowns/spinner v1.23.0/go.mod h1:rPG4gmXeN3wQV/TsAY4w8lPdIM6RX3yqeBQJSrbXjuE=
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q=
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.1.0 h1:g6Z6vPFA9dYBAF7DWcH6sCcOntplXsDKcliusYijMlw=
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=

277
main.go Normal file
View File

@ -0,0 +1,277 @@
package main
import (
"flag"
"fmt"
"os"
"strings"
"time"
"github.com/fatih/color"
"github.com/briandowns/spinner"
"git.supernets.org/e/managerofmanagers/pkg_manager"
)
var (
// Color definitions
success = color.New(color.FgGreen, color.Bold)
warning = color.New(color.FgYellow, color.Bold)
error = color.New(color.FgRed, color.Bold)
info = color.New(color.FgCyan)
header = color.New(color.FgMagenta, color.Bold)
command = color.New(color.FgBlue, color.Bold)
// Command line flags
verbose bool
)
func showSpinner(message string) func() {
s := spinner.New(spinner.CharSets[14], 100*time.Millisecond)
s.Suffix = " " + message
s.Color("cyan")
s.Start()
return func() {
s.Stop()
}
}
func main() {
// Initialize universal package managers
pkg_manager.InitializeUniversalManagers()
if len(os.Args) < 2 {
printUsage()
os.Exit(1)
}
// Check for flags
var universalPM string
flag.StringVar(&universalPM, "u", "", "Use universal package manager (snap/flatpak)")
flag.BoolVar(&verbose, "v", false, "Show verbose output")
flag.Parse()
if universalPM != "" {
if mgr, ok := pkg_manager.GetUniversalManager(universalPM); ok {
handleCommand(&mgr.Manager, os.Args[1:])
return
}
fmt.Fprintf(os.Stderr, "Universal package manager %s not available\n", universalPM)
os.Exit(1)
}
pm, err := pkg_manager.DetectPackageManager()
if err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
os.Exit(1)
}
handleCommand(pm, os.Args[1:])
}
func handleCommand(pm *pkg_manager.Manager, args []string) {
// Set output mode based on verbose flag
if verbose {
pkg_manager.SetOutputMode(pkg_manager.OutputVerbose)
} else {
pkg_manager.SetOutputMode(pkg_manager.OutputQuiet)
}
if len(args) == 0 {
printUsage()
os.Exit(1)
}
command := args[0]
cmdArgs := args[1:]
switch command {
case "install":
if len(cmdArgs) == 0 {
error.Fprintln(os.Stderr, "Error: no packages specified")
os.Exit(1)
}
stop := showSpinner("Installing packages...")
err := pm.Install(cmdArgs...)
stop()
if err != nil {
error.Fprintf(os.Stderr, "Failed to install packages: %v\n", err)
os.Exit(1)
}
success.Printf("✓ Successfully installed: %s\n", strings.Join(cmdArgs, ", "))
case "remove":
if len(cmdArgs) == 0 {
error.Fprintln(os.Stderr, "Error: no packages specified")
os.Exit(1)
}
stop := showSpinner("Removing packages...")
err := pm.Remove(cmdArgs...)
stop()
if err != nil {
error.Fprintf(os.Stderr, "Failed to remove packages: %v\n", err)
os.Exit(1)
}
success.Printf("✓ Successfully removed: %s\n", strings.Join(cmdArgs, ", "))
case "search":
if len(cmdArgs) == 0 {
fmt.Fprintln(os.Stderr, "Error: search term required")
os.Exit(1)
}
if err := pm.Search(strings.Join(cmdArgs, " ")); err != nil {
fmt.Fprintf(os.Stderr, "Search failed: %v\n", err)
os.Exit(1)
}
case "update":
if err := pm.Update(); err != nil {
fmt.Fprintf(os.Stderr, "Failed to update package lists: %v\n", err)
os.Exit(1)
}
case "upgrade":
if err := pm.Upgrade(); err != nil {
fmt.Fprintf(os.Stderr, "Failed to upgrade packages: %v\n", err)
os.Exit(1)
}
case "list":
if err := pm.ListInstalled(); err != nil {
fmt.Fprintf(os.Stderr, "Failed to list packages: %v\n", err)
os.Exit(1)
}
case "info":
if len(cmdArgs) == 0 {
fmt.Fprintln(os.Stderr, "Error: package name required")
os.Exit(1)
}
if err := pm.ShowInfo(cmdArgs[0]); err != nil {
fmt.Fprintf(os.Stderr, "Failed to show package info: %v\n", err)
os.Exit(1)
}
case "repo":
if len(cmdArgs) < 1 {
fmt.Fprintln(os.Stderr, "Error: repo subcommand required (add/remove/list)")
os.Exit(1)
}
switch cmdArgs[0] {
case "add":
if len(cmdArgs) < 2 {
fmt.Fprintln(os.Stderr, "Error: repository URL required")
os.Exit(1)
}
if err := pm.AddRepository(cmdArgs[1]); err != nil {
fmt.Fprintf(os.Stderr, "Failed to add repository: %v\n", err)
os.Exit(1)
}
case "remove":
if len(cmdArgs) < 2 {
fmt.Fprintln(os.Stderr, "Error: repository name required")
os.Exit(1)
}
if err := pm.RemoveRepository(cmdArgs[1]); err != nil {
fmt.Fprintf(os.Stderr, "Failed to remove repository: %v\n", err)
os.Exit(1)
}
case "list":
if err := pm.ListRepositories(); err != nil {
fmt.Fprintf(os.Stderr, "Failed to list repositories: %v\n", err)
os.Exit(1)
}
default:
fmt.Fprintf(os.Stderr, "Unknown repo subcommand: %s\n", cmdArgs[0])
printUsage()
os.Exit(1)
}
case "clean":
if err := pm.CleanCache(); err != nil {
fmt.Fprintf(os.Stderr, "Failed to clean cache: %v\n", err)
os.Exit(1)
}
case "autoremove":
if err := pm.AutoRemove(); err != nil {
fmt.Fprintf(os.Stderr, "Failed to remove unused dependencies: %v\n", err)
os.Exit(1)
}
case "check-deps":
pkg := ""
if len(cmdArgs) > 0 {
pkg = cmdArgs[0]
}
if err := pm.CheckDependencies(pkg); err != nil {
fmt.Fprintf(os.Stderr, "Dependency check failed: %v\n", err)
os.Exit(1)
}
case "show-deps":
if len(cmdArgs) == 0 {
fmt.Fprintln(os.Stderr, "Error: package name required")
os.Exit(1)
}
if err := pm.ShowDependencies(cmdArgs[0]); err != nil {
fmt.Fprintf(os.Stderr, "Failed to show dependencies: %v\n", err)
os.Exit(1)
}
default:
fmt.Fprintf(os.Stderr, "Unknown command: %s\n", command)
printUsage()
os.Exit(1)
}
}
func printUsage() {
header.Println("\n📦 Universal Package Manager")
fmt.Println("\nUsage: upm [-u snap|flatpak] [-v] <command> [arguments]")
info.Println("\nCommands:")
command.Print(" install ")
fmt.Println("<package1[@version]> [package2[@version]...] - Install packages")
command.Print(" remove ")
fmt.Println("<package1> [package2...] - Remove packages")
command.Print(" search ")
fmt.Println("<term> - Search for packages")
command.Print(" update ")
fmt.Println(" - Update package lists")
command.Print(" upgrade ")
fmt.Println(" - Upgrade installed packages")
command.Print(" list ")
fmt.Println(" - List installed packages")
command.Print(" info ")
fmt.Println("<package> - Show package information")
info.Println("\nRepository Management:")
command.Print(" repo add ")
fmt.Println("<url> - Add repository")
command.Print(" repo remove ")
fmt.Println("<name> - Remove repository")
command.Print(" repo list ")
fmt.Println(" - List repositories")
info.Println("\nMaintenance:")
command.Print(" clean ")
fmt.Println(" - Clean package cache")
command.Print(" autoremove ")
fmt.Println(" - Remove unused dependencies")
info.Println("\nDependency Management:")
command.Print(" check-deps ")
fmt.Println("[package] - Check dependencies")
command.Print(" show-deps ")
fmt.Println("<package> - Show package dependencies")
info.Println("\nFlags:")
fmt.Println(" -u string Use universal package manager (snap/flatpak)")
fmt.Println(" -v Show verbose output")
warning.Println("\nExamples:")
fmt.Println(" upm install nginx@1.18.0")
fmt.Println(" upm -u snap install firefox")
fmt.Println(" upm repo add https://repo.example.com")
fmt.Println(" upm show-deps nginx")
fmt.Println()
}

388
pkg_manager/pkg_manager.go Normal file
View File

@ -0,0 +1,388 @@
package pkg_manager
import (
"fmt"
"os"
"os/exec"
"strings"
)
// PackageManager interface defines common operations
type PackageManager interface {
Install(packages ...string) error
Remove(packages ...string) error
Search(term string) error
Update() error
Upgrade() error
ListInstalled() error
ShowInfo(pkg string) error
AddRepository(repo string) error
RemoveRepository(repo string) error
ListRepositories() error
CleanCache() error
AutoRemove() error
CheckDependencies(pkg string) error
ShowDependencies(pkg string) error
}
// Manager represents a concrete package manager
type Manager struct {
command string
installCmd []string
removeCmd []string
searchCmd []string
updateCmd []string
upgradeCmd []string
listCmd []string
infoCmd []string
addRepoCmd []string
removeRepoCmd []string
listRepoCmd []string
cleanCacheCmd []string
autoRemoveCmd []string
checkDependsCmd []string
showDependsCmd []string
needsSudo bool
versionSep string
cacheDir string
}
// UniversalManager represents universal package managers like snap/flatpak
type UniversalManager struct {
Manager
isAvailable bool
}
// PackageVersion represents a package with optional version
type PackageVersion struct {
Name string
Version string
}
var universalManagers = map[string]*UniversalManager{
"snap": {
Manager: Manager{
command: "snap",
installCmd: []string{"install"},
removeCmd: []string{"remove"},
searchCmd: []string{"find"},
updateCmd: []string{"refresh"},
upgradeCmd: []string{"refresh"},
needsSudo: true,
},
},
"flatpak": {
Manager: Manager{
command: "flatpak",
installCmd: []string{"install", "-y"},
removeCmd: []string{"uninstall", "-y"},
searchCmd: []string{"search"},
updateCmd: []string{"update", "-y"},
upgradeCmd: []string{"update", "-y"},
needsSudo: false,
},
},
}
var managers = map[string]Manager{
"apt": {
command: "apt",
installCmd: []string{"install", "-y"},
removeCmd: []string{"remove", "-y"},
searchCmd: []string{"search"},
updateCmd: []string{"update"},
upgradeCmd: []string{"upgrade", "-y"},
listCmd: []string{"list", "--installed"},
infoCmd: []string{"show"},
addRepoCmd: []string{"add-apt-repository", "-y"},
removeRepoCmd: []string{"add-apt-repository", "-r", "-y"},
listRepoCmd: []string{"sources"},
cleanCacheCmd: []string{"clean"},
autoRemoveCmd: []string{"autoremove", "-y"},
checkDependsCmd: []string{"check"},
showDependsCmd: []string{"depends"},
needsSudo: true,
versionSep: "=",
cacheDir: "/var/cache/apt",
},
"dnf": {
command: "dnf",
installCmd: []string{"install", "-y"},
removeCmd: []string{"remove", "-y"},
searchCmd: []string{"search"},
updateCmd: []string{"check-update"},
upgradeCmd: []string{"upgrade", "-y"},
listCmd: []string{"list", "installed"},
infoCmd: []string{"info"},
addRepoCmd: []string{"config-manager", "--add-repo"},
removeRepoCmd: []string{"config-manager", "--disable"},
listRepoCmd: []string{"repolist"},
cleanCacheCmd: []string{"clean", "all"},
autoRemoveCmd: []string{"autoremove", "-y"},
checkDependsCmd: []string{"check-dependencies"},
showDependsCmd: []string{"repoquery", "--requires"},
needsSudo: true,
versionSep: "-",
cacheDir: "/var/cache/dnf",
},
"yum": {
command: "yum",
installCmd: []string{"install", "-y"},
removeCmd: []string{"remove", "-y"},
searchCmd: []string{"search"},
updateCmd: []string{"check-update"},
upgradeCmd: []string{"upgrade", "-y"},
needsSudo: true,
versionSep: "-",
cacheDir: "/var/cache/yum",
},
"pacman": {
command: "pacman",
installCmd: []string{"-S", "--noconfirm"},
removeCmd: []string{"-R", "--noconfirm"},
searchCmd: []string{"-Ss"},
updateCmd: []string{"-Sy"},
upgradeCmd: []string{"-Syu", "--noconfirm"},
needsSudo: true,
versionSep: "=",
cacheDir: "/var/cache/pacman",
},
"zypper": {
command: "zypper",
installCmd: []string{"install", "-y"},
removeCmd: []string{"remove", "-y"},
searchCmd: []string{"search"},
updateCmd: []string{"refresh"},
upgradeCmd: []string{"update", "-y"},
needsSudo: true,
versionSep: "=",
cacheDir: "/var/cache/zypp",
},
"apk": {
command: "apk",
installCmd: []string{"add"},
removeCmd: []string{"del"},
searchCmd: []string{"search"},
updateCmd: []string{"update"},
upgradeCmd: []string{"upgrade"},
needsSudo: true,
versionSep: "=",
cacheDir: "/var/cache/apk",
},
"xbps": {
command: "xbps-install",
installCmd: []string{"-y"},
removeCmd: []string{"-R"},
searchCmd: []string{"-Rs"},
updateCmd: []string{"-S"},
upgradeCmd: []string{"-Su"},
listCmd: []string{"-l"},
infoCmd: []string{"-S"},
addRepoCmd: []string{"-R", "add"},
removeRepoCmd: []string{"-R", "remove"},
listRepoCmd: []string{"-R", "list"},
cleanCacheCmd: []string{"-Op"},
autoRemoveCmd: []string{"-Oo"},
checkDependsCmd: []string{"-C"},
showDependsCmd: []string{"-x"},
needsSudo: true,
versionSep: "-",
cacheDir: "/var/cache/xbps",
},
"emerge": {
command: "emerge",
installCmd: []string{"--ask", "n"},
removeCmd: []string{"--unmerge", "--ask", "n"},
searchCmd: []string{"--search"},
updateCmd: []string{"--sync"},
upgradeCmd: []string{"--update", "--deep", "--ask", "n", "@world"},
listCmd: []string{"--list-sets"},
infoCmd: []string{"--info"},
addRepoCmd: []string{"--repos-conf", "add"},
removeRepoCmd: []string{"--repos-conf", "remove"},
listRepoCmd: []string{"--repos-conf", "list"},
cleanCacheCmd: []string{"--depclean"},
autoRemoveCmd: []string{"--depclean"},
checkDependsCmd: []string{"--depclean", "-p"},
showDependsCmd: []string{"--deps"},
needsSudo: true,
versionSep: "-",
cacheDir: "/var/cache/portage",
},
}
// ParsePackageVersion parses package name and version
func ParsePackageVersion(pkg string) PackageVersion {
parts := strings.Split(pkg, "@")
if len(parts) == 2 {
return PackageVersion{
Name: parts[0],
Version: parts[1],
}
}
return PackageVersion{Name: pkg}
}
// formatPackageWithVersion formats package with version using manager's separator
func (m *Manager) formatPackageWithVersion(pv PackageVersion) string {
if pv.Version == "" {
return pv.Name
}
return fmt.Sprintf("%s%s%s", pv.Name, m.versionSep, pv.Version)
}
// Install packages with version support
func (m *Manager) Install(packages ...string) error {
if len(packages) == 0 {
return fmt.Errorf("no packages specified")
}
formattedPkgs := make([]string, len(packages))
for i, pkg := range packages {
pv := ParsePackageVersion(pkg)
formattedPkgs[i] = m.formatPackageWithVersion(pv)
}
return m.execCommand(m.installCmd, formattedPkgs...)
}
// InitializeUniversalManagers checks which universal package managers are available
func InitializeUniversalManagers() {
for _, mgr := range universalManagers {
_, err := exec.LookPath(mgr.command)
mgr.isAvailable = err == nil
}
}
// GetUniversalManager returns a universal package manager if available
func GetUniversalManager(name string) (*UniversalManager, bool) {
if mgr, exists := universalManagers[name]; exists && mgr.isAvailable {
return mgr, true
}
return nil, false
}
type OutputMode int
const (
OutputQuiet OutputMode = iota
OutputVerbose
)
var outputMode = OutputQuiet
// SetOutputMode sets the output verbosity
func SetOutputMode(mode OutputMode) {
outputMode = mode
}
func (m *Manager) execCommand(baseCmd []string, args ...string) error {
cmdArgs := append(baseCmd, args...)
var cmd *exec.Cmd
if m.needsSudo && os.Geteuid() != 0 {
// Clear the line to prevent spinner interference with sudo prompt
fmt.Print("\r\033[K")
cmdArgs = append([]string{m.command}, cmdArgs...)
cmd = exec.Command("sudo", cmdArgs...)
} else {
cmd = exec.Command(m.command, cmdArgs...)
}
// Always capture output
if outputMode == OutputVerbose {
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
} else {
// Capture but don't display output in quiet mode
cmd.Stdout = nil
cmd.Stderr = nil
}
cmd.Stdin = os.Stdin
return cmd.Run()
}
// Remove packages
func (m *Manager) Remove(packages ...string) error {
if len(packages) == 0 {
return fmt.Errorf("no packages specified")
}
return m.execCommand(m.removeCmd, packages...)
}
// Search for packages
func (m *Manager) Search(term string) error {
if term == "" {
return fmt.Errorf("no search term specified")
}
return m.execCommand(m.searchCmd, term)
}
// Update package lists
func (m *Manager) Update() error {
return m.execCommand(m.updateCmd)
}
// Upgrade installed packages
func (m *Manager) Upgrade() error {
return m.execCommand(m.upgradeCmd)
}
// ListInstalled lists all installed packages
func (m *Manager) ListInstalled() error {
return m.execCommand(m.listCmd)
}
// ShowInfo shows detailed information about a package
func (m *Manager) ShowInfo(pkg string) error {
return m.execCommand(m.infoCmd, pkg)
}
// AddRepository adds a new repository
func (m *Manager) AddRepository(repo string) error {
return m.execCommand(m.addRepoCmd, repo)
}
// RemoveRepository removes a repository
func (m *Manager) RemoveRepository(repo string) error {
return m.execCommand(m.removeRepoCmd, repo)
}
// ListRepositories lists all configured repositories
func (m *Manager) ListRepositories() error {
return m.execCommand(m.listRepoCmd)
}
// CleanCache cleans the package manager cache
func (m *Manager) CleanCache() error {
return m.execCommand(m.cleanCacheCmd)
}
// AutoRemove removes unused dependencies
func (m *Manager) AutoRemove() error {
return m.execCommand(m.autoRemoveCmd)
}
// CheckDependencies checks for dependency issues
func (m *Manager) CheckDependencies(pkg string) error {
if pkg == "" {
return m.execCommand(m.checkDependsCmd)
}
return m.execCommand(m.checkDependsCmd, pkg)
}
// ShowDependencies shows dependencies for a package
func (m *Manager) ShowDependencies(pkg string) error {
return m.execCommand(m.showDependsCmd, pkg)
}
// DetectPackageManager identifies the system's package manager
func DetectPackageManager() (*Manager, error) {
for _, mgr := range managers {
if _, err := exec.LookPath(mgr.command); err == nil {
return &mgr, nil
}
}
return nil, fmt.Errorf("no supported package manager found")
}