refactor: move pkg/ to internal/ and update imports

Restructure project by relocating package contents from pkg/ to internal/ to better reflect internal-only usage. This commit is initial step to prepare project for public api
This commit is contained in:
2025-06-09 10:15:47 +03:00
parent 06fcab4ce7
commit 703ab8e8c4
63 changed files with 209 additions and 209 deletions

169
internal/manager/apk.go Normal file
View File

@ -0,0 +1,169 @@
// This file was originally part of the project "LURE - Linux User REpository", created by Elara Musayelyan.
// It has been modified as part of "ALR - Any Linux Repository" by the ALR Authors.
//
// ALR - Any Linux Repository
// Copyright (C) 2025 The ALR Authors
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
package manager
import (
"bufio"
"fmt"
"os/exec"
"strings"
)
// APK represents the APK package manager
type APK struct {
CommonPackageManager
}
func NewAPK() *APK {
return &APK{
CommonPackageManager: CommonPackageManager{
noConfirmArg: "-i",
},
}
}
func (*APK) Exists() bool {
_, err := exec.LookPath("apk")
return err == nil
}
func (*APK) Name() string {
return "apk"
}
func (*APK) Format() string {
return "apk"
}
func (a *APK) Sync(opts *Opts) error {
opts = ensureOpts(opts)
cmd := a.getCmd(opts, "apk", "update")
setCmdEnv(cmd)
err := cmd.Run()
if err != nil {
return fmt.Errorf("apk: sync: %w", err)
}
return nil
}
func (a *APK) Install(opts *Opts, pkgs ...string) error {
opts = ensureOpts(opts)
cmd := a.getCmd(opts, "apk", "add")
cmd.Args = append(cmd.Args, pkgs...)
setCmdEnv(cmd)
err := cmd.Run()
if err != nil {
return fmt.Errorf("apk: install: %w", err)
}
return nil
}
func (a *APK) InstallLocal(opts *Opts, pkgs ...string) error {
opts = ensureOpts(opts)
cmd := a.getCmd(opts, "apk", "add", "--allow-untrusted")
cmd.Args = append(cmd.Args, pkgs...)
setCmdEnv(cmd)
err := cmd.Run()
if err != nil {
return fmt.Errorf("apk: installlocal: %w", err)
}
return nil
}
func (a *APK) Remove(opts *Opts, pkgs ...string) error {
opts = ensureOpts(opts)
cmd := a.getCmd(opts, "apk", "del")
cmd.Args = append(cmd.Args, pkgs...)
setCmdEnv(cmd)
err := cmd.Run()
if err != nil {
return fmt.Errorf("apk: remove: %w", err)
}
return nil
}
func (a *APK) Upgrade(opts *Opts, pkgs ...string) error {
opts = ensureOpts(opts)
cmd := a.getCmd(opts, "apk", "upgrade")
cmd.Args = append(cmd.Args, pkgs...)
setCmdEnv(cmd)
err := cmd.Run()
if err != nil {
return fmt.Errorf("apk: upgrade: %w", err)
}
return nil
}
func (a *APK) UpgradeAll(opts *Opts) error {
opts = ensureOpts(opts)
return a.Upgrade(opts)
}
func (a *APK) ListInstalled(opts *Opts) (map[string]string, error) {
out := map[string]string{}
cmd := exec.Command("apk", "list", "-I")
stdout, err := cmd.StdoutPipe()
if err != nil {
return nil, err
}
err = cmd.Start()
if err != nil {
return nil, err
}
scanner := bufio.NewScanner(stdout)
for scanner.Scan() {
name, info, ok := strings.Cut(scanner.Text(), "-")
if !ok {
continue
}
version, _, ok := strings.Cut(info, " ")
if !ok {
continue
}
out[name] = version
}
err = scanner.Err()
if err != nil {
return nil, err
}
return out, nil
}
func (a *APK) IsInstalled(pkg string) (bool, error) {
cmd := exec.Command("apk", "info", "--installed", pkg)
output, err := cmd.CombinedOutput()
if err != nil {
if exitErr, ok := err.(*exec.ExitError); ok {
// Exit code 1 means the package is not installed
if exitErr.ExitCode() == 1 {
return false, nil
}
}
return false, fmt.Errorf("apk: isinstalled: %w, output: %s", err, output)
}
return true, nil
}

155
internal/manager/apt.go Normal file
View File

@ -0,0 +1,155 @@
// This file was originally part of the project "LURE - Linux User REpository", created by Elara Musayelyan.
// It has been modified as part of "ALR - Any Linux Repository" by the ALR Authors.
//
// ALR - Any Linux Repository
// Copyright (C) 2025 The ALR Authors
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
package manager
import (
"bufio"
"fmt"
"os/exec"
"strings"
)
// APT represents the APT package manager
type APT struct {
CommonPackageManager
}
func NewAPT() *APT {
return &APT{
CommonPackageManager: CommonPackageManager{
noConfirmArg: "-y",
},
}
}
func (*APT) Exists() bool {
_, err := exec.LookPath("apt")
return err == nil
}
func (*APT) Name() string {
return "apt"
}
func (*APT) Format() string {
return "deb"
}
func (a *APT) Sync(opts *Opts) error {
opts = ensureOpts(opts)
cmd := a.getCmd(opts, "apt", "update")
setCmdEnv(cmd)
err := cmd.Run()
if err != nil {
return fmt.Errorf("apt: sync: %w", err)
}
return nil
}
func (a *APT) Install(opts *Opts, pkgs ...string) error {
opts = ensureOpts(opts)
cmd := a.getCmd(opts, "apt", "install")
cmd.Args = append(cmd.Args, pkgs...)
setCmdEnv(cmd)
err := cmd.Run()
if err != nil {
return fmt.Errorf("apt: install: %w", err)
}
return nil
}
func (a *APT) InstallLocal(opts *Opts, pkgs ...string) error {
opts = ensureOpts(opts)
return a.Install(opts, pkgs...)
}
func (a *APT) Remove(opts *Opts, pkgs ...string) error {
opts = ensureOpts(opts)
cmd := a.getCmd(opts, "apt", "remove")
cmd.Args = append(cmd.Args, pkgs...)
setCmdEnv(cmd)
err := cmd.Run()
if err != nil {
return fmt.Errorf("apt: remove: %w", err)
}
return nil
}
func (a *APT) Upgrade(opts *Opts, pkgs ...string) error {
opts = ensureOpts(opts)
return a.Install(opts, pkgs...)
}
func (a *APT) UpgradeAll(opts *Opts) error {
opts = ensureOpts(opts)
cmd := a.getCmd(opts, "apt", "upgrade")
setCmdEnv(cmd)
err := cmd.Run()
if err != nil {
return fmt.Errorf("apt: upgradeall: %w", err)
}
return nil
}
func (a *APT) ListInstalled(opts *Opts) (map[string]string, error) {
out := map[string]string{}
cmd := exec.Command("dpkg-query", "-f", "${Package}\u200b${Version}\\n", "-W")
stdout, err := cmd.StdoutPipe()
if err != nil {
return nil, err
}
err = cmd.Start()
if err != nil {
return nil, err
}
scanner := bufio.NewScanner(stdout)
for scanner.Scan() {
name, version, ok := strings.Cut(scanner.Text(), "\u200b")
if !ok {
continue
}
out[name] = version
}
err = scanner.Err()
if err != nil {
return nil, err
}
return out, nil
}
func (a *APT) IsInstalled(pkg string) (bool, error) {
cmd := exec.Command("dpkg-query", "-l", pkg)
output, err := cmd.CombinedOutput()
if err != nil {
if exitErr, ok := err.(*exec.ExitError); ok {
// Exit code 1 means the package is not installed
if exitErr.ExitCode() == 1 {
return false, nil
}
}
return false, fmt.Errorf("apt: isinstalled: %w, output: %s", err, output)
}
return true, nil
}

112
internal/manager/apt_rpm.go Normal file
View File

@ -0,0 +1,112 @@
// ALR - Any Linux Repository
// Copyright (C) 2025 The ALR Authors
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
package manager
import (
"fmt"
"os/exec"
"strings"
)
// APTRpm represents the APT-RPM package manager
type APTRpm struct {
CommonPackageManager
CommonRPM
}
func NewAPTRpm() *APTRpm {
return &APTRpm{
CommonPackageManager: CommonPackageManager{
noConfirmArg: "-y",
},
}
}
func (*APTRpm) Name() string {
return "apt-rpm"
}
func (*APTRpm) Format() string {
return "rpm"
}
func (*APTRpm) Exists() bool {
cmd := exec.Command("apt-config", "dump")
output, err := cmd.Output()
if err != nil {
return false
}
return strings.Contains(string(output), "RPM")
}
func (a *APTRpm) Sync(opts *Opts) error {
opts = ensureOpts(opts)
cmd := a.getCmd(opts, "apt-get", "update")
setCmdEnv(cmd)
err := cmd.Run()
if err != nil {
return fmt.Errorf("apt-get: sync: %w", err)
}
return nil
}
func (a *APTRpm) Install(opts *Opts, pkgs ...string) error {
opts = ensureOpts(opts)
cmd := a.getCmd(opts, "apt-get", "install")
cmd.Args = append(cmd.Args, pkgs...)
setCmdEnv(cmd)
cmd.Stdout = cmd.Stderr
err := cmd.Run()
if err != nil {
return fmt.Errorf("apt-get: install: %w", err)
}
return nil
}
func (a *APTRpm) InstallLocal(opts *Opts, pkgs ...string) error {
opts = ensureOpts(opts)
return a.Install(opts, pkgs...)
}
func (a *APTRpm) Remove(opts *Opts, pkgs ...string) error {
opts = ensureOpts(opts)
cmd := a.getCmd(opts, "apt-get", "remove")
cmd.Args = append(cmd.Args, pkgs...)
setCmdEnv(cmd)
err := cmd.Run()
if err != nil {
return fmt.Errorf("apt-get: remove: %w", err)
}
return nil
}
func (a *APTRpm) Upgrade(opts *Opts, pkgs ...string) error {
opts = ensureOpts(opts)
return a.Install(opts, pkgs...)
}
func (a *APTRpm) UpgradeAll(opts *Opts) error {
opts = ensureOpts(opts)
cmd := a.getCmd(opts, "apt-get", "dist-upgrade")
setCmdEnv(cmd)
err := cmd.Run()
if err != nil {
return fmt.Errorf("apt-get: upgradeall: %w", err)
}
return nil
}

View File

@ -0,0 +1,35 @@
// ALR - Any Linux Repository
// Copyright (C) 2025 The ALR Authors
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
package manager
import "os/exec"
type CommonPackageManager struct {
noConfirmArg string
}
func (m *CommonPackageManager) getCmd(opts *Opts, mgrCmd string, args ...string) *exec.Cmd {
cmd := exec.Command(mgrCmd)
cmd.Args = append(cmd.Args, opts.Args...)
cmd.Args = append(cmd.Args, args...)
if opts.NoConfirm {
cmd.Args = append(cmd.Args, m.noConfirmArg)
}
return cmd
}

View File

@ -0,0 +1,72 @@
// ALR - Any Linux Repository
// Copyright (C) 2025 The ALR Authors
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
package manager
import (
"bufio"
"fmt"
"os/exec"
"strings"
)
type CommonRPM struct{}
func (c *CommonRPM) ListInstalled(opts *Opts) (map[string]string, error) {
out := map[string]string{}
cmd := exec.Command("rpm", "-qa", "--queryformat", "%{NAME}\u200b%|EPOCH?{%{EPOCH}:}:{}|%{VERSION}-%{RELEASE}\\n")
stdout, err := cmd.StdoutPipe()
if err != nil {
return nil, err
}
err = cmd.Start()
if err != nil {
return nil, err
}
scanner := bufio.NewScanner(stdout)
for scanner.Scan() {
name, version, ok := strings.Cut(scanner.Text(), "\u200b")
if !ok {
continue
}
version = strings.TrimPrefix(version, "0:")
out[name] = version
}
err = scanner.Err()
if err != nil {
return nil, err
}
return out, nil
}
func (a *CommonRPM) IsInstalled(pkg string) (bool, error) {
cmd := exec.Command("rpm", "-q", "--whatprovides", pkg)
output, err := cmd.CombinedOutput()
if err != nil {
if exitErr, ok := err.(*exec.ExitError); ok {
if exitErr.ExitCode() == 1 {
return false, nil
}
}
return false, fmt.Errorf("rpm: isinstalled: %w, output: %s", err, output)
}
return true, nil
}

120
internal/manager/dnf.go Normal file
View File

@ -0,0 +1,120 @@
// This file was originally part of the project "LURE - Linux User REpository", created by Elara Musayelyan.
// It has been modified as part of "ALR - Any Linux Repository" by the ALR Authors.
//
// ALR - Any Linux Repository
// Copyright (C) 2025 The ALR Authors
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
package manager
import (
"fmt"
"os/exec"
)
type DNF struct {
CommonPackageManager
CommonRPM
}
func NewDNF() *DNF {
return &DNF{
CommonPackageManager: CommonPackageManager{
noConfirmArg: "-y",
},
}
}
func (*DNF) Exists() bool {
_, err := exec.LookPath("dnf")
return err == nil
}
func (*DNF) Name() string {
return "dnf"
}
func (*DNF) Format() string {
return "rpm"
}
// Sync выполняет upgrade всех установленных пакетов, обновляя их до более новых версий
func (d *DNF) Sync(opts *Opts) error {
opts = ensureOpts(opts) // Гарантирует, что opts не равен nil и содержит допустимые значения
cmd := d.getCmd(opts, "dnf", "upgrade")
setCmdEnv(cmd) // Устанавливает переменные окружения для команды
err := cmd.Run() // Выполняет команду
if err != nil {
return fmt.Errorf("dnf: sync: %w", err)
}
return nil
}
// Install устанавливает указанные пакеты с помощью DNF
func (d *DNF) Install(opts *Opts, pkgs ...string) error {
opts = ensureOpts(opts)
cmd := d.getCmd(opts, "dnf", "install", "--allowerasing")
cmd.Args = append(cmd.Args, pkgs...) // Добавляем названия пакетов к команде
setCmdEnv(cmd)
err := cmd.Run()
if err != nil {
return fmt.Errorf("dnf: install: %w", err)
}
return nil
}
// InstallLocal расширяет метод Install для установки пакетов, расположенных локально
func (d *DNF) InstallLocal(opts *Opts, pkgs ...string) error {
opts = ensureOpts(opts)
return d.Install(opts, pkgs...)
}
// Remove удаляет указанные пакеты с помощью DNF
func (d *DNF) Remove(opts *Opts, pkgs ...string) error {
opts = ensureOpts(opts)
cmd := d.getCmd(opts, "dnf", "remove")
cmd.Args = append(cmd.Args, pkgs...)
setCmdEnv(cmd)
err := cmd.Run()
if err != nil {
return fmt.Errorf("dnf: remove: %w", err)
}
return nil
}
// Upgrade обновляет указанные пакеты до более новых версий
func (d *DNF) Upgrade(opts *Opts, pkgs ...string) error {
opts = ensureOpts(opts)
cmd := d.getCmd(opts, "dnf", "upgrade")
cmd.Args = append(cmd.Args, pkgs...)
setCmdEnv(cmd)
err := cmd.Run()
if err != nil {
return fmt.Errorf("dnf: upgrade: %w", err)
}
return nil
}
// UpgradeAll обновляет все установленные пакеты
func (d *DNF) UpgradeAll(opts *Opts) error {
opts = ensureOpts(opts)
cmd := d.getCmd(opts, "dnf", "upgrade")
setCmdEnv(cmd)
err := cmd.Run()
if err != nil {
return fmt.Errorf("dnf: upgradeall: %w", err)
}
return nil
}

View File

@ -0,0 +1,114 @@
// This file was originally part of the project "LURE - Linux User REpository", created by Elara Musayelyan.
// It has been modified as part of "ALR - Any Linux Repository" by the ALR Authors.
//
// ALR - Any Linux Repository
// Copyright (C) 2025 The ALR Authors
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
package manager
import (
"os"
"os/exec"
)
var Args []string
type Opts struct {
NoConfirm bool
Args []string
}
var DefaultOpts = &Opts{
NoConfirm: false,
}
var managers = []Manager{
NewPacman(),
NewAPT(),
NewDNF(),
NewYUM(),
NewAPK(),
NewZypper(),
NewAPTRpm(),
}
// Register registers a new package manager
func Register(m Manager) {
managers = append(managers, m)
}
// Manager represents a system package manager
type Manager interface {
// Name returns the name of the manager.
Name() string
// Format returns the packaging format of the manager.
// Examples: rpm, deb, apk
Format() string
// Returns true if the package manager exists on the system.
Exists() bool
// Sync fetches repositories without installing anything
Sync(*Opts) error
// Install installs packages
Install(*Opts, ...string) error
// Remove uninstalls packages
Remove(*Opts, ...string) error
// Upgrade upgrades packages
Upgrade(*Opts, ...string) error
// InstallLocal installs packages from local files rather than repos
InstallLocal(*Opts, ...string) error
// UpgradeAll upgrades all packages
UpgradeAll(*Opts) error
// ListInstalled returns all installed packages mapped to their versions
ListInstalled(*Opts) (map[string]string, error)
//
IsInstalled(string) (bool, error)
}
// Detect returns the package manager detected on the system
func Detect() Manager {
for _, mgr := range managers {
if mgr.Exists() {
return mgr
}
}
return nil
}
// Get returns the package manager with the given name
func Get(name string) Manager {
for _, mgr := range managers {
if mgr.Name() == name {
return mgr
}
}
return nil
}
func setCmdEnv(cmd *exec.Cmd) {
cmd.Env = os.Environ()
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stderr
cmd.Stderr = os.Stderr
}
func ensureOpts(opts *Opts) *Opts {
if opts == nil {
opts = DefaultOpts
}
opts.Args = append(opts.Args, Args...)
return opts
}

162
internal/manager/pacman.go Normal file
View File

@ -0,0 +1,162 @@
// This file was originally part of the project "LURE - Linux User REpository", created by Elara Musayelyan.
// It has been modified as part of "ALR - Any Linux Repository" by the ALR Authors.
//
// ALR - Any Linux Repository
// Copyright (C) 2025 The ALR Authors
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
package manager
import (
"bufio"
"fmt"
"os/exec"
"strings"
)
// Pacman represents the Pacman package manager
type Pacman struct {
CommonPackageManager
}
func NewPacman() *Pacman {
return &Pacman{
CommonPackageManager: CommonPackageManager{
noConfirmArg: "--noconfirm",
},
}
}
func (*Pacman) Exists() bool {
_, err := exec.LookPath("pacman")
return err == nil
}
func (*Pacman) Name() string {
return "pacman"
}
func (*Pacman) Format() string {
return "archlinux"
}
func (p *Pacman) Sync(opts *Opts) error {
opts = ensureOpts(opts)
cmd := p.getCmd(opts, "pacman", "-Sy")
setCmdEnv(cmd)
err := cmd.Run()
if err != nil {
return fmt.Errorf("pacman: sync: %w", err)
}
return nil
}
func (p *Pacman) Install(opts *Opts, pkgs ...string) error {
opts = ensureOpts(opts)
cmd := p.getCmd(opts, "pacman", "-S", "--needed")
cmd.Args = append(cmd.Args, pkgs...)
setCmdEnv(cmd)
err := cmd.Run()
if err != nil {
return fmt.Errorf("pacman: install: %w", err)
}
return nil
}
func (p *Pacman) InstallLocal(opts *Opts, pkgs ...string) error {
opts = ensureOpts(opts)
cmd := p.getCmd(opts, "pacman", "-U", "--needed")
cmd.Args = append(cmd.Args, pkgs...)
setCmdEnv(cmd)
err := cmd.Run()
if err != nil {
return fmt.Errorf("pacman: installlocal: %w", err)
}
return nil
}
func (p *Pacman) Remove(opts *Opts, pkgs ...string) error {
opts = ensureOpts(opts)
cmd := p.getCmd(opts, "pacman", "-R")
cmd.Args = append(cmd.Args, pkgs...)
setCmdEnv(cmd)
err := cmd.Run()
if err != nil {
return fmt.Errorf("pacman: remove: %w", err)
}
return nil
}
func (p *Pacman) Upgrade(opts *Opts, pkgs ...string) error {
opts = ensureOpts(opts)
return p.Install(opts, pkgs...)
}
func (p *Pacman) UpgradeAll(opts *Opts) error {
opts = ensureOpts(opts)
cmd := p.getCmd(opts, "pacman", "-Su")
setCmdEnv(cmd)
err := cmd.Run()
if err != nil {
return fmt.Errorf("pacman: upgradeall: %w", err)
}
return nil
}
func (p *Pacman) ListInstalled(opts *Opts) (map[string]string, error) {
out := map[string]string{}
cmd := exec.Command("pacman", "-Q")
stdout, err := cmd.StdoutPipe()
if err != nil {
return nil, err
}
err = cmd.Start()
if err != nil {
return nil, err
}
scanner := bufio.NewScanner(stdout)
for scanner.Scan() {
name, version, ok := strings.Cut(scanner.Text(), " ")
if !ok {
continue
}
out[name] = version
}
err = scanner.Err()
if err != nil {
return nil, err
}
return out, nil
}
func (p *Pacman) IsInstalled(pkg string) (bool, error) {
cmd := exec.Command("pacman", "-Q", pkg)
output, err := cmd.CombinedOutput()
if err != nil {
// Pacman returns exit code 1 if the package is not found
if exitErr, ok := err.(*exec.ExitError); ok {
if exitErr.ExitCode() == 1 {
return false, nil
}
}
return false, fmt.Errorf("pacman: isinstalled: %w, output: %s", err, output)
}
return true, nil
}

115
internal/manager/yum.go Normal file
View File

@ -0,0 +1,115 @@
// This file was originally part of the project "LURE - Linux User REpository", created by Elara Musayelyan.
// It has been modified as part of "ALR - Any Linux Repository" by the ALR Authors.
//
// ALR - Any Linux Repository
// Copyright (C) 2025 The ALR Authors
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
package manager
import (
"fmt"
"os/exec"
)
// YUM represents the YUM package manager
type YUM struct {
CommonPackageManager
CommonRPM
}
func NewYUM() *YUM {
return &YUM{
CommonPackageManager: CommonPackageManager{
noConfirmArg: "-y",
},
}
}
func (*YUM) Exists() bool {
_, err := exec.LookPath("yum")
return err == nil
}
func (*YUM) Name() string {
return "yum"
}
func (*YUM) Format() string {
return "rpm"
}
func (y *YUM) Sync(opts *Opts) error {
opts = ensureOpts(opts)
cmd := y.getCmd(opts, "yum", "upgrade")
setCmdEnv(cmd)
err := cmd.Run()
if err != nil {
return fmt.Errorf("yum: sync: %w", err)
}
return nil
}
func (y *YUM) Install(opts *Opts, pkgs ...string) error {
opts = ensureOpts(opts)
cmd := y.getCmd(opts, "yum", "install", "--allowerasing")
cmd.Args = append(cmd.Args, pkgs...)
setCmdEnv(cmd)
err := cmd.Run()
if err != nil {
return fmt.Errorf("yum: install: %w", err)
}
return nil
}
func (y *YUM) InstallLocal(opts *Opts, pkgs ...string) error {
opts = ensureOpts(opts)
return y.Install(opts, pkgs...)
}
func (y *YUM) Remove(opts *Opts, pkgs ...string) error {
opts = ensureOpts(opts)
cmd := y.getCmd(opts, "yum", "remove")
cmd.Args = append(cmd.Args, pkgs...)
setCmdEnv(cmd)
err := cmd.Run()
if err != nil {
return fmt.Errorf("yum: remove: %w", err)
}
return nil
}
func (y *YUM) Upgrade(opts *Opts, pkgs ...string) error {
opts = ensureOpts(opts)
cmd := y.getCmd(opts, "yum", "upgrade")
cmd.Args = append(cmd.Args, pkgs...)
setCmdEnv(cmd)
err := cmd.Run()
if err != nil {
return fmt.Errorf("yum: upgrade: %w", err)
}
return nil
}
func (y *YUM) UpgradeAll(opts *Opts) error {
opts = ensureOpts(opts)
cmd := y.getCmd(opts, "yum", "upgrade")
setCmdEnv(cmd)
err := cmd.Run()
if err != nil {
return fmt.Errorf("yum: upgradeall: %w", err)
}
return nil
}

115
internal/manager/zypper.go Normal file
View File

@ -0,0 +1,115 @@
// This file was originally part of the project "LURE - Linux User REpository", created by Elara Musayelyan.
// It has been modified as part of "ALR - Any Linux Repository" by the ALR Authors.
//
// ALR - Any Linux Repository
// Copyright (C) 2025 The ALR Authors
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
package manager
import (
"fmt"
"os/exec"
)
// Zypper represents the Zypper package manager
type Zypper struct {
CommonPackageManager
CommonRPM
}
func NewZypper() *YUM {
return &YUM{
CommonPackageManager: CommonPackageManager{
noConfirmArg: "-y",
},
}
}
func (*Zypper) Exists() bool {
_, err := exec.LookPath("zypper")
return err == nil
}
func (*Zypper) Name() string {
return "zypper"
}
func (*Zypper) Format() string {
return "rpm"
}
func (z *Zypper) Sync(opts *Opts) error {
opts = ensureOpts(opts)
cmd := z.getCmd(opts, "zypper", "refresh")
setCmdEnv(cmd)
err := cmd.Run()
if err != nil {
return fmt.Errorf("zypper: sync: %w", err)
}
return nil
}
func (z *Zypper) Install(opts *Opts, pkgs ...string) error {
opts = ensureOpts(opts)
cmd := z.getCmd(opts, "zypper", "install", "-y")
cmd.Args = append(cmd.Args, pkgs...)
setCmdEnv(cmd)
err := cmd.Run()
if err != nil {
return fmt.Errorf("zypper: install: %w", err)
}
return nil
}
func (z *Zypper) InstallLocal(opts *Opts, pkgs ...string) error {
opts = ensureOpts(opts)
return z.Install(opts, pkgs...)
}
func (z *Zypper) Remove(opts *Opts, pkgs ...string) error {
opts = ensureOpts(opts)
cmd := z.getCmd(opts, "zypper", "remove", "-y")
cmd.Args = append(cmd.Args, pkgs...)
setCmdEnv(cmd)
err := cmd.Run()
if err != nil {
return fmt.Errorf("zypper: remove: %w", err)
}
return nil
}
func (z *Zypper) Upgrade(opts *Opts, pkgs ...string) error {
opts = ensureOpts(opts)
cmd := z.getCmd(opts, "zypper", "update", "-y")
cmd.Args = append(cmd.Args, pkgs...)
setCmdEnv(cmd)
err := cmd.Run()
if err != nil {
return fmt.Errorf("zypper: upgrade: %w", err)
}
return nil
}
func (z *Zypper) UpgradeAll(opts *Opts) error {
opts = ensureOpts(opts)
cmd := z.getCmd(opts, "zypper", "update", "-y")
setCmdEnv(cmd)
err := cmd.Run()
if err != nil {
return fmt.Errorf("zypper: upgradeall: %w", err)
}
return nil
}