forked from Plemya-x/ALR
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:
169
internal/manager/apk.go
Normal file
169
internal/manager/apk.go
Normal 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
155
internal/manager/apt.go
Normal 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
112
internal/manager/apt_rpm.go
Normal 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
|
||||
}
|
35
internal/manager/common.go
Normal file
35
internal/manager/common.go
Normal 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
|
||||
}
|
72
internal/manager/common_rpm.go
Normal file
72
internal/manager/common_rpm.go
Normal 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
120
internal/manager/dnf.go
Normal 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
|
||||
}
|
114
internal/manager/managers.go
Normal file
114
internal/manager/managers.go
Normal 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
162
internal/manager/pacman.go
Normal 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
115
internal/manager/yum.go
Normal 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
115
internal/manager/zypper.go
Normal 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
|
||||
}
|
Reference in New Issue
Block a user