feat(updater): disable self-update for pacman/AUR installs
- commit
- 283a119221c745792194d455ce3d139040d541bc
- author
- bnema · · 2025-12-30 21:25 UTC
- parent
- 15e7c83
- signature
- GPG Verified
CD88F9E564E0102646FB6077A1A07C7C7C3E349D· arch-gpg Verified for the committer email
3 files · +34 -1
M CHANGELOG.md +1 -0
| @@ -10,6 +10,7 @@ All notable changes to this project will be documented in this file. | |||
| 10 | 10 | - `dumber-browser-git`: Build from source, tracks latest git. | |
| 11 | 11 | - Install with `yay -S dumber-browser-bin` or `paru -S dumber-browser-bin`. | |
| 12 | 12 | - Automatic AUR updates via GitHub Actions (1 hour delay after Flatpak build for safety). | |
| 13 | + | - **Pacman/AUR install detection**: Self-updater is disabled when installed via pacman/AUR (uses `pacman -Qo` to detect package ownership). | |
| 13 | 14 | ||
| 14 | 15 | ### Changed | |
| 15 | 16 | ||
| @@ -10,6 +10,7 @@ All notable changes to this project will be documented in this file. | |||||
| 10 | - `dumber-browser-git`: Build from source, tracks latest git. | 10 | - `dumber-browser-git`: Build from source, tracks latest git. | ||
| 11 | - Install with `yay -S dumber-browser-bin` or `paru -S dumber-browser-bin`. | 11 | - Install with `yay -S dumber-browser-bin` or `paru -S dumber-browser-bin`. | ||
| 12 | - Automatic AUR updates via GitHub Actions (1 hour delay after Flatpak build for safety). | 12 | - Automatic AUR updates via GitHub Actions (1 hour delay after Flatpak build for safety). | ||
| 13 | + | - **Pacman/AUR install detection**: Self-updater is disabled when installed via pacman/AUR (uses `pacman -Qo` to detect package ownership). | |||
| 13 | 14 | ||||
| 14 | ### Changed | 15 | ### Changed | ||
| 15 | 16 | ||||
M internal/infrastructure/env/manager.go +25 -0
| @@ -5,6 +5,7 @@ import ( | |||
| 5 | 5 | "context" | |
| 6 | 6 | "fmt" | |
| 7 | 7 | "os" | |
| 8 | + | "os/exec" | |
| 8 | 9 | "path/filepath" | |
| 9 | 10 | "strings" | |
| 10 | 11 | ||
| @@ -20,6 +21,30 @@ func IsFlatpak() bool { | |||
| 20 | 21 | return err == nil | |
| 21 | 22 | } | |
| 22 | 23 | ||
| 24 | + | // IsPacman returns true if the application was installed via pacman (including AUR). | |
| 25 | + | // Packages managed by pacman should not self-update; use pacman/AUR helpers instead. | |
| 26 | + | // Detection uses `pacman -Qo` to check if the binary is owned by a package. | |
| 27 | + | func IsPacman() bool { | |
| 28 | + | exe, err := os.Executable() | |
| 29 | + | if err != nil { | |
| 30 | + | return false | |
| 31 | + | } | |
| 32 | + | resolved, err := filepath.EvalSymlinks(exe) | |
| 33 | + | if err != nil { | |
| 34 | + | return false | |
| 35 | + | } | |
| 36 | + | ||
| 37 | + | // Check if pacman exists and if it owns this binary | |
| 38 | + | pacman, err := exec.LookPath("pacman") | |
| 39 | + | if err != nil { | |
| 40 | + | return false | |
| 41 | + | } | |
| 42 | + | ||
| 43 | + | // pacman -Qo returns 0 if the file is owned by a package | |
| 44 | + | cmd := exec.Command(pacman, "-Qo", resolved) | |
| 45 | + | return cmd.Run() == nil | |
| 46 | + | } | |
| 47 | + | ||
| 23 | 48 | // Manager implements port.RenderingEnvManager for configuring | |
| 24 | 49 | // environment variables for GStreamer, WebKit, and GTK/GSK. | |
| 25 | 50 | type Manager struct { | |
| @@ -5,6 +5,7 @@ import ( | |||||
| 5 | "context" | 5 | "context" | ||
| 6 | "fmt" | 6 | "fmt" | ||
| 7 | "os" | 7 | "os" | ||
| 8 | + | "os/exec" | |||
| 8 | "path/filepath" | 9 | "path/filepath" | ||
| 9 | "strings" | 10 | "strings" | ||
| 10 | 11 | ||||
| @@ -20,6 +21,30 @@ func IsFlatpak() bool { | |||||
| 20 | return err == nil | 21 | return err == nil | ||
| 21 | } | 22 | } | ||
| 22 | 23 | ||||
| 24 | + | // IsPacman returns true if the application was installed via pacman (including AUR). | |||
| 25 | + | // Packages managed by pacman should not self-update; use pacman/AUR helpers instead. | |||
| 26 | + | // Detection uses `pacman -Qo` to check if the binary is owned by a package. | |||
| 27 | + | func IsPacman() bool { | |||
| 28 | + | exe, err := os.Executable() | |||
| 29 | + | if err != nil { | |||
| 30 | + | return false | |||
| 31 | + | } | |||
| 32 | + | resolved, err := filepath.EvalSymlinks(exe) | |||
| 33 | + | if err != nil { | |||
| 34 | + | return false | |||
| 35 | + | } | |||
| 36 | + | ||||
| 37 | + | // Check if pacman exists and if it owns this binary | |||
| 38 | + | pacman, err := exec.LookPath("pacman") | |||
| 39 | + | if err != nil { | |||
| 40 | + | return false | |||
| 41 | + | } | |||
| 42 | + | ||||
| 43 | + | // pacman -Qo returns 0 if the file is owned by a package | |||
| 44 | + | cmd := exec.Command(pacman, "-Qo", resolved) | |||
| 45 | + | return cmd.Run() == nil | |||
| 46 | + | } | |||
| 47 | + | ||||
| 23 | // Manager implements port.RenderingEnvManager for configuring | 48 | // Manager implements port.RenderingEnvManager for configuring | ||
| 24 | // environment variables for GStreamer, WebKit, and GTK/GSK. | 49 | // environment variables for GStreamer, WebKit, and GTK/GSK. | ||
| 25 | type Manager struct { | 50 | type Manager struct { | ||
M internal/infrastructure/updater/applier.go +8 -1
| @@ -59,7 +59,8 @@ func (a *Applier) stagedBinaryPath() string { | |||
| 59 | 59 | } | |
| 60 | 60 | ||
| 61 | 61 | // CanSelfUpdate checks if the current binary is writable by the current user. | |
| 62 | - | // Returns false if running inside a Flatpak sandbox (updates handled by Flatpak). | |
| 62 | + | // Returns false if running inside a Flatpak sandbox (updates handled by Flatpak) | |
| 63 | + | // or if installed via pacman/AUR (updates handled by package manager). | |
| 63 | 64 | func (a *Applier) CanSelfUpdate(ctx context.Context) bool { | |
| 64 | 65 | log := logging.FromContext(ctx) | |
| 65 | 66 | ||
| @@ -69,6 +70,12 @@ func (a *Applier) CanSelfUpdate(ctx context.Context) bool { | |||
| 69 | 70 | return false | |
| 70 | 71 | } | |
| 71 | 72 | ||
| 73 | + | // Pacman/AUR packages should not self-update; use pacman or AUR helper. | |
| 74 | + | if env.IsPacman() { | |
| 75 | + | log.Debug().Msg("installed via pacman/AUR, self-update disabled") | |
| 76 | + | return false | |
| 77 | + | } | |
| 78 | + | ||
| 72 | 79 | binaryPath, err := a.GetBinaryPath() | |
| 73 | 80 | if err != nil { | |
| 74 | 81 | log.Debug().Err(err).Msg("failed to get binary path") | |
| @@ -59,7 +59,8 @@ func (a *Applier) stagedBinaryPath() string { | |||||
| 59 | } | 59 | } | ||
| 60 | 60 | ||||
| 61 | // CanSelfUpdate checks if the current binary is writable by the current user. | 61 | // CanSelfUpdate checks if the current binary is writable by the current user. | ||
| 62 | - | // Returns false if running inside a Flatpak sandbox (updates handled by Flatpak). | 62 | + | // Returns false if running inside a Flatpak sandbox (updates handled by Flatpak) |
| 63 | + | // or if installed via pacman/AUR (updates handled by package manager). | |||
| 63 | func (a *Applier) CanSelfUpdate(ctx context.Context) bool { | 64 | func (a *Applier) CanSelfUpdate(ctx context.Context) bool { | ||
| 64 | log := logging.FromContext(ctx) | 65 | log := logging.FromContext(ctx) | ||
| 65 | 66 | ||||
| @@ -69,6 +70,12 @@ func (a *Applier) CanSelfUpdate(ctx context.Context) bool { | |||||
| 69 | return false | 70 | return false | ||
| 70 | } | 71 | } | ||
| 71 | 72 | ||||
| 73 | + | // Pacman/AUR packages should not self-update; use pacman or AUR helper. | |||
| 74 | + | if env.IsPacman() { | |||
| 75 | + | log.Debug().Msg("installed via pacman/AUR, self-update disabled") | |||
| 76 | + | return false | |||
| 77 | + | } | |||
| 78 | + | ||||
| 72 | binaryPath, err := a.GetBinaryPath() | 79 | binaryPath, err := a.GetBinaryPath() | ||
| 73 | if err != nil { | 80 | if err != nil { | ||
| 74 | log.Debug().Err(err).Msg("failed to get binary path") | 81 | log.Debug().Err(err).Msg("failed to get binary path") | ||