Skip to content

Brew info reports an incorrect formula URL from a tap #19294

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
3 tasks done
jasonkarns opened this issue Feb 12, 2025 · 11 comments · Fixed by #19295
Closed
3 tasks done

Brew info reports an incorrect formula URL from a tap #19294

jasonkarns opened this issue Feb 12, 2025 · 11 comments · Fixed by #19295
Labels
bug Reproducible Homebrew/brew bug stale No recent activity

Comments

@jasonkarns
Copy link
Contributor

brew doctor output

$ brew doctor
Your system is ready to brew.

Verification

  • My "brew doctor output" above says Your system is ready to brew. and am still able to reproduce my issue.
  • I ran brew update twice and am still able to reproduce my issue.
  • This issue's title and/or description do not reference a single formula e.g. brew install wget. If they do, open an issue at https://github.com/Homebrew/homebrew-core/issues/new/choose instead.

brew config output

HOMEBREW_VERSION: 4.4.20
ORIGIN: https://github.com/Homebrew/brew
HEAD: 47ef1a3b0b742a78be35c016df6a0279d6035ebb
Last commit: 9 days ago
Branch: stable
Core tap JSON: 12 Feb 17:09 UTC
Core cask tap JSON: 12 Feb 17:09 UTC
HOMEBREW_PREFIX: /opt/homebrew
HOMEBREW_BUNDLE_USER_CACHE: /Users/jason.karns/.cache/bundler
HOMEBREW_CASK_OPTS: []
HOMEBREW_EDITOR: vim
HOMEBREW_GITHUB_API_TOKEN: set
HOMEBREW_MAKE_JOBS: 12
HOMEBREW_SORBET_RUNTIME: set
HOMEBREW_UPDATE_TO_TAG: set
Homebrew Ruby: 3.3.7 => /opt/homebrew/Library/Homebrew/vendor/portable-ruby/3.3.7/bin/ruby
CPU: dodeca-core 64-bit arm_blizzard_avalanche
Clang: 16.0.0 build 1600
Git: 2.48.1 => /opt/homebrew/bin/git
Curl: 8.7.1 => /usr/bin/curl
macOS: 15.3-arm64
CLT: 16.2.0.0.1.1733547573
Xcode: 16.2
Rosetta 2: false

What were you trying to do (and why)?

I was trying to find the url for a formula that i have installed in order to share it with colleagues.

The utility I wanted to share was git-sync, but the one I have installed is from a tap, not core. There is a conflicting formula on core titled git-sync.

What happened (include all command output)?

I ran:

$ brew info git-sync
==> git-sync: stable 4.4.0 (bottled), HEAD
Clones a git repository and keeps it synchronized with the upstream
https://github.com/kubernetes/git-sync
Conflicts with:
  git-extras (because both install `git-sync` binaries)
Installed
/opt/homebrew/Cellar/git-sync/1.0.0 (7 files, 1.8MB) *
  Built from source on 2025-02-12 at 12:07:43
From: https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/g/git-sync.rb
License: Apache-2.0
==> Dependencies
Build: go ✘
Required: coreutils ✔
==> Options
--HEAD
	Install HEAD version
==> Analytics
install: 44 (30 days), 81 (90 days), 331 (365 days)
install-on-request: 44 (30 days), 82 (90 days), 331 (365 days)
build-error: 0 (30 days)

To get the formula URL. But I know this to be not the formula that I have installed. Despite brew info reporting that it is installed.

I eventually found the tap formula and was able to reproduce the bug whereby brew reports a formula as installed that is decidedly not installed.

What did you expect to happen?

I expected brew info git-sync to perhaps include a note that a conflicting formula (from a tap) is already installed. But at the very least, I expected brew info git-sync to tell me that it was not installed because the core formula is indeed not installed. In addition to it incorrectly stating it's installed, it even gives installation date/method that are from the tap's formula, not the core formula.

Step-by-step reproduction instructions (by running brew commands)

1. Ensure it's not installed: `brew rm git-sync`
2. Inspect that brew says it's not installed: `brew info git-sync`
3. Install from the tap: `brew install jacobwgillespie/tap/git-sync`
4. See that brew now incorrectly reports git-sync installed: `brew info git-sync`
@jasonkarns jasonkarns added the bug Reproducible Homebrew/brew bug label Feb 12, 2025
ZhongRuoyu added a commit that referenced this issue Feb 12, 2025
@jasonkarns
Copy link
Contributor Author

PR to fix this (#19295 ) was reverted by #19324 thus this issue exists again. Desired solution described #19295 (comment)

Would like to reopen this.

@MikeMcQuaid MikeMcQuaid changed the title Brew info reports a formula installed that is not installed Brew info reports an incorrect formula URL from a tap Mar 2, 2025
@MikeMcQuaid
Copy link
Member

From: https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/g/git-sync.rb

This is the only thing that should be changed/fixed in this output. Unless I'm mistaken, everything else is correct.

We shouldn't require brew info some/tap/git-sync to avoid errors here.

We could consider duplicating/including something the new brew doctor output to note it's available from multiple taps.

Copy link

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.

@github-actions github-actions bot added the stale No recent activity label Mar 24, 2025
@jasonkarns
Copy link
Contributor Author

This is the only thing that should be changed/fixed in this output. Unless I'm mistaken, everything else is correct.

Not quite. In addition to the From being incorrect, also the version, description, url, license, dependencies, and options are all incorrect. Though "incorrect" presumes that git info git-sync should prefer to print the data from the tap instead of core if there is a conflict. Do I assume that's the desired behavior? (I assume so from:

We shouldn't require brew info some/tap/git-sync to avoid errors here.

Here is my output from brew info git-sync, with each line decorated with core/tap denoting where I believe that line is coming from.

repo line
core ==> git-sync: stable 4.4.0 (bottled), HEAD
core Clones a git repository and keeps it synchronized with the upstream
core https://github.com/kubernetes/git-sync
core Conflicts with:
core git-extras (because both installgit-sync binaries)
tap Installed
tap /opt/homebrew/Cellar/git-sync/1.0.0 (7 files, 1.8MB) *
tap Built from source on 2025-02-12 at 12:07:43
core From: https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/g/git-sync.rb
core License: Apache-2.0
core ==> Dependencies
core Build: go ✘
core Required: coreutils ✔
core ==> Options
core --HEAD
core Install HEAD version
both? ==> Analytics
both? install: 4 (30 days), 58 (90 days), 296 (365 days)
both? install-on-request: 4 (30 days), 58 (90 days), 296 (365 days)
both? build-error: 0 (30 days)

With such a mix of lines, I can't tell what the expected behavior is supposed to be. But if brew info is going to show "Installed" (with all the installation info) when it's installed from a tap, then I don't believe it should be mixing the version, description, url, conflicts, formula-path, license, deps, and options from core. It should show the data from the tap.

Really it seems like this command needs to have the expected behavior in the conflicting-formula scenario thought through from scratch?

@github-actions github-actions bot removed the stale No recent activity label Mar 24, 2025
@jasonkarns
Copy link
Contributor Author

For completeness: here is various brew-info output (both abbreviated and fully-qualified formula name, while untapped, tapped-but-not-installed, tapped-and-installed):

abbreviated, from core (tap removed)
$ brew info git-sync
==> git-sync: stable 4.4.0 (bottled), HEAD
Clones a git repository and keeps it synchronized with the upstream
https://github.com/kubernetes/git-sync
Conflicts with:
  git-extras (because both install `git-sync` binaries)
Not installed
From: https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/g/git-sync.rb
License: Apache-2.0
==> Dependencies
Build: go
Required: coreutils
==> Options
--HEAD
	Install HEAD version
==> Analytics
install: 4 (30 days), 58 (90 days), 296 (365 days)
install-on-request: 4 (30 days), 58 (90 days), 296 (365 days)
build-error: 0 (30 days)
fully qualified, not installed
$ brew info jacobwgillespie/tap/git-sync
==> jacobwgillespie/tap/git-sync: stable 1.0.0
Git branch sync utility
https://github.com/jacobwgillespie/git-sync
Not installed
From: https://github.com/jacobwgillespie/homebrew-tap/blob/HEAD/git-sync.rb
License: MIT
==> Analytics
install: 4 (30 days), 58 (90 days), 296 (365 days)
install-on-request: 4 (30 days), 58 (90 days), 296 (365 days)
build-error: 0 (30 days)
fully qualified, installed from tap
$ brew info jacobwgillespie/tap/git-sync
==> jacobwgillespie/tap/git-sync: stable 1.0.0
Git branch sync utility
https://github.com/jacobwgillespie/git-sync
Installed
/opt/homebrew/Cellar/git-sync/1.0.0 (7 files, 1.8MB) *
  Built from source on 2025-03-24 at 12:46:13
From: https://github.com/jacobwgillespie/homebrew-tap/blob/HEAD/git-sync.rb
License: MIT
==> Analytics
install: 4 (30 days), 58 (90 days), 296 (365 days)
install-on-request: 4 (30 days), 58 (90 days), 296 (365 days)
build-error: 0 (30 days)
abbreviated, installed from tap
$ brew info git-sync
==> git-sync: stable 4.4.0 (bottled), HEAD
Clones a git repository and keeps it synchronized with the upstream
https://github.com/kubernetes/git-sync
Conflicts with:
  git-extras (because both install `git-sync` binaries)
Installed
/opt/homebrew/Cellar/git-sync/1.0.0 (7 files, 1.8MB) *
  Built from source on 2025-03-24 at 12:46:13
From: https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/g/git-sync.rb
License: Apache-2.0
==> Dependencies
Build: go
Required: coreutils
==> Options
--HEAD
	Install HEAD version
==> Analytics
install: 4 (30 days), 58 (90 days), 296 (365 days)
install-on-request: 4 (30 days), 58 (90 days), 296 (365 days)
build-error: 0 (30 days)

@MikeMcQuaid
Copy link
Member

Though "incorrect" presumes that git info git-sync should prefer to print the data from the tap instead of core if there is a conflict.

git info git-sync should do the same as brew install git-sync i.e. not use the version from the tap, if there's two with a conflicting name.

brew info some/tap/git-sync should work as desired, even although I question how many people will ever fully scope it like this.

tap Installed
tap /opt/homebrew/Cellar/git-sync/1.0.0 (7 files, 1.8MB) *
tap Built from source on 2025-02-12 at 12:07:43

This isn't actually "from the tap". Homebrew doesn't know or care which tap this is installed from here. It could be annotated with the specific tap name.

@jasonkarns
Copy link
Contributor Author

tap Installed
tap /opt/homebrew/Cellar/git-sync/1.0.0 (7 files, 1.8MB) *
tap Built from source on 2025-02-12 at 12:07:43

This isn't actually "from the tap". Homebrew doesn't know or care which tap this is installed from here. It could be annotated with the specific tap name.

I mean "it's from the tap" in the sense that git-sync (core) is not actually installed. So if git info is supposed to be the same as brew install (that is, prefer core formulae over taps), then it shouldn't be reporting as installed (because the core formulae isn't installed). The base confusion is intermixing state of the system from the tap formulae with the core formulae. Changing only the "From" line as indicated here #19294 (comment) would still be printing intermixed and conflicting information. (Particularly, the license/deps/options info, at that point.)

@MikeMcQuaid
Copy link
Member

So if git git info is supposed to be the same as brew install

They are not meant to be the same. One (info) operates on rack, the other (install) operates on formulae.

Formulae are never technically "installed". Kegs are "installed" in a rack. Formulae can have taps, racks cannot.

This is because there always has been (and always will be) overlapping namespaces between "short name formulae" and "racks" and not between "full name formulae" or "taps".

The keg is named git-sync. You're asking here by running brew info, among other things, "what, if anything, is in the git-sync rack?". The answer is "an 1.0.0 keg/installation of the some/tap/git-sync formula".

It would not make sense to say "nothing is installed here".

Again: this is why shadowing formula names is not the best idea and why we now warn about it.

@jasonkarns
Copy link
Contributor Author

jasonkarns commented Apr 14, 2025

Ah, that clarifies a lot! (I didn't have any prior experience with the concept of a "rack" so this distinction helps! appreciate that in the terminology docs)

If I'm understanding better, then would any of the following bits of data be more appropriately tied to the versioned keg that's installed?

  • version
  • description
  • url
  • 'from' formula path (already discussed)
  • license
  • dependencies
  • options

It seems that the top bits of the info output print from whatever the latest formulae has (so version, description, and url). Which would mean even ignoring taps, those would print the latest values from the formula, and not "values at the time of installation".

Then there's a section that seems to read from the rack (beginning with "Installed"), which prints the keg path, installation date, and formula path (the latter being "wrong").

From that point, it prints license, dependencies, and options, which similar to the top section, print values from the latest formula.

It might just be worth clarifying which sections of the output print from keg (ie, details from the keg that are pinned from what was actually the values at installation time) and which print from that rack (aka, pulling from latest formula found)?

Again: this is why shadowing formula names is not the best idea and why we now warn about it.

Understood. I'm wondering what homebrew's recommended workflow would look like for a tap that is published with a non-conflicting rack name. It is effectively "complete" and working in the wild for years. And then a new formula is added to core that introduces the conflict. Is it expected that tap owners perpetually monitor and retroactively rename? (Whether the taps even still have active maintainers, notwithstanding.) Or is it recommended that taps preemptively "namespace" their racks with a prefix or something to reduce the chance of future conflicts that are out of their control? (One can't completely prevent a future conflict without some namespace reservation mechanism, of course.)

@MikeMcQuaid
Copy link
Member

and formula path (the latter being "wrong").

Yup, this part of "Installed" is the only thing that seems "wrong" to me.

I'm wondering what homebrew's recommended workflow would look like for a tap that is published with a non-conflicting rack name.

I guess we don't have an explicit/documented recommendation here.

Is it expected that tap owners perpetually monitor and retroactively rename?

Yeh, pretty much this, unfortunately.

(Whether the taps even still have active maintainers, notwithstanding.)

Given Homebrew's rolling release nature and deprecation process: not having active maintainers often results in broken formulae, unfortunately. I think this is another part the side effects of that. I don't really see any perfect solution to resolve, unfortunately 😭

Copy link

github-actions bot commented May 7, 2025

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.

@github-actions github-actions bot added the stale No recent activity label May 7, 2025
@github-actions github-actions bot closed this as not planned Won't fix, can't repro, duplicate, stale May 14, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Reproducible Homebrew/brew bug stale No recent activity
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants