feat(uninstall): add --list flag to surface installed apps and uninstall names#755
Conversation
Implements `mo list` command to display installed applications with their uninstall names, supporting JSON/text output formats and filtering by source (user/system/homebrew/setapp) or size. Helps users find correct names for `mo uninstall`.
|
Hey, I’m not sure if you’re accepting PRs—I couldn’t find any contributing guidelines—but I needed a mole list command to list all the applications installed on my Mac so I can uninstall them easily. If you find this useful, feel free to improve the implementation. And if it meets your standards, I’d appreciate it if you could merge it. I’ve added some tests and manually verified all commands to make sure nothing breaks. I’ll be using this on my own machine as well. Hope you like it. PS. |
…flag Original PR added a new top-level 'mo list' command. Per maintainer feedback, fold the same capability into 'mo uninstall --list' to avoid adding new top-level surface area. Reuses scan_applications() so the listing stays in lockstep with the destructive path; cask resolution still goes through get_brew_cask_name(). Auto-emits JSON when stdout is piped (matches 'mo status' precedent).
|
@rafay99-epic thanks for the thorough work on this, the code is clean, the bats coverage is solid, and the "give users the exact name to pass to I want to keep top-level commands tight, so I pushed a follow-up commit folding the capability into Merging this in. Will ship in the next release, you can run |
|
@tw93, that’s a better approach. Why didn’t I think of that? Thanks for merging the PR. I’ll switch to the nightly version as well. Thanks again! |
Co-developed with @rafay99-epic. Surfaces each installed app with the exact name 'mo uninstall' accepts (Homebrew cask token when brew-managed, display name otherwise). Auto-JSON when stdout is piped.
Summary
mo list, a read-only command that enumerates installed applications from the project's documented installed-app sources (/Applications,/System/Applications,~/Applications,/Applications/Setapp).mo uninstallwill accept: the Homebrew cask token (resolved via the existingget_brew_cask_nameinlib/uninstall/brew.sh) for brew-managed apps, and the display name (resolved viaplutilagainstCFBundleDisplayName→CFBundleName→ basename) for everything else.mo statusprecedent).lib/core/help.sh::show_list_help()per project convention. Registry entry added tolib/core/commands.shsomo --helpand shell completion pick it up automatically. Dispatcher arm added inmole.Motivation: users running
mo uninstall <name>don't always know whether to pass the display name (e.g.Visual Studio Code) or the Homebrew cask token (visual-studio-code).mo listsurfaces both side-by-side so the output can be grepped directly intomo uninstall <UNINSTALL NAME>.New commands & flags
One new top-level subcommand,
mo list, with the following flags:mo listNAME · BUNDLE ID · SOURCE · UNINSTALL NAME · SIZEmo list --jsonmo list --source <all|user|system|homebrew|setapp>all)mo list --brew-only--source homebrewmo list --sort <name|size>name;sizeis descending)mo list --debugMO_DEBUG)mo list -h,mo list --helpNo flag is destructive; nothing requires sudo. The command produces no side effects beyond reads from
/Applications*,~/Applications, appInfo.plistfiles, and (when Homebrew is available)brew list --cask.Example workflow
Safety Review
rm, nosudo, no path validation surface, no symlink writes, no destructive boundaries.lib/uninstall/brew.sh::get_brew_cask_nameso the surfaced "uninstall name" is exactly whatmo uninstallalready accepts; no parallel resolver logic was introduced.Tests
tests/list.batswith 12 cases:--helpand-hprint usage and exit 0modispatcher routeslisttobin/list.sh--sortand--sourcevalues--jsonemits a valid JSON array--brew-onlyrestricts source to Homebrew--sort sizeproduces non-increasing sizes./scripts/check.sh: all 6 stages pass (shfmt, gofmt, go vet, shellcheck, syntax check, optimization checks 5/5)bats tests/list.bats: 12/12cli,regression,scripts,completion): no regressions introduced (one pre-existing perf flake inregression.bats:253that fails on cleanmaintoo)SC2054was suppressed inline with an explanatory comment because-k1,1/-k1,1nrare legitimatesort(1)field specifiers, not multi-element array entries.Safety-related changes