Skip to content

Add which entry command#21790

Open
ooye-sanket wants to merge 4 commits intoHomebrew:mainfrom
ooye-sanket:add-which-entry-command
Open

Add which entry command#21790
ooye-sanket wants to merge 4 commits intoHomebrew:mainfrom
ooye-sanket:add-which-entry-command

Conversation

@ooye-sanket
Copy link
Contributor

Adds brew which-entry <formula> a developer command that generates
a single executables.txt entry for a formula by reading
sh.brew.path_exec_files from its bottle manifest.

This is intended to replace the batch brew which-update job with a
per-formula update triggered by homebrew/core CI on each merge.
What it does

  • Fetches the bottle manifest and reads sh.brew.path_exec_files
  • With --output-db=<file>: upserts the formula's line in the DB file
    and removes it if the formula is disabled, deprecated, or deleted
  • Without --output-db=: prints the DB line to stdout

Relationship to other PRs
The companion homebrew/core PR (Homebrew/homebrew-core#272976) slims
the existing workflow down to just call brew which-entry per formula
detected by brew test-bot --only-formulae-detect, replacing the
current daily batch job entirely.

@MikeMcQuaid please have a look!

  • Have you followed the guidelines in our Contributing document?
  • Have you checked to ensure there aren't other open Pull Requests for the same change?
  • Have you added an explanation of what your changes do and why you'd like us to include them?
  • Have you written new tests for your changes? Here's an example.
  • Have you successfully run brew lgtm (style, typechecking and tests) with your changes locally?

  • AI was used to generate or assist with generating this PR. Please specify below how you used AI to help you, and what steps you have taken to manually verify the changes.

When marking a formula as not installed on request, also set
installed_as_dependency to true, to ensure brew bundle dump
correctly excludes it. Previously, brew tab --no-installed-on-request
had no effect on bundle dump because the dump logic checks both

Fixes Homebrew#21751
Copy link
Member

@MikeMcQuaid MikeMcQuaid left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work @ooye-sanket! Looks good so far. Please add a very basic integration test and args check for which-entry. Also, please inline functions that are only used once as there's a fair bit of indirection right now.

Comment on lines +61 to +62
rescue JSON::ParserError
[]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably worth a opoo warning of the exception in this case?

@ooye-sanket
Copy link
Contributor Author

Thanks @MikeMcQuaid! I've pushed the changes:

  • Inlined cached_manifest, fetch_manifest, read_db, and remove_entry .
  • Added opoo warning when JSON::ParserError is raised so failures aren't silent
  • Added the basic spec with args check

Let me know if the level of inlining looks right or if you'd like it structured differently!

@ooye-sanket ooye-sanket requested a review from MikeMcQuaid March 21, 2026 09:35
Copy link
Member

@MikeMcQuaid MikeMcQuaid left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! Please ensure CI syntax job passing before asking for re-review.


sig { override.void }
def run
db_path = args.output_db&.then { |path| Pathname(path) }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure I understand the .then usage here: can you explain?

formula = Formulary.factory(name)
line = db_line(formula)
if db_path
existing = db_path.exist? ? db_path.readlines(chomp: true).reject(&:empty?) : []
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
existing = db_path.exist? ? db_path.readlines(chomp: true).reject(&:empty?) : []
existing = db_path.readlines(chomp: true).reject(&:blank?) if db_path.exist?
existing ||= []

maybe

line = db_line(formula)
if db_path
existing = db_path.exist? ? db_path.readlines(chomp: true).reject(&:empty?) : []
lines = existing.reject { |l| l.start_with?("#{formula.full_name}(") }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could maybe drop existing as a variable and just chain this?

if db_path
existing = db_path.exist? ? db_path.readlines(chomp: true).reject(&:empty?) : []
lines = existing.reject { |l| l.start_with?("#{formula.full_name}(") }
lines << line if line
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe use filter_map?

Comment on lines +38 to +39
else
puts line if line
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
else
puts line if line
elsif line
puts line

Comment on lines +44 to +45
lines = db_path.readlines(chomp: true).reject { |l| l.start_with?("#{name}(") }
db_path.write("#{lines.sort.join("\n")}\n")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This logic is repeated, maybe worth turning into a function or restructuring

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants