brew: `brew deps` output shows inconsistent dependency information between tree and non-tree output

brew doctor output

Please note that these warnings are just used to help the Homebrew maintainers
with debugging if you file an issue. If everything you use Homebrew for is
working fine: please don't worry or file an issue; just ignore this. Thanks!

Warning: Putting non-prefixed coreutils in your path can cause GMP builds to fail.

Warning: Homebrew's "sbin" was not found in your PATH but you have installed
formulae that put executables in /opt/homebrew/sbin.
Consider setting your PATH for example like so:
  echo 'export PATH="/opt/homebrew/sbin:$PATH"' >> /Users/51195/.bash_profile

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.1.13
ORIGIN: https://github.com/Homebrew/brew
HEAD: a8519f78fb63f2f2266950bdd8141037da69f8bd
Last commit: 6 hours ago
Core tap JSON: 25 Sep 18:03 UTC
HOMEBREW_PREFIX: /opt/homebrew
HOMEBREW_CASK_OPTS: []
HOMEBREW_EDITOR: nvim
HOMEBREW_MAKE_JOBS: 10
Homebrew Ruby: 2.6.10 => /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/bin/ruby
CPU: 10-core 64-bit arm_firestorm_icestorm
Clang: 14.0.3 build 1403
Git: 2.42.0 => /opt/homebrew/bin/git
Curl: 8.1.2 => /usr/bin/curl
macOS: 13.5.2-arm64
CLT: 14.3.1.0.1.1683849156
Xcode: N/A
Rosetta 2: false

What were you trying to do (and why)?

When checking to see which of my installed homebrew packages had updates, I noticed that I had both OpenSSL@1.1 and OpenSSL@3 installed. I didn’t realize I had two versions, and I wanted to know which packages depended on each respective version, if any. I have found a few unused packages recently in my Homebrew installation, and wanted to clean up packages that weren’t being used.

I ran brew deps --tree --installed to look at all dependencies, and searched for “openssl@1.1” in that output.

What happened (include all command output)?

On initial check, I did not see “openssl@1.1” listed anywhere in the command’s output.

I narrowed this down and found an inconsistency in brew deps output as follows.

Output of brew deps --installed tmux:

ca-certificates
libevent
ncurses
openssl@1.1
utf8proc

Output of brew deps --tree --installed tmux:

tmux
├── libevent
│   └── openssl@3
│       └── ca-certificates
├── ncurses
└── utf8proc

Note the different versions of openssl reported between these two commands.

What did you expect to happen?

I expect the same specific version of a package to be reported as a dependency regardless of which command or command arguments are used to view dependencies.

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

brew install tmux tmuxp
brew deps --installed tmux
brew deps --tree --installed tmux

About this issue

  • Original URL
  • State: open
  • Created 9 months ago
  • Comments: 17 (13 by maintainers)

Most upvoted comments

I’m also inclined to open a new issue for the outdated install receipt since it seems like it’s still causing unexpected behavior with multiple commands.

We have this issue every time there’s a OpenSSL migration.

Ignoring the brew deps for a moment (where there’s probably room for an extra flag somewhere) and focussing on the tab specifically: by the letter of how it is designed to work, it is correct. That’s not to say it’s necessarily 100% ideal. The tab is fairly eager with dependencies, mostly because it’s tricky to do anything else safely. We collect recursive dependencies but don’t really properly know what’s actually a runtime dependency (linkage is fairly safe bet for some things, but not everything). But when we do OpenSSL migrations, we only revision bump things that actually have linkage to OpenSSL (usually direct dependencies plus anything recursive that’s flagged in CI). In this case tmux did not need revision bumping, but the tab will think OpenSSL is a runtime dependency because it doesn’t know otherwise.

But yes it does cause issues when brew uninstall openssl@1.1 is blocked when in reality it’s safe (except for the very few formulae left that directly depend on it), meaning people are told to keep something we’ve phased out as EOL.

(Though yeah, this is treading towards a separate issue rather than brew deps specifically)

There was recently added a paragraph to the command’s docs addressing this:

If any version of each formula argument is installed and no other options are passed, this command displays their actual runtime dependencies (similar to brew linkage), which may differ from the current versons’ stated dependencies if the installed versions are outdated.

What doesn’t make sense to me is that you would show this type of information as the default for any command, especially for the baseline command I would reach for if I was looking for dependency information.

It didn’t use to be the default and people complained that it didn’t match what’s happening on their machine. There’s not a single default that everyone will agree on and not find confusing.

Would it be unreasonable to add a separate, different option to show information from the “install receipt / tab,”

We could/should add an option for the opposite: to discard the information from your tap and use only what the formula says.

@ZhongRuoyu Yep, you’re right. That’s exactly what’s happening here. We end up calling Formula#runtime_dependencies internally and that defaults to the tab if there’s a keg already installed. We could easily change that to always skip the tab in these situations but I’m not sure if that’d be less confusing.

https://github.com/Homebrew/brew/blob/f1d345a60e2c02f7e5c1b7930601b1921432cfb6/Library/Homebrew/formula.rb#L2120-L2122

I haven’t looked into this but I can say that we have different dependency resolution code for the normal and tree versions of the brew deps command. For that reason I’m not completely surprised that they might return different results. Definitely seems like a bug though on our side.

Created as a homebrew issue and not a formula issue as this behavior seems more likely to be on the homebrew side.