Uninstall an application from a box - #211
Open
kacperpaczos wants to merge 4 commits into
Open
Conversation
Adds a pill 'Uninstall' button next to 'Run' on every row in the View Applications popup. The handler shells to a terminal running 'distrobox enter NAME -- sudo <pkg-manager> remove EXEC', so the user sees the sudo prompt and can confirm before the package is removed. The package manager is picked from the box's image (apt/dnf/zypper/ pacman/apk/xbps-install/emerge/installpkg) by pick_pkg_manager_for_ uninstall - a small heuristic that mirrors what Kontainer's packageinstallcommand.cpp does for install flows. The default is apt because apt fails loudly on non-apt distros instead of partially succeeding. Resolves 'Uninstall application from box' from the Roadmap. The .desktop export on the host is deliberately left alone - that is a separate, reversible 'Remove From Menu' action already available on the same row.
Uninstall passed the desktop file's Exec= value straight to the package manager as if it were a package name. The two rarely agree - gimp lives in gimp-2.10 - so the happy path mostly failed. Worse, the value was interpolated unquoted into a bash -c line, and a desktop file comes from the container image, not from the user: an Exec= with a semicolon in it would have run whatever it liked with the host's home mounted. The manager now gets asked who owns the binary (dpkg -S, rpm -qf or pacman -Qqo, after resolving the name through command -v with /usr/games widening the search, since desktop files may point outside the login PATH), with the bare executable name kept as the fallback guess. Everything that reaches the terminal command is shell-quoted, and the untrusted values travel to the resolution queries as positional parameters rather than shell text. Removal is also spelled per manager now - pacman takes -R, apk takes del, and slackware removes with removepkg despite installing with installpkg. The pure pieces - token splitting, quoting, ownership-output parsing and the removal table - come with unit tests.
kacperpaczos
force-pushed
the
feat/uninstall-app
branch
from
August 22, 2026 18:32
ab28818 to
54a12ff
Compare
master already knows how to tell a box's package manager from its image (utils::detect_pkg_manager), so the uninstall path now asks that instead of carrying its own copy of the table. The terminal spawn is shared with the .deb/.rpm install path too: run_install_in_terminal takes the manager's arguments as a slice, so install and remove go through the same argv-based call - which also means there is no shell line to quote any more, and the quoting helper and its test go away with it.
A non-login shell inside the box does not have /usr/games on its PATH, so command -v could not find a desktop file's binary there and the resolver fell back to the bare name. The lookup now adds the games directories for that one query.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #207
Adds an Uninstall button to the applications list — the bookend to Add To Menu, and one of the Needs External Help roadmap items.
The interesting part is picking what to remove. A desktop file's
Exec=is the binary, which usually isn't the package name (gimp → gimp-2.10), so the handler asks the box who owns the binary —dpkg -S,rpm -qforpacman -Qqo, after resolving the name throughcommand -vwith the games directories added since desktop files can point there (Debian's cowsay lives in/usr/games, which a non-login shell's PATH lacks) — and only falls back to the bare name if that fails. Removal is spelled per manager (pacman-R, apkdel, slackwareremovepkg).It reuses what master already has: the box's package manager comes from
utils::detect_pkg_manager(the same table the .deb/.rpm install paths use), and the terminal is opened through the install path's helper, now taking the manager's arguments as a slice — so install and remove share one argv-based spawn. Everything from the desktop file reaches the commands as separate arguments or positional parameters, never spliced into shell text.Testing
cowsay, ran the exact resolve queries the button issues (command -vfound/usr/games/cowsay,dpkg -Snamed the package), removed it with the samesudo apt remove <pkg>argv, and confirmed the binary was gone afterwards. An earlier revision of the same pipeline was also exercised on a Fedora box.