Files
DankMaterialShell/core/internal/server/sysupdate/backend_pkg.go
T
Zer0TraceXandclaude[bot] 87a4da9e13 feat(freebsd): Add initial native FreeBSD support (#3559)
* feat(freebsd): add comprehensive native FreeBSD support

* Update BatteryService.qml

* Add battery probe completion and fallback updates

* Add isVideoSource function and update PwObjectTracker filter

* Add isPipewireVideoSource function to AudioService

Added a function to check if a Pipewire node is a video source.

* Refactor video source check to use AudioService

* Remove unnecessary call in BatteryService.qml

* Add call to updateFreeBsdBatteryFallback on completion

* Simplify AudioService by eliminating redundant bindings

Removed unnecessary bindings in the AudioService loader to streamline the loading process.

* Improve error handling in CheckUpdates function

Handle specific exit error for package upgrade check.

* Enhance FreeBSD network detection logic

* Implement FreeBSD Wi-Fi hardware discovery in Initialize

Added FreeBSD Wi-Fi hardware discovery and updated initialization logic to handle cases where no wpa_supplicant control socket is found.

* Implement Ethernet state monitoring in StartMonitoring

Added monitoring for Ethernet state updates in StartMonitoring function.

* Add Ethernet management functions to backend

* Remove unimplemented Ethernet control methods

Removed unimplemented Ethernet control methods from WpaSupplicantBackend.

* Implement SetWiFiEnabled method for WiFi control

Add error handling and state management for WiFi control

* Update core/internal/server/network/backend_wpa_ethernet.go

Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com>

* Implement Ethernet monitoring in WpaSupplicantBackend

* Refactor startEthernetMonitor and add debounce logic

Refactor the startEthernetMonitor function to improve readability and maintainability. Introduce a debounce mechanism for processing relevant FreeBSD route events.

* Reorder import statements in backend_pkg.go

* Remove unnecessary blank line in backend_wpa_ethernet.go

* Implement FreeBSD audio polling based on UI visibility

Introduce a polling mechanism for FreeBSD audio device updates based on visibility of UI elements.

* Add readonly freeBsdPollingRequested property and optimize polling

Introduce a readonly property to determine if FreeBSD polling is requested based on various UI conditions. Update command execution to prioritize polling efficiency.

* Simplify freeBsdPollingRequested logic

Removed unnecessary conditions from freeBsdPollingRequested property.

* Implement reference counting for battery consumers

Added reference counting to manage battery information consumers and updated related functions for better battery state handling.

---------

Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com>
2026-10-05 22:03:32 -04:00

94 lines
2.7 KiB
Go

package sysupdate
import (
"context"
"errors"
"os/exec"
"regexp"
"strings"
)
func init() {
// FreeBSD's pkg(8) is the native binary package manager. Register it after
// the Linux backends; IsAvailable keeps this harmless on other systems.
RegisterSystemBackend(func() Backend { return &pkgBackend{} })
}
type pkgBackend struct{}
func (pkgBackend) ID() string { return "pkg" }
func (pkgBackend) DisplayName() string { return "FreeBSD pkg" }
func (pkgBackend) Repo() RepoKind { return RepoSystem }
func (pkgBackend) NeedsAuth() bool { return true }
func (pkgBackend) RunsInTerminal() bool { return false }
func (pkgBackend) IsAvailable(_ context.Context) bool { return commandExists("pkg") }
// pkg upgrade -n prints upgrade rows like:
//
// nano: 8.6 -> 8.7 [FreeBSD]
//
// Keep the parser deliberately tolerant of repository names and whitespace.
var pkgUpgradeLine = regexp.MustCompile(`^\s*([^:\s][^:]*):\s+(\S+)\s+->\s+(\S+)(?:\s+\[[^]]+\])?\s*$`)
func (pkgBackend) CheckUpdates(ctx context.Context) ([]Package, error) {
out, err := Capture(ctx, []string{"pkg", "upgrade", "-n", "-q"})
if err != nil {
exitErr, ok := errors.AsType[*exec.ExitError](err)
if !ok || exitErr.ExitCode() != 1 {
return nil, err
}
}
return parsePkgUpgradeDryRun(out), nil
}
func parsePkgUpgradeDryRun(text string) []Package {
var pkgs []Package
seen := make(map[string]bool)
for _, raw := range strings.Split(text, "\n") {
m := pkgUpgradeLine.FindStringSubmatch(raw)
if m == nil {
continue
}
name := strings.TrimSpace(m[1])
if name == "" || seen[name] {
continue
}
seen[name] = true
pkgs = append(pkgs, Package{
Name: name,
Repo: RepoSystem,
Backend: "pkg",
FromVersion: m[2],
ToVersion: m[3],
})
}
return pkgs
}
func (pkgBackend) Upgrade(ctx context.Context, opts UpgradeOptions, onLine func(string)) error {
if !BackendHasTargets(pkgBackend{}, opts.Targets, opts.IncludeAUR, opts.IncludeFlatpak) {
return nil
}
if opts.DryRun {
return Run(ctx, []string{"pkg", "upgrade", "-n"}, RunOptions{OnLine: onLine})
}
// pkg upgrade accepts package names, so preserve the UI selection and any
// ignored packages instead of forcing an all-packages upgrade.
ignored := make(map[string]bool, len(opts.Ignored))
for _, name := range opts.Ignored {
ignored[name] = true
}
argv := []string{"pkg", "upgrade", "-y"}
for _, p := range opts.Targets {
if p.Backend != "pkg" || ignored[p.Name] || !safePkgName.MatchString(p.Name) {
continue
}
argv = append(argv, p.Name)
}
if len(argv) == 3 {
return nil
}
return Run(ctx, privilegedArgv(opts, argv...), RunOptions{OnLine: onLine, AttachStdio: opts.AttachStdio})
}