Homebrew / brew

šŸŗ The missing package manager for macOS (or Linux)
https://brew.sh
BSD 2-Clause "Simplified" License
41.07k stars 9.64k forks source link

`brew deps` sometimes incorrectly returns an empty list #9333

Closed carlocab closed 3 years ago

carlocab commented 3 years ago

Bug report

Please note we will close your issue without comment if you delete, do not read or do not fill out the issue checklist below and provide ALL the requested information. If you repeatedly fail to use the issue template, we will block you from ever submitting issues to Homebrew again.

What you were trying to do (and why)

I ran brew deps tree-sitter, because I was interested in the footprint of this package on my system.

What happened (include command output)

Nothing happened. This was surprising because tree-sitter does have dependents. The dependency tree is reported correctly by brew deps --tree tree-sitter.

Other formulae seem to report their dependencies correctly (e.g. python@3.9).

Command output
āÆ brew deps tree-sitter
āÆ brew deps --tree tree-sitter
tree-sitter
ā”œā”€ā”€ emscripten
ā”‚   ā”œā”€ā”€ binaryen
ā”‚   ā”œā”€ā”€ node
ā”‚   ā”‚   ā””ā”€ā”€ icu4c
ā”‚   ā”œā”€ā”€ python@3.9
ā”‚   ā”‚   ā”œā”€ā”€ gdbm
ā”‚   ā”‚   ā”œā”€ā”€ openssl@1.1
ā”‚   ā”‚   ā”œā”€ā”€ readline
ā”‚   ā”‚   ā”œā”€ā”€ sqlite
ā”‚   ā”‚   ā”‚   ā””ā”€ā”€ readline
ā”‚   ā”‚   ā””ā”€ā”€ xz
ā”‚   ā””ā”€ā”€ yuicompressor
ā”‚       ā””ā”€ā”€ openjdk
ā””ā”€ā”€ node
    ā””ā”€ā”€ icu4c

āÆ brew deps python@3.9
gdbm
openssl@1.1
readline
sqlite
xz
  

What you expected to happen

I expected brew deps tree-sitter to correctly report tree-sitter's dependencies.

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

Just brew deps tree-sitter.

Output of brew config and brew doctor commands

āÆ brew config
HOMEBREW_VERSION: 2.5.12-275-gef75518
ORIGIN: https://github.com/Homebrew/brew
HEAD: ef755182bbd11bf8f49b0139d089046596ab8fb7
Last commit: 22 hours ago
Core tap ORIGIN: https://github.com/Homebrew/homebrew-core
Core tap HEAD: 6de7edb5a4024433e8cf9e78f8bb9be1c153d244
Core tap last commit: 44 minutes ago
Core tap branch: master
HOMEBREW_PREFIX: /usr/local
HOMEBREW_BAT: set
HOMEBREW_CASK_OPTS: []
HOMEBREW_COLOR: set
HOMEBREW_EDITOR: nvim
HOMEBREW_FORCE_VENDOR_RUBY: set
HOMEBREW_GITHUB_API_TOKEN: set
HOMEBREW_MAKE_JOBS: 4
Homebrew Ruby: 2.6.3 => /usr/local/Homebrew/Library/Homebrew/vendor/portable-ruby/2.6.3_2/bin/ruby
CPU: quad-core 64-bit icelake
Clang: 12.0 build 1200
Git: 2.29.2 => /usr/local/bin/git
Curl: 7.64.1 => /usr/bin/curl
macOS: 11.0.1-x86_64
CLT: 12.2.0.0.1.1604076827
Xcode: N/A

āÆ brew doctor
Your system is ready to brew.
jonchang commented 3 years ago

Try running it with brew deps --verbose --debug tree-sitter to see what might be going on. There's likely an error somewhere that we're silently ignoring in brew deps.

carlocab commented 3 years ago

Not sure if this says anything useful:

āÆ brew deps --verbose --debug tree-sitter
/usr/local/Homebrew/Library/Homebrew/brew.rb (Formulary::FormulaLoader): loading /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/tree-sitter.rb
/usr/local/Homebrew/Library/Homebrew/brew.rb (Formulary::FormulaLoader): loading /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/rust.rb
/usr/local/Homebrew/Library/Homebrew/brew.rb (Formulary::FormulaLoader): loading /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/cmake.rb
/usr/local/Homebrew/Library/Homebrew/brew.rb (Formulary::FormulaLoader): loading /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/sphinx-doc.rb
/usr/local/Homebrew/Library/Homebrew/brew.rb (Formulary::FormulaLoader): loading /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/python@3.9.rb
/usr/local/Homebrew/Library/Homebrew/brew.rb (Formulary::FormulaLoader): loading /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/pkg-config.rb
/usr/local/Homebrew/Library/Homebrew/brew.rb (Formulary::FormulaLoader): loading /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/gdbm.rb
/usr/local/Homebrew/Library/Homebrew/brew.rb (Formulary::FormulaLoader): loading /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/openssl@1.1.rb
/usr/local/Homebrew/Library/Homebrew/brew.rb (Formulary::FormulaLoader): loading /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/readline.rb
/usr/local/Homebrew/Library/Homebrew/brew.rb (Formulary::FormulaLoader): loading /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/sqlite.rb
/usr/local/Homebrew/Library/Homebrew/brew.rb (Formulary::FormulaLoader): loading /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/xz.rb
/usr/local/Homebrew/Library/Homebrew/brew.rb (Formulary::FormulaLoader): loading /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/libssh2.rb
/usr/local/Homebrew/Library/Homebrew/brew.rb (Formulary::FormulaLoader): loading /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/emscripten.rb
/usr/local/Homebrew/Library/Homebrew/brew.rb (Formulary::FormulaLoader): loading /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/binaryen.rb
/usr/local/Homebrew/Library/Homebrew/brew.rb (Formulary::FormulaLoader): loading /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/node.rb
/usr/local/Homebrew/Library/Homebrew/brew.rb (Formulary::FormulaLoader): loading /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/icu4c.rb
/usr/local/Homebrew/Library/Homebrew/brew.rb (Formulary::FormulaLoader): loading /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/yuicompressor.rb
/usr/local/Homebrew/Library/Homebrew/brew.rb (Formulary::FormulaLoader): loading /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/openjdk.rb
/usr/local/Homebrew/Library/Homebrew/brew.rb (Formulary::FormulaLoader): loading /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/autoconf.rb

It seems like deps finds all the formulae that tree-sitter depends on just fine (though I suppose that is no surprise given that it works with --tree), it's just not printing them.

I'll try to have a poke around cmd/deps.rb to see if I can figure something out.

EricFromCanada commented 3 years ago

Could be related to @use_runtime_dependencies. Try running brew deps --include-test --verbose --debug tree-sitter which will force it to be false.

carlocab commented 3 years ago

Yes, I had discovered that brew deps --include-test tree-sitter correctly returns the (recursive) list of dependencies. I tried each of the possible flags for deps. Didn't try combinations of them though.

Adding the flags --verbose and --debug just prepends that list with the output from my last comment.

In case it's helpful:

Of course, "complete" is with respect to what that flag is supposed to print out.

Looking back at deps.rb, it does look related to @use_runtime_dependencies.

EricFromCanada commented 3 years ago

Try running brew ruby -e 'puts "tree-sitter".f.runtime_dependencies'. For me it returns this, but it might be blank for you:

$ brew ruby -e 'puts "tree-sitter".f.runtime_dependencies'
binaryen
icu4c
node
gdbm
openssl@1.1
readline
sqlite
xz
python@3.9
openjdk
yuicompressor
emscripten
carlocab commented 3 years ago

I don't understand enough of the brew codebase to figure out what's happening, but I did wonder if other formulae were also not reporting their dependencies correctly.

I wrote a little script to check:

#!/usr/bin/env zsh

formulae_dir="/usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula"

for formula in $formulae_dir/*.rb; do
    if [[ -n "$(brew deps --include-test $formula)" ]]; then
        if [[ -z "$(brew deps $formula)" ]]; then
            echo $formula
        fi
    fi
done

I don't actually recommend you run that, because it will take ages. However, I did run a version of this using parallel. This will produce false positives: some formulae may have no dependencies other than those required for testing.

After filtering out the formulae that actually do have test dependencies, I came up with this list:

acme
ddrescue
ed
lcs
make
moe
ocrad
snap7
spim
tree-sitter

It seems there's a second kind of problem, where brew deps --include-test falsely reports non-existent dependencies.

For example:

āÆ cd $(brew --repo homebrew/core)/Formula
āÆ grep ':test' acme.rb
āÆ brew deps --include-test acme
apr
apr-util
gettext
lz4
openssl@1.1
perl
readline
sqlite
subversion
utf8proc
āÆ brew deps --tree acme
acme

brew deps --tree acme is correct: acme has no listed dependencies.

carlocab commented 3 years ago

Try running brew ruby -e 'puts "tree-sitter".f.runtime_dependencies'.

It is blank for me.

Rylan12 commented 3 years ago

It seems there's a second kind of problem, where brew deps --include-test falsely reports non-existent dependencies.

I can reproduce this one šŸ¤”. It seems that brew deps --include-test acme and brew deps --include-build acme show lists of dependencies that, according to the formula file, don't exist (as the formula seems to declare no dependencies).

Based on the output of brew info acme and adding --tree to the above commands, it seems that subversion is appearing as a build dependency of acme. Not sure why šŸ¤”

$ brew info acme
acme: stable 0.97 (bottled)
Crossassembler for multiple environments
https://sourceforge.net/projects/acme-crossass/
Not installed
From: https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/acme.rb
License: GPL-2.0-or-later
==> Dependencies
Build: subversion
==> Analytics
install: 639 (30 days), 1,763 (90 days), 9,978 (365 days)
install-on-request: 638 (30 days), 1,758 (90 days), 9,953 (365 days)
build-error: 0 (30 days)
$ brew deps --tree acme
acme
$ brew deps --include-test --tree acme
acme
ā””ā”€ā”€ subversion
    ā”œā”€ā”€ apr
    ā”œā”€ā”€ apr-util
    ā”‚   ā”œā”€ā”€ apr
    ā”‚   ā””ā”€ā”€ openssl@1.1
    ā”œā”€ā”€ gettext
    ā”œā”€ā”€ lz4
    ā”œā”€ā”€ openssl@1.1
    ā”œā”€ā”€ perl
    ā”œā”€ā”€ sqlite
    ā”‚   ā””ā”€ā”€ readline
    ā””ā”€ā”€ utf8proc
$ brew deps --include-build --tree acme
acme
ā””ā”€ā”€ subversion
    ā”œā”€ā”€ openjdk
    ā”‚   ā””ā”€ā”€ autoconf
    ā”œā”€ā”€ pkg-config
    ā”œā”€ā”€ python@3.9
    ā”‚   ā”œā”€ā”€ pkg-config
    ā”‚   ā”œā”€ā”€ gdbm
    ā”‚   ā”œā”€ā”€ openssl@1.1
    ā”‚   ā”œā”€ā”€ readline
    ā”‚   ā”œā”€ā”€ sqlite
    ā”‚   ā”‚   ā””ā”€ā”€ readline
    ā”‚   ā””ā”€ā”€ xz
    ā”œā”€ā”€ scons
    ā”‚   ā””ā”€ā”€ python@3.9
    ā”‚       ā”œā”€ā”€ pkg-config
    ā”‚       ā”œā”€ā”€ gdbm
    ā”‚       ā”œā”€ā”€ openssl@1.1
    ā”‚       ā”œā”€ā”€ readline
    ā”‚       ā”œā”€ā”€ sqlite
    ā”‚       ā”‚   ā””ā”€ā”€ readline
    ā”‚       ā””ā”€ā”€ xz
    ā”œā”€ā”€ swig
    ā”‚   ā””ā”€ā”€ pcre
    ā”œā”€ā”€ apr
    ā”‚   ā””ā”€ā”€ autoconf
    ā”œā”€ā”€ apr-util
    ā”‚   ā”œā”€ā”€ apr
    ā”‚   ā”‚   ā””ā”€ā”€ autoconf
    ā”‚   ā””ā”€ā”€ openssl@1.1
    ā”œā”€ā”€ gettext
    ā”œā”€ā”€ lz4
    ā”œā”€ā”€ openssl@1.1
    ā”œā”€ā”€ perl
    ā”œā”€ā”€ sqlite
    ā”‚   ā””ā”€ā”€ readline
    ā””ā”€ā”€ utf8proc

Unfortunately, it's getting late for me so I'll have to wait until tomorrow to investigate...

MikeMcQuaid commented 3 years ago

I can reproduce this one šŸ¤”. It seems that brew deps --include-test acme and brew deps --include-build acme show lists of dependencies that, according to the formula file, don't exist (as the formula seems to declare no dependencies).

The formula file is not authoritative for installed formulae, the actual detected linkage of the formula is.

Closing as the original issue cannot be reproduced by multiple maintainers. Feel free to continue discussion here though.

carlocab commented 3 years ago

The formula file is not authoritative for installed formulae, the actual detected linkage of the formula is.

Doesn't brew need the formula installed to detect linkage though? At least, that's my guess since brew linkage <formula> returns an error for formulae that are not installed (which brew help linkage also mentions).

This makes the acme example troubling for me, as it seems to detect linkage (or otherwise think there's a dependency) even though I don't have acme installed.

Closing as the original issue cannot be reproduced by multiple maintainers. Feel free to continue discussion here though.

Right. I just tried it again and I can't reproduce it anymore either, so... šŸ¤· Apologies if this was all a waste of time.

EricFromCanada commented 3 years ago

acme has subversion as a build dependency because its URL is detected to be for an SVN repo and your system's Xcode or CLT don't ship with svn.

carlocab commented 3 years ago

Cool. I wish I understood how brew deps actually resolved dependencies.

Thanks for taking the time to look into this, everyone.