mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-04-30 01:22:06 -04:00
97 lines
1.9 KiB
Go
97 lines
1.9 KiB
Go
package sysupdate
|
|
|
|
import (
|
|
"context"
|
|
"os/exec"
|
|
"sync"
|
|
)
|
|
|
|
type Backend interface {
|
|
ID() string
|
|
DisplayName() string
|
|
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
|
|
}
|
|
|
|
type Selection struct {
|
|
System Backend
|
|
Overlay []Backend
|
|
}
|
|
|
|
func (s Selection) All() []Backend {
|
|
if s.System == nil {
|
|
return s.Overlay
|
|
}
|
|
out := make([]Backend, 0, 1+len(s.Overlay))
|
|
out = append(out, s.System)
|
|
out = append(out, s.Overlay...)
|
|
return out
|
|
}
|
|
|
|
func (s Selection) Info() []BackendInfo {
|
|
all := s.All()
|
|
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(),
|
|
})
|
|
}
|
|
return out
|
|
}
|
|
|
|
var (
|
|
registryMu sync.RWMutex
|
|
systemCandidates []func() Backend
|
|
overlayCandidate []func() Backend
|
|
)
|
|
|
|
func RegisterSystemBackend(factory func() Backend) {
|
|
registryMu.Lock()
|
|
defer registryMu.Unlock()
|
|
systemCandidates = append(systemCandidates, factory)
|
|
}
|
|
|
|
func RegisterOverlayBackend(factory func() Backend) {
|
|
registryMu.Lock()
|
|
defer registryMu.Unlock()
|
|
overlayCandidate = append(overlayCandidate, factory)
|
|
}
|
|
|
|
func Select(ctx context.Context) Selection {
|
|
registryMu.RLock()
|
|
sys := append([]func() Backend(nil), systemCandidates...)
|
|
ov := append([]func() Backend(nil), overlayCandidate...)
|
|
registryMu.RUnlock()
|
|
|
|
var sel Selection
|
|
for _, factory := range sys {
|
|
b := factory()
|
|
if !b.IsAvailable(ctx) {
|
|
continue
|
|
}
|
|
sel.System = b
|
|
break
|
|
}
|
|
for _, factory := range ov {
|
|
b := factory()
|
|
if !b.IsAvailable(ctx) {
|
|
continue
|
|
}
|
|
sel.Overlay = append(sel.Overlay, b)
|
|
}
|
|
return sel
|
|
}
|
|
|
|
func commandExists(name string) bool {
|
|
_, err := exec.LookPath(name)
|
|
return err == nil
|
|
}
|