Skip to content

Conversation

@hmk
Copy link

@hmk hmk commented Jan 7, 2026

  • 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?

This PR implements the changes discussed in #20752 to remove the batch which-update workflow and replace it with a small, maintainable path that derives executables database entries directly from bottle metadata.

I chose to name it which-entry but am open to other suggestions.

@hmk hmk marked this pull request as draft January 7, 2026 03:50
@hmk
Copy link
Author

hmk commented Jan 7, 2026

Some commands I ran to test (in case this helps others):

HOMEBREW_DEVELOPER=1 ./bin/brew which-entry --help

# Basic checks (print a single DB line):
HOMEBREW_DEVELOPER=1 ./bin/brew which-entry curl
HOMEBREW_DEVELOPER=1 ./bin/brew which-entry ripgrep
HOMEBREW_DEVELOPER=1 ./bin/brew which-entry jq

# Multiple formulas in one go:
HOMEBREW_DEVELOPER=1 ./bin/brew which-entry curl ripgrep jq

# Append/update a DB file (sorted) and inspect:
HOMEBREW_DEVELOPER=1 ./bin/brew which-entry --append-to=/tmp/executables.txt curl ripgrep jq
cat /tmp/executables.txt

# Force manifest-only (no tar fallback):
HOMEBREW_DEVELOPER=1 ./bin/brew which-entry --no-fallback curl

@hmk hmk marked this pull request as ready for review January 7, 2026 04:47
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.

@hmk Did you use AI/LLM to generate this? If so, which one and can you confirm you reviewed/understood every line of code before submitting this PR?

@hmk
Copy link
Author

hmk commented Jan 7, 2026

@hmk Did you use AI/LLM to generate this? If so, which one

Yes — parts of this were assisted by AI. I used Claude Code for research and planning and Kilo for autocomplete. Models used: Claude Haiku 4.5, Claude Sonnet 4.5, and GPT-5.

can you confirm you reviewed/understood every line of code before submitting this PR?

Yes. I have reviewed every line of code and take responsibility for it. I understand the code as written.

This is my first contribution to Homebrew, so I’m still building familiarity with the development workflow.

Questions:

  1. My understanding is that the approach suggested by @Rylan12 in
    Remove brew which-update #20752 (comment)
    will require a canonical executables.txt and a new CI workflow in homebrew/core. Since there’s no existing issue tracking that work, should I open one and make this PR depend on it?
  2. Should which-update be deprecated with a warning period before removal? If so, what timeframe (or version bump) would be appropriate?

If I’m misunderstanding the intent or suggested implementation from that discussion, please let me know.

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.

Reviewed. Code pretty hard to follow so far. Somewhat classic AI generation: comments for very obvious things but the choices made are not justified, the code isn't DRY, etc.

I'll probably do one more pass at this level of detail and if it's not good enough I'll pass and prompt an AI to do this myself.


module Homebrew
module DevCmd
# `brew which-entry` command.
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
# `brew which-entry` command.

cmd_args do
description <<~EOS
Generate an executables database entry for one or more formulae using
their bottle manifest metadata (sh.brew.path_exec_files). Optionally
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
their bottle manifest metadata (sh.brew.path_exec_files). Optionally
their bottle manifest metadata (in `sh.brew.path_exec_files`). Optionally

description <<~EOS
Generate an executables database entry for one or more formulae using
their bottle manifest metadata (sh.brew.path_exec_files). Optionally
append/update entries in an existing executables.txt file.
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
append/update entries in an existing executables.txt file.
append/update entries in an existing `executables.txt` file.

EOS

flag "--append-to=",
description: "Append or update entries in the given database file (e.g. executables.txt)."
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
description: "Append or update entries in the given database file (e.g. executables.txt)."
description: "Append or update entries in the given database file (e.g. `executables.txt`)."

sig { override.void }
def run
# Resolve all formula objects first
formulae = args.named.to_a.map { |name| Formulary.factory(name) }
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
formulae = args.named.to_a.map { |name| Formulary.factory(name) }
formulae = args.named.to_formulae_and_casks

end

existing_lines = if path.exist?
path.read.split("\n", -1).reject(&:empty?).map { |l| l.end_with?("\n") ? l : "#{l}\n" }
Copy link
Member

Choose a reason for hiding this comment

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

Split this to a .abc per line for readability. Also: this is somewhat incomprehensible.

updated = []
seen = {}
existing_lines.each do |line|
name = line[/\A([^()]+)\(/, 1]
Copy link
Member

Choose a reason for hiding this comment

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

Same on this regex. is this the same as above?


DB_LINE_REGEX = /^(?<name>.*?)(?:\((?<version>.*)\)):(?<exes_line>.*)?$/

# Represents a single formula entry in the executables database.
Copy link
Member

Choose a reason for hiding this comment

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

All these sort of AI generated comments should be removed.

update_formula_binaries formula, binaries
end

class << self
Copy link
Member

Choose a reason for hiding this comment

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

just do def self.entry_from_manifest instead.

Comment on lines +305 to +306
# Fallback: scan the bottle tar directly
bottle.fetch
Copy link
Member

Choose a reason for hiding this comment

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

When is this needed?

Copy link
Member

@Rylan12 Rylan12 left a comment

Choose a reason for hiding this comment

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

I will review more thoroughly once Mike's comments are addressed, but I don't think this is quite the right approach.

We should be removing all of this logic from this repo and instead writing it as a GitHub action in homebrew/core. Most of the logic in executables_db only exists to get user-friendly diff messages which we don't need once we're doing one-by-one updates, and we can easily pass the just-built bottles and metadata back and worth with github actions artifacts.

@hmk
Copy link
Author

hmk commented Jan 8, 2026

Thanks. I will close this for now in favor of opening a PR with a Github action in homebrew/core, then revisit this branch with a removal-only diff.

@hmk hmk closed this Jan 8, 2026
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.

3 participants