mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-04-30 01:22:06 -04:00
system updater: make all distros use terminal
This commit is contained in:
@@ -7,6 +7,8 @@ This file is more of a quick reference so I know what to account for before next
|
||||
- Terminal mux
|
||||
- Locale overrides
|
||||
- new neovim theming
|
||||
- system upder overhaul
|
||||
- New Log system, remember to update all plugins after release as it breaks compat
|
||||
|
||||
# 1.4.0
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -183,10 +184,20 @@ func runSystemUpdateApply() {
|
||||
DryRun: sysUpdateDry,
|
||||
}
|
||||
|
||||
onLine := func(line string) { fmt.Println(line) }
|
||||
for _, b := range backends {
|
||||
fmt.Printf("\n== %s ==\n", b.DisplayName())
|
||||
if err := b.Upgrade(ctx, opts, onLine); err != nil {
|
||||
cmd, err := b.UpgradeCommand(opts)
|
||||
if err != nil {
|
||||
log.Fatalf("%s: %v", b.ID(), err)
|
||||
}
|
||||
if cmd == "" {
|
||||
continue
|
||||
}
|
||||
fmt.Printf("\n== %s ==\n$ %s\n\n", b.DisplayName(), cmd)
|
||||
shell := exec.CommandContext(ctx, "sh", "-c", cmd)
|
||||
shell.Stdin = os.Stdin
|
||||
shell.Stdout = os.Stdout
|
||||
shell.Stderr = os.Stderr
|
||||
if err := shell.Run(); err != nil {
|
||||
log.Fatalf("%s upgrade failed: %v", b.ID(), err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,9 +12,8 @@ type Backend interface {
|
||||
Repo() RepoKind
|
||||
IsAvailable(ctx context.Context) bool
|
||||
NeedsAuth() bool
|
||||
RunsInTerminal() bool
|
||||
CheckUpdates(ctx context.Context) ([]Package, error)
|
||||
Upgrade(ctx context.Context, opts UpgradeOptions, onLine func(string)) error
|
||||
UpgradeCommand(opts UpgradeOptions) (string, error)
|
||||
}
|
||||
|
||||
type Selection struct {
|
||||
@@ -37,11 +36,10 @@ func (s Selection) Info() []BackendInfo {
|
||||
out := make([]BackendInfo, 0, len(all))
|
||||
for _, b := range all {
|
||||
out = append(out, BackendInfo{
|
||||
ID: b.ID(),
|
||||
DisplayName: b.DisplayName(),
|
||||
Repo: b.Repo(),
|
||||
NeedsAuth: b.NeedsAuth(),
|
||||
RunsInTerminal: b.RunsInTerminal(),
|
||||
ID: b.ID(),
|
||||
DisplayName: b.DisplayName(),
|
||||
Repo: b.Repo(),
|
||||
NeedsAuth: b.NeedsAuth(),
|
||||
})
|
||||
}
|
||||
return out
|
||||
|
||||
@@ -15,11 +15,10 @@ var aptUpgradableLine = regexp.MustCompile(`^([^/]+)/\S+\s+(\S+)\s+\S+\s+\[upgra
|
||||
|
||||
type aptBackend struct{}
|
||||
|
||||
func (aptBackend) ID() string { return "apt" }
|
||||
func (aptBackend) DisplayName() string { return "APT" }
|
||||
func (aptBackend) Repo() RepoKind { return RepoSystem }
|
||||
func (aptBackend) NeedsAuth() bool { return true }
|
||||
func (aptBackend) RunsInTerminal() bool { return false }
|
||||
func (aptBackend) ID() string { return "apt" }
|
||||
func (aptBackend) DisplayName() string { return "APT" }
|
||||
func (aptBackend) Repo() RepoKind { return RepoSystem }
|
||||
func (aptBackend) NeedsAuth() bool { return true }
|
||||
func (aptBackend) IsAvailable(_ context.Context) bool {
|
||||
return commandExists("apt") || commandExists("apt-get")
|
||||
}
|
||||
@@ -34,19 +33,16 @@ func (aptBackend) CheckUpdates(ctx context.Context) ([]Package, error) {
|
||||
return parseAptUpgradable(string(out)), nil
|
||||
}
|
||||
|
||||
func (aptBackend) Upgrade(ctx context.Context, opts UpgradeOptions, onLine func(string)) error {
|
||||
func (aptBackend) UpgradeCommand(opts UpgradeOptions) (string, error) {
|
||||
bin := "apt-get"
|
||||
if !commandExists(bin) {
|
||||
bin = "apt"
|
||||
}
|
||||
env := "DEBIAN_FRONTEND=noninteractive LC_ALL=C "
|
||||
if opts.DryRun {
|
||||
return Run(ctx, []string{bin, "upgrade", "--dry-run"}, RunOptions{
|
||||
Env: []string{"DEBIAN_FRONTEND=noninteractive", "LC_ALL=C"},
|
||||
OnLine: onLine,
|
||||
})
|
||||
return env + bin + " upgrade --dry-run", nil
|
||||
}
|
||||
argv := []string{"pkexec", "env", "DEBIAN_FRONTEND=noninteractive", "LC_ALL=C", bin, "upgrade", "-y"}
|
||||
return Run(ctx, argv, RunOptions{OnLine: onLine})
|
||||
return "sudo " + env + bin + " upgrade -y", nil
|
||||
}
|
||||
|
||||
func parseAptUpgradable(text string) []Package {
|
||||
|
||||
@@ -3,6 +3,7 @@ package sysupdate
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"strings"
|
||||
)
|
||||
@@ -16,11 +17,10 @@ type dnfBackend struct {
|
||||
bin string
|
||||
}
|
||||
|
||||
func (b dnfBackend) ID() string { return b.bin }
|
||||
func (b dnfBackend) DisplayName() string { return strings.ToUpper(b.bin) }
|
||||
func (b dnfBackend) Repo() RepoKind { return RepoSystem }
|
||||
func (b dnfBackend) NeedsAuth() bool { return true }
|
||||
func (b dnfBackend) RunsInTerminal() bool { return false }
|
||||
func (b dnfBackend) ID() string { return b.bin }
|
||||
func (b dnfBackend) DisplayName() string { return strings.ToUpper(b.bin) }
|
||||
func (b dnfBackend) Repo() RepoKind { return RepoSystem }
|
||||
func (b dnfBackend) NeedsAuth() bool { return true }
|
||||
|
||||
func (b dnfBackend) IsAvailable(ctx context.Context) bool {
|
||||
if !commandExists(b.bin) {
|
||||
@@ -41,11 +41,11 @@ func (b dnfBackend) CheckUpdates(ctx context.Context) ([]Package, error) {
|
||||
return parseDnfList(out, b.bin, installed), nil
|
||||
}
|
||||
|
||||
func (b dnfBackend) Upgrade(ctx context.Context, opts UpgradeOptions, onLine func(string)) error {
|
||||
func (b dnfBackend) UpgradeCommand(opts UpgradeOptions) (string, error) {
|
||||
if opts.DryRun {
|
||||
return Run(ctx, []string{b.bin, "upgrade", "--assumeno"}, RunOptions{OnLine: onLine})
|
||||
return fmt.Sprintf("%s upgrade --assumeno", b.bin), nil
|
||||
}
|
||||
return Run(ctx, []string{"pkexec", b.bin, "upgrade", "-y"}, RunOptions{OnLine: onLine})
|
||||
return fmt.Sprintf("sudo %s upgrade -y", b.bin), nil
|
||||
}
|
||||
|
||||
func dnfListUpgrades(ctx context.Context, bin string) (string, error) {
|
||||
|
||||
@@ -16,7 +16,6 @@ func (flatpakBackend) ID() string { return "flatpak" }
|
||||
func (flatpakBackend) DisplayName() string { return "Flatpak" }
|
||||
func (flatpakBackend) Repo() RepoKind { return RepoFlatpak }
|
||||
func (flatpakBackend) NeedsAuth() bool { return false }
|
||||
func (flatpakBackend) RunsInTerminal() bool { return false }
|
||||
func (flatpakBackend) IsAvailable(_ context.Context) bool { return commandExists("flatpak") }
|
||||
|
||||
func (flatpakBackend) CheckUpdates(ctx context.Context) ([]Package, error) {
|
||||
@@ -69,12 +68,11 @@ type flatpakInstalledEntry struct {
|
||||
commit string
|
||||
}
|
||||
|
||||
func (flatpakBackend) Upgrade(ctx context.Context, opts UpgradeOptions, onLine func(string)) error {
|
||||
argv := []string{"flatpak", "update", "-y", "--noninteractive"}
|
||||
func (flatpakBackend) UpgradeCommand(opts UpgradeOptions) (string, error) {
|
||||
if opts.DryRun {
|
||||
argv = []string{"flatpak", "update", "--no-deploy", "-y"}
|
||||
return "flatpak update --no-deploy -y", nil
|
||||
}
|
||||
return Run(ctx, argv, RunOptions{OnLine: onLine})
|
||||
return "flatpak update -y --noninteractive", nil
|
||||
}
|
||||
|
||||
func parseFlatpakUpdates(text string, installed map[string]flatpakInstalledEntry) []Package {
|
||||
|
||||
@@ -28,7 +28,6 @@ func (pacmanBackend) ID() string { return "pacman" }
|
||||
func (pacmanBackend) DisplayName() string { return "Pacman" }
|
||||
func (pacmanBackend) Repo() RepoKind { return RepoSystem }
|
||||
func (pacmanBackend) NeedsAuth() bool { return true }
|
||||
func (pacmanBackend) RunsInTerminal() bool { return false }
|
||||
func (pacmanBackend) IsAvailable(_ context.Context) bool { return commandExists("pacman") }
|
||||
|
||||
func (b pacmanBackend) CheckUpdates(ctx context.Context) ([]Package, error) {
|
||||
@@ -39,11 +38,11 @@ func (b pacmanBackend) CheckUpdates(ctx context.Context) ([]Package, error) {
|
||||
return parseArchUpdates(out, b.ID(), RepoSystem), nil
|
||||
}
|
||||
|
||||
func (b pacmanBackend) Upgrade(ctx context.Context, opts UpgradeOptions, onLine func(string)) error {
|
||||
func (pacmanBackend) UpgradeCommand(opts UpgradeOptions) (string, error) {
|
||||
if opts.DryRun {
|
||||
return Run(ctx, []string{"pacman", "-Sup"}, RunOptions{OnLine: onLine})
|
||||
return "pacman -Sup", nil
|
||||
}
|
||||
return Run(ctx, []string{"pkexec", "pacman", "-Syu", "--noconfirm"}, RunOptions{OnLine: onLine})
|
||||
return "sudo pacman -Syu --noconfirm", nil
|
||||
}
|
||||
|
||||
type archHelperBackend struct {
|
||||
@@ -53,7 +52,6 @@ type archHelperBackend struct {
|
||||
func (b archHelperBackend) ID() string { return b.id }
|
||||
func (b archHelperBackend) Repo() RepoKind { return RepoSystem }
|
||||
func (b archHelperBackend) NeedsAuth() bool { return true }
|
||||
func (b archHelperBackend) RunsInTerminal() bool { return true }
|
||||
func (b archHelperBackend) IsAvailable(_ context.Context) bool { return commandExists(b.id) }
|
||||
|
||||
func (b archHelperBackend) DisplayName() string {
|
||||
@@ -82,20 +80,15 @@ func (b archHelperBackend) CheckUpdates(ctx context.Context) ([]Package, error)
|
||||
return pkgs, nil
|
||||
}
|
||||
|
||||
func (b archHelperBackend) Upgrade(ctx context.Context, opts UpgradeOptions, onLine func(string)) error {
|
||||
func (b archHelperBackend) UpgradeCommand(opts UpgradeOptions) (string, error) {
|
||||
if opts.DryRun {
|
||||
return Run(ctx, []string{b.id, "-Sup"}, RunOptions{OnLine: onLine})
|
||||
return fmt.Sprintf("%s -Sup", b.id), nil
|
||||
}
|
||||
term := findTerminal(opts.Terminal)
|
||||
if term == "" {
|
||||
return fmt.Errorf("no terminal found (pick one in DMS settings, set $TERMINAL, or install kitty/ghostty/foot/alacritty)")
|
||||
}
|
||||
cmd := fmt.Sprintf("%s -Syu", b.id)
|
||||
cmd := fmt.Sprintf("%s -Syu --noconfirm", b.id)
|
||||
if !opts.IncludeAUR {
|
||||
cmd += " --repo"
|
||||
}
|
||||
title := fmt.Sprintf("DMS — System Update (%s)", b.id)
|
||||
return Run(ctx, wrapInTerminal(term, title, cmd), RunOptions{OnLine: onLine})
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
func pacmanRepoUpdates(ctx context.Context) (string, error) {
|
||||
|
||||
@@ -15,11 +15,10 @@ func init() {
|
||||
|
||||
type rpmOstreeBackend struct{}
|
||||
|
||||
func (rpmOstreeBackend) ID() string { return "rpm-ostree" }
|
||||
func (rpmOstreeBackend) DisplayName() string { return "rpm-ostree" }
|
||||
func (rpmOstreeBackend) Repo() RepoKind { return RepoOSTree }
|
||||
func (rpmOstreeBackend) NeedsAuth() bool { return true }
|
||||
func (rpmOstreeBackend) RunsInTerminal() bool { return false }
|
||||
func (rpmOstreeBackend) ID() string { return "rpm-ostree" }
|
||||
func (rpmOstreeBackend) DisplayName() string { return "rpm-ostree" }
|
||||
func (rpmOstreeBackend) Repo() RepoKind { return RepoOSTree }
|
||||
func (rpmOstreeBackend) NeedsAuth() bool { return true }
|
||||
|
||||
func (b rpmOstreeBackend) IsAvailable(ctx context.Context) bool {
|
||||
if !commandExists("rpm-ostree") {
|
||||
@@ -116,10 +115,9 @@ func bootedDeployment(deps []ostreeDeployment) *ostreeDeployment {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (rpmOstreeBackend) Upgrade(ctx context.Context, opts UpgradeOptions, onLine func(string)) error {
|
||||
argv := []string{"rpm-ostree", "upgrade"}
|
||||
func (rpmOstreeBackend) UpgradeCommand(opts UpgradeOptions) (string, error) {
|
||||
if opts.DryRun {
|
||||
argv = append(argv, "--check")
|
||||
return "rpm-ostree upgrade --check", nil
|
||||
}
|
||||
return Run(ctx, argv, RunOptions{OnLine: onLine})
|
||||
return "rpm-ostree upgrade", nil
|
||||
}
|
||||
|
||||
@@ -17,7 +17,6 @@ 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 {
|
||||
@@ -70,9 +69,9 @@ func parseZypperXML(out []byte) ([]Package, error) {
|
||||
return pkgs, nil
|
||||
}
|
||||
|
||||
func (zypperBackend) Upgrade(ctx context.Context, opts UpgradeOptions, onLine func(string)) error {
|
||||
func (zypperBackend) UpgradeCommand(opts UpgradeOptions) (string, error) {
|
||||
if opts.DryRun {
|
||||
return Run(ctx, []string{"zypper", "--non-interactive", "--dry-run", "update"}, RunOptions{OnLine: onLine})
|
||||
return "zypper --non-interactive --dry-run update", nil
|
||||
}
|
||||
return Run(ctx, []string{"pkexec", "zypper", "--non-interactive", "update"}, RunOptions{OnLine: onLine})
|
||||
return "sudo zypper --non-interactive update", nil
|
||||
}
|
||||
|
||||
@@ -1,63 +1,18 @@
|
||||
package sysupdate
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type RunOptions struct {
|
||||
Env []string
|
||||
OnLine func(string)
|
||||
}
|
||||
|
||||
func Run(ctx context.Context, argv []string, opts RunOptions) error {
|
||||
func Run(ctx context.Context, argv []string) error {
|
||||
if len(argv) == 0 {
|
||||
return fmt.Errorf("sysupdate.Run: empty argv")
|
||||
}
|
||||
|
||||
cmd := exec.CommandContext(ctx, argv[0], argv[1:]...)
|
||||
if len(opts.Env) > 0 {
|
||||
cmd.Env = append(cmd.Environ(), opts.Env...)
|
||||
}
|
||||
|
||||
stdout, err := cmd.StdoutPipe()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
stderr, err := cmd.StderrPipe()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := cmd.Start(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(2)
|
||||
go pump(stdout, opts.OnLine, &wg)
|
||||
go pump(stderr, opts.OnLine, &wg)
|
||||
wg.Wait()
|
||||
|
||||
return cmd.Wait()
|
||||
}
|
||||
|
||||
func pump(r io.Reader, onLine func(string), wg *sync.WaitGroup) {
|
||||
defer wg.Done()
|
||||
if onLine == nil {
|
||||
_, _ = io.Copy(io.Discard, r)
|
||||
return
|
||||
}
|
||||
scanner := bufio.NewScanner(r)
|
||||
scanner.Buffer(make([]byte, 64*1024), 1024*1024)
|
||||
for scanner.Scan() {
|
||||
onLine(scanner.Text())
|
||||
}
|
||||
return cmd.Run()
|
||||
}
|
||||
|
||||
func Capture(ctx context.Context, argv []string) (string, error) {
|
||||
|
||||
@@ -18,7 +18,6 @@ import (
|
||||
const (
|
||||
defaultIntervalSeconds = 30 * 60
|
||||
minIntervalSeconds = 5 * 60
|
||||
recentLogCapacity = 200
|
||||
checkTimeout = 5 * time.Minute
|
||||
upgradeTimeout = 30 * time.Minute
|
||||
)
|
||||
@@ -240,7 +239,6 @@ func (m *Manager) runRefresh(parent context.Context) {
|
||||
}
|
||||
m.state.Phase = PhaseRefreshing
|
||||
m.state.Error = nil
|
||||
m.state.RecentLog = nil
|
||||
m.mu.Unlock()
|
||||
m.markDirty()
|
||||
|
||||
@@ -298,57 +296,13 @@ func (m *Manager) runUpgrade(ctx context.Context, opts UpgradeOptions) {
|
||||
m.opMu.Unlock()
|
||||
}()
|
||||
|
||||
if opts.CustomCommand != "" {
|
||||
m.runCustomUpgrade(ctx, opts.CustomCommand, opts.Terminal)
|
||||
combined, err := buildBundledCommand(m.selection, opts)
|
||||
if err != nil {
|
||||
m.setError(ErrCodeNoBackend, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
backends := upgradeBackends(m.selection, opts)
|
||||
if len(backends) == 0 {
|
||||
m.setError(ErrCodeNoBackend, "no backend selected for upgrade")
|
||||
return
|
||||
}
|
||||
|
||||
opID := fmt.Sprintf("op-%d", time.Now().UnixNano())
|
||||
m.mu.Lock()
|
||||
m.state.Phase = PhaseUpgrading
|
||||
m.state.OperationID = opID
|
||||
m.state.OperationStarted = time.Now().Unix()
|
||||
m.state.RecentLog = m.state.RecentLog[:0]
|
||||
m.state.Error = nil
|
||||
m.mu.Unlock()
|
||||
m.markDirty()
|
||||
|
||||
onLine := func(line string) { m.appendLog(line) }
|
||||
for _, b := range backends {
|
||||
m.appendLog(fmt.Sprintf("== %s ==", b.DisplayName()))
|
||||
if err := b.Upgrade(ctx, opts, onLine); err != nil {
|
||||
code := ErrCodeBackendFailed
|
||||
if errors.Is(ctx.Err(), context.DeadlineExceeded) {
|
||||
code = ErrCodeTimeout
|
||||
} else if errors.Is(ctx.Err(), context.Canceled) {
|
||||
code = ErrCodeCancelled
|
||||
}
|
||||
m.mu.Lock()
|
||||
m.state.Phase = PhaseError
|
||||
m.state.Error = &ErrorInfo{Code: code, Message: fmt.Sprintf("%s: %v", b.ID(), err)}
|
||||
m.mu.Unlock()
|
||||
m.markDirty()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
m.mu.Lock()
|
||||
m.state.Phase = PhaseIdle
|
||||
m.state.OperationID = ""
|
||||
m.state.OperationStarted = 0
|
||||
m.mu.Unlock()
|
||||
m.markDirty()
|
||||
go m.runRefresh(context.Background())
|
||||
}
|
||||
|
||||
func (m *Manager) runCustomUpgrade(ctx context.Context, command, terminalOverride string) {
|
||||
term := findTerminal(terminalOverride)
|
||||
term := findTerminal(opts.Terminal)
|
||||
if term == "" {
|
||||
m.setError(ErrCodeBackendFailed, "no terminal found (pick one in DMS settings, set $TERMINAL, or install kitty/ghostty/foot/alacritty)")
|
||||
return
|
||||
@@ -359,14 +313,12 @@ func (m *Manager) runCustomUpgrade(ctx context.Context, command, terminalOverrid
|
||||
m.state.Phase = PhaseUpgrading
|
||||
m.state.OperationID = opID
|
||||
m.state.OperationStarted = time.Now().Unix()
|
||||
m.state.RecentLog = m.state.RecentLog[:0]
|
||||
m.state.Error = nil
|
||||
m.mu.Unlock()
|
||||
m.markDirty()
|
||||
|
||||
onLine := func(line string) { m.appendLog(line) }
|
||||
argv := wrapInTerminal(term, "DMS — System Update (custom)", command)
|
||||
if err := Run(ctx, argv, RunOptions{OnLine: onLine}); err != nil {
|
||||
argv := wrapInTerminal(term, "DMS — System Update", combined)
|
||||
if err := Run(ctx, argv); err != nil {
|
||||
code := ErrCodeBackendFailed
|
||||
switch {
|
||||
case errors.Is(ctx.Err(), context.DeadlineExceeded):
|
||||
@@ -391,6 +343,31 @@ func (m *Manager) runCustomUpgrade(ctx context.Context, command, terminalOverrid
|
||||
go m.runRefresh(context.Background())
|
||||
}
|
||||
|
||||
func buildBundledCommand(sel Selection, opts UpgradeOptions) (string, error) {
|
||||
if opts.CustomCommand != "" {
|
||||
return opts.CustomCommand, nil
|
||||
}
|
||||
backends := upgradeBackends(sel, opts)
|
||||
if len(backends) == 0 {
|
||||
return "", errors.New("no backend selected for upgrade")
|
||||
}
|
||||
parts := make([]string, 0, len(backends))
|
||||
for _, b := range backends {
|
||||
cmd, err := b.UpgradeCommand(opts)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("%s: %w", b.ID(), err)
|
||||
}
|
||||
if cmd == "" {
|
||||
continue
|
||||
}
|
||||
parts = append(parts, cmd)
|
||||
}
|
||||
if len(parts) == 0 {
|
||||
return "", errors.New("no backend produced an upgrade command")
|
||||
}
|
||||
return strings.Join(parts, " && "), nil
|
||||
}
|
||||
|
||||
func upgradeBackends(sel Selection, opts UpgradeOptions) []Backend {
|
||||
var out []Backend
|
||||
if sel.System != nil {
|
||||
@@ -406,20 +383,6 @@ func upgradeBackends(sel Selection, opts UpgradeOptions) []Backend {
|
||||
return out
|
||||
}
|
||||
|
||||
func (m *Manager) appendLog(line string) {
|
||||
m.mu.Lock()
|
||||
if cap(m.state.RecentLog) == 0 {
|
||||
m.state.RecentLog = make([]string, 0, recentLogCapacity)
|
||||
}
|
||||
if len(m.state.RecentLog) >= recentLogCapacity {
|
||||
copy(m.state.RecentLog, m.state.RecentLog[1:])
|
||||
m.state.RecentLog = m.state.RecentLog[:recentLogCapacity-1]
|
||||
}
|
||||
m.state.RecentLog = append(m.state.RecentLog, line)
|
||||
m.mu.Unlock()
|
||||
m.markDirty()
|
||||
}
|
||||
|
||||
func (m *Manager) setError(code ErrorCode, msg string) {
|
||||
m.mu.Lock()
|
||||
m.state.Phase = PhaseError
|
||||
@@ -458,7 +421,6 @@ func cloneState(s State) State {
|
||||
out := s
|
||||
out.Backends = append([]BackendInfo(nil), s.Backends...)
|
||||
out.Packages = append([]Package(nil), s.Packages...)
|
||||
out.RecentLog = append([]string(nil), s.RecentLog...)
|
||||
if s.Error != nil {
|
||||
errCopy := *s.Error
|
||||
out.Error = &errCopy
|
||||
|
||||
@@ -41,11 +41,10 @@ type Package struct {
|
||||
}
|
||||
|
||||
type BackendInfo struct {
|
||||
ID string `json:"id"`
|
||||
DisplayName string `json:"displayName"`
|
||||
Repo RepoKind `json:"repo"`
|
||||
NeedsAuth bool `json:"needsAuth"`
|
||||
RunsInTerminal bool `json:"runsInTerminal"`
|
||||
ID string `json:"id"`
|
||||
DisplayName string `json:"displayName"`
|
||||
Repo RepoKind `json:"repo"`
|
||||
NeedsAuth bool `json:"needsAuth"`
|
||||
}
|
||||
|
||||
type ErrorInfo struct {
|
||||
@@ -67,7 +66,6 @@ type State struct {
|
||||
NextCheckUnix int64 `json:"nextCheckUnix,omitempty"`
|
||||
OperationID string `json:"operationId,omitempty"`
|
||||
OperationStarted int64 `json:"operationStartedUnix,omitempty"`
|
||||
RecentLog []string `json:"recentLog,omitempty"`
|
||||
Error *ErrorInfo `json:"error,omitempty"`
|
||||
}
|
||||
|
||||
|
||||
@@ -57,8 +57,6 @@ DankPopout {
|
||||
color: "transparent"
|
||||
focus: true
|
||||
|
||||
readonly property bool hasTerminalBackend: (SystemUpdateService.backends || []).some(b => b.runsInTerminal === true)
|
||||
|
||||
Keys.onPressed: event => {
|
||||
if (event.key === Qt.Key_Escape) {
|
||||
systemUpdatePopout.close();
|
||||
@@ -208,13 +206,9 @@ DankPopout {
|
||||
includeAUR: SettingsData.updaterAllowAUR,
|
||||
terminal: SessionData.terminalOverride
|
||||
};
|
||||
if (updaterPanel.hasTerminalBackend) {
|
||||
systemUpdatePopout._reopenAfterUpgrade = true;
|
||||
SystemUpdateService.runUpdates(opts);
|
||||
systemUpdatePopout.close();
|
||||
return;
|
||||
}
|
||||
systemUpdatePopout._reopenAfterUpgrade = true;
|
||||
SystemUpdateService.runUpdates(opts);
|
||||
systemUpdatePopout.close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -383,7 +377,7 @@ DankPopout {
|
||||
anchors.fill: parent
|
||||
anchors.margins: Theme.spacingM
|
||||
spacing: Theme.spacingS
|
||||
visible: SystemUpdateService.isUpgrading && updaterPanel.hasTerminalBackend
|
||||
visible: SystemUpdateService.isUpgrading
|
||||
|
||||
DankIcon {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
@@ -403,38 +397,13 @@ DankPopout {
|
||||
|
||||
StyledText {
|
||||
width: parent.width
|
||||
text: I18n.tr("AUR helpers are interactive — see the terminal window for prompts. This popout will return to idle when the upgrade exits.")
|
||||
text: I18n.tr("See the terminal window for prompts. This popout will return when the upgrade exits.")
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Theme.surfaceVariantText
|
||||
wrapMode: Text.WordWrap
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
}
|
||||
}
|
||||
|
||||
DankFlickable {
|
||||
anchors.fill: parent
|
||||
anchors.margins: Theme.spacingM
|
||||
visible: SystemUpdateService.isUpgrading && !updaterPanel.hasTerminalBackend
|
||||
contentWidth: width
|
||||
contentHeight: logText.implicitHeight
|
||||
clip: true
|
||||
|
||||
onContentHeightChanged: {
|
||||
if (contentHeight > height) {
|
||||
contentY = contentHeight - height;
|
||||
}
|
||||
}
|
||||
|
||||
StyledText {
|
||||
id: logText
|
||||
width: parent.width
|
||||
text: (SystemUpdateService.recentLog || []).join("\n")
|
||||
font.family: Theme.monoFontFamily || "monospace"
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Theme.surfaceText
|
||||
wrapMode: Text.NoWrap
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@ Rectangle {
|
||||
property string iconName: ""
|
||||
property string text: ""
|
||||
property bool isDestructive: false
|
||||
property bool enabled: true
|
||||
|
||||
signal triggered
|
||||
|
||||
|
||||
@@ -24,7 +24,6 @@ Singleton {
|
||||
property string distributionPretty: ""
|
||||
property string pkgManager: ""
|
||||
property bool distributionSupported: false
|
||||
property var recentLog: []
|
||||
property int intervalSeconds: 1800
|
||||
property int lastCheckUnix: 0
|
||||
property int nextCheckUnix: 0
|
||||
@@ -89,7 +88,6 @@ Singleton {
|
||||
distribution = data.distro || "";
|
||||
distributionPretty = data.distroPretty || "";
|
||||
distributionSupported = (backends.length > 0);
|
||||
recentLog = data.recentLog || [];
|
||||
intervalSeconds = data.intervalSeconds || 1800;
|
||||
lastCheckUnix = data.lastCheckUnix || 0;
|
||||
nextCheckUnix = data.nextCheckUnix || 0;
|
||||
|
||||
Reference in New Issue
Block a user