- I think it would be better if one for commands only, one for the spec handling core logic so people won't be confused by the core logic inside the commands folder (cleaner I guess) - Regen docs
328 lines
13 KiB
Go
328 lines
13 KiB
Go
package pkginstaller
|
|
|
|
import (
|
|
"context"
|
|
"os/exec"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/versenilvis/iris/spec"
|
|
)
|
|
|
|
func installedPackageGenerator(pm string) spec.GeneratorFunc {
|
|
return func(tokens []string, _ string, _ string) []spec.Suggestion {
|
|
ctx, cancel := context.WithTimeout(context.Background(), 8*time.Second)
|
|
defer cancel()
|
|
|
|
var cmd *exec.Cmd
|
|
switch pm {
|
|
case "pacman", "yay", "paru":
|
|
cmd = exec.CommandContext(ctx, pm, "-Qq")
|
|
case "apt", "apt-get":
|
|
cmd = exec.CommandContext(ctx, "dpkg-query", "-W", "-f=${Package}\n")
|
|
case "dnf", "yum":
|
|
cmd = exec.CommandContext(ctx, "rpm", "-qa", "--qf", "%{NAME}\n")
|
|
case "brew":
|
|
cmd = exec.CommandContext(ctx, "brew", "list")
|
|
default:
|
|
return nil
|
|
}
|
|
|
|
out, err := cmd.Output()
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
|
|
var results []spec.Suggestion
|
|
for line := range strings.SplitSeq(string(out), "\n") {
|
|
line = strings.TrimSpace(line)
|
|
if line == "" {
|
|
continue
|
|
}
|
|
results = append(results, spec.Suggestion{Cmd: line, Desc: "installed"})
|
|
}
|
|
return results
|
|
}
|
|
}
|
|
|
|
func init() {
|
|
// pacman
|
|
spec.Register(&spec.Spec{
|
|
Name: "pacman",
|
|
Description: "Arch package manager",
|
|
Options: []spec.Option{
|
|
{Name: "-S", Description: "install package"},
|
|
{Name: "-Syu", Description: "full system upgrade"},
|
|
{Name: "-Sy", Description: "sync database"},
|
|
{Name: "-Su", Description: "upgrade installed"},
|
|
{Name: "-Ss", Description: "search in repos"},
|
|
{Name: "-Si", Description: "show package info"},
|
|
{Name: "-R", Description: "remove package"},
|
|
{Name: "-Rs", Description: "remove + unused deps"},
|
|
{Name: "-Rns", Description: "remove + deps + configs"},
|
|
{Name: "-Q", Description: "query installed"},
|
|
{Name: "-Qq", Description: "query names only"},
|
|
{Name: "-Qs", Description: "search installed"},
|
|
{Name: "-Qi", Description: "installed package info"},
|
|
{Name: "-Qo", Description: "which package owns file"},
|
|
{Name: "-Ql", Description: "list package files"},
|
|
{Name: "-U", Description: "install local package"},
|
|
{Name: "-D", Description: "set install reason"},
|
|
{Name: "--noconfirm", Description: "skip confirmations"},
|
|
{Name: "--needed", Description: "skip up-to-date"},
|
|
{Name: "--asdeps", Description: "mark as dependency"},
|
|
{Name: "--asexplicit", Description: "mark as explicit"},
|
|
},
|
|
Generator: installedPackageGenerator("pacman"),
|
|
})
|
|
|
|
// yay
|
|
spec.Register(&spec.Spec{
|
|
Name: "yay",
|
|
Description: "AUR helper (pacman wrapper)",
|
|
Options: []spec.Option{
|
|
{Name: "-S", Description: "install package (AUR + repos)"},
|
|
{Name: "-Syu", Description: "full system upgrade + AUR"},
|
|
{Name: "-Ss", Description: "search AUR + repos"},
|
|
{Name: "-Si", Description: "show package info"},
|
|
{Name: "-R", Description: "remove package"},
|
|
{Name: "-Rs", Description: "remove + unused deps"},
|
|
{Name: "-Rns", Description: "remove + deps + configs"},
|
|
{Name: "-Q", Description: "query installed"},
|
|
{Name: "-Qs", Description: "search installed"},
|
|
{Name: "-Qi", Description: "installed package info"},
|
|
{Name: "-Yc", Description: "remove unneeded deps"},
|
|
{Name: "-Y", Description: "yay-specific options"},
|
|
{Name: "--aur", Description: "only AUR results"},
|
|
{Name: "--repo", Description: "only repo results"},
|
|
{Name: "--devel", Description: "update devel packages"},
|
|
{Name: "--noconfirm", Description: "skip confirmations"},
|
|
{Name: "--needed", Description: "skip up-to-date"},
|
|
},
|
|
Generator: installedPackageGenerator("yay"),
|
|
})
|
|
|
|
// paru
|
|
spec.Register(&spec.Spec{
|
|
Name: "paru",
|
|
Description: "AUR helper (feature-rich)",
|
|
Options: []spec.Option{
|
|
{Name: "-S", Description: "install package"},
|
|
{Name: "-Syu", Description: "full upgrade"},
|
|
{Name: "-Ss", Description: "search"},
|
|
{Name: "-R", Description: "remove"},
|
|
{Name: "-Rs", Description: "remove + deps"},
|
|
{Name: "-Q", Description: "query installed"},
|
|
{Name: "--fm", Description: "file manager for PKGBUILDs"},
|
|
{Name: "--noconfirm", Description: "skip confirmations"},
|
|
{Name: "--aur", Description: "AUR only"},
|
|
{Name: "--repo", Description: "repo only"},
|
|
},
|
|
Generator: installedPackageGenerator("paru"),
|
|
})
|
|
|
|
// apt
|
|
spec.Register(&spec.Spec{
|
|
Name: "apt",
|
|
Description: "Debian/Ubuntu package manager",
|
|
Subcommands: []spec.Subcommand{
|
|
{Name: "install", Description: "install packages"},
|
|
{Name: "remove", Description: "remove packages", Generator: installedPackageGenerator("apt")},
|
|
{Name: "purge", Description: "remove + config files", Generator: installedPackageGenerator("apt")},
|
|
{Name: "autoremove", Description: "remove unused deps"},
|
|
{Name: "update", Description: "refresh package lists"},
|
|
{Name: "upgrade", Description: "upgrade installed"},
|
|
{Name: "full-upgrade", Description: "upgrade with auto remove"},
|
|
{Name: "dist-upgrade", Description: "smart upgrade"},
|
|
{Name: "search", Description: "search packages"},
|
|
{Name: "show", Description: "show package info"},
|
|
{Name: "list", Description: "list packages", Options: []spec.Option{
|
|
{Name: "--installed", Description: "installed only"},
|
|
{Name: "--upgradable", Description: "upgradable only"},
|
|
}},
|
|
{Name: "download", Description: "download package (no install)"},
|
|
{Name: "clean", Description: "clear local repo"},
|
|
{Name: "autoclean", Description: "clear old cached packages"},
|
|
{Name: "depends", Description: "show dependencies"},
|
|
{Name: "rdepends", Description: "show reverse dependencies"},
|
|
},
|
|
Options: []spec.Option{
|
|
{Name: "-y", Description: "yes to all"},
|
|
{Name: "--no-install-recommends", Description: "skip recommends"},
|
|
{Name: "--dry-run", Description: "simulate"},
|
|
{Name: "-q", Description: "quiet"},
|
|
{Name: "--fix-broken", Description: "fix broken deps"},
|
|
},
|
|
})
|
|
|
|
// apt-get
|
|
spec.Register(&spec.Spec{
|
|
Name: "apt-get",
|
|
Description: "Debian/Ubuntu package manager (low-level)",
|
|
Subcommands: []spec.Subcommand{
|
|
{Name: "install", Description: "install packages"},
|
|
{Name: "remove", Description: "remove packages", Generator: installedPackageGenerator("apt")},
|
|
{Name: "purge", Description: "remove + configs", Generator: installedPackageGenerator("apt")},
|
|
{Name: "autoremove", Description: "remove unused deps"},
|
|
{Name: "update", Description: "refresh package lists"},
|
|
{Name: "upgrade", Description: "upgrade installed"},
|
|
{Name: "dist-upgrade", Description: "smart upgrade"},
|
|
{Name: "clean", Description: "clean cache"},
|
|
{Name: "autoclean", Description: "clean old packages"},
|
|
{Name: "download", Description: "download only"},
|
|
{Name: "source", Description: "get source package"},
|
|
},
|
|
Options: []spec.Option{
|
|
{Name: "-y", Description: "yes to all"},
|
|
{Name: "--no-install-recommends", Description: "skip recommends"},
|
|
{Name: "-q", Description: "quiet"},
|
|
{Name: "-s", Description: "simulate"},
|
|
{Name: "--fix-missing", Description: "fix missing"},
|
|
},
|
|
})
|
|
|
|
// dnf (Fedora/RHEL)
|
|
spec.Register(&spec.Spec{
|
|
Name: "dnf",
|
|
Description: "Fedora/RHEL package manager",
|
|
Subcommands: []spec.Subcommand{
|
|
{Name: "install", Description: "install packages"},
|
|
{Name: "remove", Description: "remove packages", Generator: installedPackageGenerator("dnf")},
|
|
{Name: "update", Description: "update packages"},
|
|
{Name: "upgrade", Description: "upgrade system"},
|
|
{Name: "search", Description: "search packages"},
|
|
{Name: "info", Description: "show package info"},
|
|
{Name: "list", Description: "list packages"},
|
|
{Name: "autoremove", Description: "remove unneeded"},
|
|
{Name: "clean", Description: "clean cache", Subcommands: []spec.Subcommand{
|
|
{Name: "all", Description: "clean all"},
|
|
{Name: "packages", Description: "clean packages"},
|
|
{Name: "metadata", Description: "clean metadata"},
|
|
}},
|
|
{Name: "repolist", Description: "list repos"},
|
|
{Name: "history", Description: "transaction history"},
|
|
{Name: "group", Description: "manage package groups"},
|
|
},
|
|
Options: []spec.Option{
|
|
{Name: "-y", Description: "yes to all"},
|
|
{Name: "-q", Description: "quiet"},
|
|
{Name: "--best", Description: "install best"},
|
|
{Name: "--allowerasing", Description: "allow package replacement"},
|
|
{Name: "--no-best", Description: "allow older versions"},
|
|
},
|
|
})
|
|
|
|
// yum (RHEL/CentOS legacy)
|
|
spec.Register(&spec.Spec{
|
|
Name: "yum",
|
|
Description: "RHEL/CentOS package manager (legacy)",
|
|
Subcommands: []spec.Subcommand{
|
|
{Name: "install", Description: "install packages"},
|
|
{Name: "remove", Description: "remove packages", Generator: installedPackageGenerator("yum")},
|
|
{Name: "update", Description: "update packages"},
|
|
{Name: "search", Description: "search packages"},
|
|
{Name: "info", Description: "show package info"},
|
|
{Name: "list", Description: "list packages"},
|
|
{Name: "clean", Description: "clean cache"},
|
|
{Name: "repolist", Description: "list repos"},
|
|
},
|
|
Options: []spec.Option{
|
|
{Name: "-y", Description: "yes to all"},
|
|
{Name: "-q", Description: "quiet"},
|
|
},
|
|
})
|
|
|
|
// brew (macOS / Linux Homebrew)
|
|
spec.Register(&spec.Spec{
|
|
Name: "brew",
|
|
Description: "Homebrew package manager",
|
|
Subcommands: []spec.Subcommand{
|
|
{Name: "install", Description: "install formula/cask"},
|
|
{Name: "uninstall", Description: "remove formula", Generator: installedPackageGenerator("brew")},
|
|
{Name: "reinstall", Description: "reinstall formula", Generator: installedPackageGenerator("brew")},
|
|
{Name: "update", Description: "update Homebrew"},
|
|
{Name: "upgrade", Description: "upgrade packages"},
|
|
{Name: "search", Description: "search formulas"},
|
|
{Name: "info", Description: "show package info"},
|
|
{Name: "list", Description: "list installed"},
|
|
{Name: "outdated", Description: "list outdated"},
|
|
{Name: "doctor", Description: "check system"},
|
|
{Name: "cleanup", Description: "remove old versions"},
|
|
{Name: "tap", Description: "add tap repo"},
|
|
{Name: "untap", Description: "remove tap"},
|
|
{Name: "services", Description: "manage services", Subcommands: []spec.Subcommand{
|
|
{Name: "start", Description: "start service"},
|
|
{Name: "stop", Description: "stop service"},
|
|
{Name: "restart", Description: "restart service"},
|
|
{Name: "list", Description: "list services"},
|
|
}},
|
|
{Name: "cask", Description: "manage GUI apps", Subcommands: []spec.Subcommand{
|
|
{Name: "install", Description: "install cask"},
|
|
{Name: "uninstall", Description: "remove cask"},
|
|
{Name: "list", Description: "list casks"},
|
|
}},
|
|
{Name: "pin", Description: "pin formula version", Generator: installedPackageGenerator("brew")},
|
|
{Name: "unpin", Description: "unpin formula", Generator: installedPackageGenerator("brew")},
|
|
{Name: "link", Description: "create symlinks", Generator: installedPackageGenerator("brew")},
|
|
{Name: "unlink", Description: "remove symlinks", Generator: installedPackageGenerator("brew")},
|
|
},
|
|
Options: []spec.Option{
|
|
{Name: "--cask", Description: "target GUI app"},
|
|
{Name: "--formula", Description: "target formula"},
|
|
{Name: "--force", Description: "force operation"},
|
|
{Name: "--verbose", Description: "verbose"},
|
|
{Name: "--dry-run", Description: "simulate"},
|
|
},
|
|
})
|
|
|
|
// snap
|
|
spec.Register(&spec.Spec{
|
|
Name: "snap",
|
|
Description: "snap package manager",
|
|
Subcommands: []spec.Subcommand{
|
|
{Name: "install", Description: "install snap"},
|
|
{Name: "remove", Description: "remove snap"},
|
|
{Name: "refresh", Description: "update snaps"},
|
|
{Name: "list", Description: "list installed"},
|
|
{Name: "find", Description: "search snaps"},
|
|
{Name: "info", Description: "show snap info"},
|
|
{Name: "run", Description: "run snap app"},
|
|
{Name: "connect", Description: "connect snap plug"},
|
|
{Name: "disconnect", Description: "disconnect snap plug"},
|
|
{Name: "revert", Description: "revert to previous"},
|
|
{Name: "enable", Description: "enable snap"},
|
|
{Name: "disable", Description: "disable snap"},
|
|
},
|
|
Options: []spec.Option{
|
|
{Name: "--classic", Description: "classic confinement"},
|
|
{Name: "--beta", Description: "beta channel"},
|
|
{Name: "--edge", Description: "edge channel"},
|
|
{Name: "--channel", Description: "specific channel"},
|
|
},
|
|
})
|
|
|
|
// flatpak
|
|
spec.Register(&spec.Spec{
|
|
Name: "flatpak",
|
|
Description: "flatpak package manager",
|
|
Subcommands: []spec.Subcommand{
|
|
{Name: "install", Description: "install application"},
|
|
{Name: "uninstall", Description: "remove application"},
|
|
{Name: "update", Description: "update applications"},
|
|
{Name: "list", Description: "list installed"},
|
|
{Name: "search", Description: "search applications"},
|
|
{Name: "info", Description: "show app info"},
|
|
{Name: "run", Description: "run application"},
|
|
{Name: "remote-add", Description: "add remote"},
|
|
{Name: "remote-delete", Description: "delete remote"},
|
|
{Name: "remote-list", Description: "list remotes"},
|
|
{Name: "repair", Description: "repair installation"},
|
|
},
|
|
Options: []spec.Option{
|
|
{Name: "--user", Description: "user installation"},
|
|
{Name: "--system", Description: "system installation"},
|
|
{Name: "-y", Description: "non-interactive"},
|
|
},
|
|
})
|
|
}
|