mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-04-30 01:22:06 -04:00
84 lines
2.3 KiB
Go
84 lines
2.3 KiB
Go
package sysupdate
|
|
|
|
import (
|
|
"context"
|
|
"encoding/xml"
|
|
"errors"
|
|
"os/exec"
|
|
)
|
|
|
|
func init() {
|
|
RegisterSystemBackend(func() Backend { return &zypperBackend{} })
|
|
}
|
|
|
|
type zypperBackend struct{}
|
|
|
|
func (zypperBackend) ID() string { return "zypper" }
|
|
func (zypperBackend) DisplayName() string { return "Zypper" }
|
|
func (zypperBackend) Repo() RepoKind { return RepoSystem }
|
|
func (zypperBackend) NeedsAuth() bool { return true }
|
|
func (zypperBackend) RunsInTerminal() bool { return false }
|
|
func (zypperBackend) IsAvailable(_ context.Context) bool { return commandExists("zypper") }
|
|
|
|
type zypperUpdateList struct {
|
|
XMLName xml.Name `xml:"stream"`
|
|
Updates []zypperUpdate `xml:"update-list>update"`
|
|
}
|
|
|
|
type zypperUpdate struct {
|
|
Name string `xml:"name,attr"`
|
|
Edition string `xml:"edition,attr"`
|
|
EditionOld string `xml:"edition-old,attr"`
|
|
Kind string `xml:"kind,attr"`
|
|
}
|
|
|
|
func (zypperBackend) CheckUpdates(ctx context.Context) ([]Package, error) {
|
|
cmd := exec.CommandContext(ctx, "zypper", "--non-interactive", "--xmlout", "list-updates")
|
|
out, err := cmd.Output()
|
|
if err != nil {
|
|
if exitErr, ok := errors.AsType[*exec.ExitError](err); ok {
|
|
switch exitErr.ExitCode() {
|
|
case 100, 101, 102, 103:
|
|
err = nil
|
|
}
|
|
}
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
return parseZypperXML(out)
|
|
}
|
|
|
|
func parseZypperXML(out []byte) ([]Package, error) {
|
|
var list zypperUpdateList
|
|
if err := xml.Unmarshal(out, &list); err != nil {
|
|
return nil, err
|
|
}
|
|
pkgs := make([]Package, 0, len(list.Updates))
|
|
for _, u := range list.Updates {
|
|
if u.Kind != "" && u.Kind != "package" {
|
|
continue
|
|
}
|
|
pkgs = append(pkgs, Package{
|
|
Name: u.Name,
|
|
Repo: RepoSystem,
|
|
Backend: "zypper",
|
|
FromVersion: u.EditionOld,
|
|
ToVersion: u.Edition,
|
|
})
|
|
}
|
|
return pkgs, nil
|
|
}
|
|
|
|
func (zypperBackend) Upgrade(ctx context.Context, opts UpgradeOptions, onLine func(string)) error {
|
|
if opts.DryRun {
|
|
return Run(ctx, []string{"zypper", "--non-interactive", "--dry-run", "update"}, RunOptions{OnLine: onLine})
|
|
}
|
|
names := pickTargetNames(opts.Targets, "zypper", true)
|
|
if len(names) == 0 {
|
|
return nil
|
|
}
|
|
argv := append([]string{"pkexec", "zypper", "--non-interactive", "update"}, names...)
|
|
return Run(ctx, argv, RunOptions{OnLine: onLine})
|
|
}
|