Skip to content

List the built-in Homebrew sources and use tap names to add and remove sources - #5433

Open
awss (awss1i) wants to merge 1 commit into
Devolutions:mainfrom
awss1i:fix/homebrew-sources-by-tap
Open

awss (awss1i) wants to merge 1 commit into
Devolutions:mainfrom
awss1i:fix/homebrew-sources-by-tap

Conversation

@awss1i

Copy link
Copy Markdown
  • I have read the contributing guidelines, and I agree with the Code of Conduct.
  • Have you checked that there aren't other open pull requests for the same changes?
  • Have you tested that the committed code can be executed without errors?
  • Have you confirmed that this issue is caused by UniGetUI itself, and not by the package manager or the package involved?

On Linux (and on any Homebrew 4+ install), the Homebrew sources page is empty, "Homebrew" shows as not configured, and adding it fails with Error: Invalid tap name: 'Homebrew', as Ed Kolis (@ekolis) reported in #5219. This PR lists the built-in sources that Homebrew serves without a tap and passes brew the tap names it expects.

This covers the sources part of #5219 only. The headline, installed Homebrew packages missing under Distrobox, did not reproduce here with the reporter's steps (details below), so this PR does not claim to fix it and uses Relates to.

Why it happened

  • HomebrewSourceHelper.GetSources_UnSafe only parses brew tap. Since Homebrew 4, homebrew/core and homebrew/cask come from the JSON API and are not tapped, so brew tap prints nothing on a normal install and the list was empty.
  • GetAddSourceParameters / GetRemoveSourceParameters pass source.Name as the tap. The known sources are named "Homebrew" and "Homebrew Cask", which brew never accepts as tap names.
  • "Homebrew Cask" was a known source on Linux, where Homebrew has no casks.

What changed

  • HomebrewSourceHelper:
    • The source list starts with the manager's known sources (the same objects, so the IPC merge by name and URL marks them configured), then every other brew tap line; homebrew/core and homebrew/cask lines are skipped so a developer who tapped them does not see duplicates. The list building moved into BuildSourceList so it can be tested without brew; the URL guess for other taps is the existing code, moved.
    • GetTapName maps "Homebrew" to homebrew/core and "Homebrew Cask" to homebrew/cask; add runs tap <tap> for those and tap <name> <url> for any other source as before; remove runs untap <tap>.
  • Homebrew.cs: KnownSources comes from CreateBuiltInSources(this, OperatingSystem.IsMacOS()): "Homebrew" everywhere, "Homebrew Cask" on macOS only. DefaultSource is unchanged.
  • Unchanged: the source names (so HomebrewPkgOperationHelper's --cask decision and the installed/updates source lookups behave as before), HomebrewPkgOperationHelper.cs, HomebrewPkgDetailsHelper.cs, and the listing/update parsing.

Verification

Fedora 44 host, a Fedora 44 distrobox (the reporter's setup) with Homebrew 7.0.6 and hello, jq installed. Debug builds of main (d0d5165) and this branch, run --headless inside the box and queried with the same binary. The brew calls in the table were recorded by a pass-through brew script placed first on PATH, which the app picked as its brew.

Step main this branch
source list --manager homebrew (brew tap prints nothing) Homebrew: known, not configured; Homebrew Cask: known, not configured Homebrew: known, configured; no Homebrew Cask on Linux
source add --name Homebrew --url https://github.com/Homebrew/homebrew-core runs brew tap Homebrew https://github.com/Homebrew/homebrew-core: exit 1, Error: Invalid tap name: 'Homebrew' runs brew tap homebrew/core: exit 1, Error: Tapping homebrew/core is no longer typically necessary. (see the question below)
source add --name hashicorp/tap --url https://github.com/hashicorp/homebrew-tap brew tap hashicorp/tap <url>, exit 0 identical
source list after that hashicorp/tap configured; Homebrew and Homebrew Cask not configured hashicorp/tap configured; Homebrew configured
source remove --name hashicorp/tap brew untap hashicorp/tap, exit 0 identical
package installed --manager homebrew hello, jq, oniguruma hello, jq, oniguruma
  • brew by hand in the same box: brew tap homebrew/core and brew tap homebrew/cask exit 1 without --force, brew untap homebrew/core exits 1 ("No available tap"), and brew tap lists neither, which is why the built-ins are listed as present rather than added.
  • Tests: UniGetUI.PackageEngine.Tests 1255 to 1261 passed (6 new in HomebrewManagerTests: 3 facts on the source list and the platform split, a 3-row Theory on add/remove parameters); the 30 failures on Linux are the same pre-existing Windows-only ones on main and here, compared by name. 5 consecutive runs of HomebrewManagerTests, 7/7 each.
  • Planted failures, one at a time: not listing the built-ins fails 2 tests; not skipping the homebrew/core line fails 1; dropping the tap-name mapping fails the Homebrew and Homebrew Cask rows; offering casks on Linux fails 1. Each revert restored the files byte for byte (sha256 compared).
  • Fresh clone of this repo at d0d5165 with the change applied and an empty NuGet cache: restore and dotnet test give the same 1261 / 30.
  • Gates: dotnet format whitespace src --folder --verify-no-changes and dotnet format style UniGetUI.Avalonia.slnx --no-restore --verify-no-changes clean.
  • Not run: macOS (I have no Mac; the macOS list is covered by CreateBuiltInSources(isMacOS: true) only), and the Sources page in the GUI (synthetic input does not reach the window on my Wayland session; the CLI reads the same GetSources the page uses).

The headline of #5219 did not reproduce

Following the reporter's 8 steps on a Fedora 44 host (not Bazzite) with a Fedora 44 distrobox, the UniGetUI rpm inside, Homebrew inside, the app exported and started with distrobox-enter -n fedora-box -- /opt/unigetui/UniGetUI:

Version in the box package installed --manager homebrew (headless) GUI, Installed page
2026.3.0 success: hello, jq, oniguruma (0.6 s) 343 packages across Dnf, Flatpak and Homebrew; Homebrew in the Sources panel
2026.2.6 (the reporter's) success: hello, jq, oniguruma (0.7 s) same

brew list --formula --versions returns in under a second, far from the 60 s listing timeout. What differs from the report and I could not test: Bazzite as the host (as far as I know it can ship Homebrew on the host under /home/linuxbrew, which a box would share with a container-local install) and a first-run brew. Ed Kolis (@ekolis), if you can run brew list --formula --versions inside the box and share the output of unigetui log manager --manager homebrew --verbose from the same box, that would show which of the two it is.

A question for review

Adding the built-in "Homebrew" source by hand still reports "failed", now with brew's own reason, because brew refuses to tap homebrew/core without --force. Since the source is now always listed as configured, I left it as an honest failure. The alternative is to treat adding a built-in as a success without calling brew; happy to switch if you prefer that.

Review guide

  • HomebrewSourceHelper.cs: GetSources_UnSafe now only collects lines; BuildSourceList holds the old loop body unchanged apart from the two-line skip, plus the known sources up front. GetTapName and the two parameter methods are the rest.
  • Homebrew.cs: the KnownSources initializer became CreateBuiltInSources.
  • HomebrewManagerTests.cs: 4 new tests after the existing one.

Not in this PR

  • The installed-list symptom of [BUG] Previously installed Homebrew packages are not shown when running via Distrobox #5219 (not reproduced, see above).
  • The Add source dropdown offers every known source even when it is already configured; that is shared by all managers (SourceManagerCardViewModel).
  • Seen while reproducing: the rpm declares libfontconfig but not libicu, so on a fresh Fedora box the binary stops with "Couldn't find a valid ICU package installed on the system" until dnf install libicu. Happy to open an issue for it.

Relates to #5219

…e sources

Homebrew 4 and later serve homebrew/core and homebrew/cask from the API
without a tap, so `brew tap` prints nothing for them and the sources
page listed nothing: the default "Homebrew" source showed as not
configured. Adding it ran `brew tap Homebrew <url>`, which brew rejects
with "Invalid tap name: 'Homebrew'"; removing ran `brew untap Homebrew`.

The source list now always starts with the built-in sources (the same
known-source objects, so they count as configured) and adds every other
tap from `brew tap`, skipping homebrew/core and homebrew/cask lines.
"Homebrew Cask" is a known source on macOS only, since Homebrew on Linux
has no casks. Add and remove map "Homebrew" and "Homebrew Cask" to
homebrew/core and homebrew/cask; other sources are already named after
their tap and keep the URL argument. The source names are unchanged, so
the --cask decision and the installed-package sources are unaffected.

Relates to Devolutions#5219

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant