-
-
Notifications
You must be signed in to change notification settings - Fork 11.1k
Add which entry command #21790
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
base: main
Are you sure you want to change the base?
Add which entry command #21790
Changes from 7 commits
66af1da
a3c0d9b
ae66e65
6c1b0ab
32a99d3
eb11c44
00d9e78
d3ae375
91f72e6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,83 @@ | ||
| # typed: strict | ||
| # frozen_string_literal: true | ||
|
|
||
| require "abstract_command" | ||
| require "formula" | ||
| require "formulary" | ||
| require "json" | ||
|
|
||
| module Homebrew | ||
| module DevCmd | ||
| class WhichEntry < AbstractCommand | ||
| cmd_args do | ||
| description <<~EOS | ||
| Generate an `executables.txt` entry for <formula> using bottle manifest metadata. | ||
| EOS | ||
| flag "--output-db=", | ||
| description: "Append or update the entry in the given `executables.txt` database file." | ||
| named_args :formula, min: 1 | ||
| end | ||
|
|
||
| sig { override.void } | ||
| def run | ||
| db_path = Pathname(T.unsafe(args).output_db) if T.unsafe(args).output_db | ||
| args.named.each { |name| process(name, db_path:) } | ||
| end | ||
|
|
||
| private | ||
|
|
||
| sig { params(name: String, db_path: T.nilable(Pathname)).void } | ||
| def process(name, db_path:) | ||
| formula = Formulary.factory(name) | ||
| line = db_line(formula) | ||
| if db_path | ||
| write_db(db_path, formula.full_name, line) | ||
| elsif line | ||
| puts line | ||
| end | ||
| rescue FormulaUnavailableError | ||
| write_db(db_path, name, nil) if db_path&.exist? | ||
| end | ||
|
|
||
| sig { params(db_path: Pathname, name: String, line: T.nilable(String)).void } | ||
| def write_db(db_path, name, line) | ||
| lines = db_path.readlines(chomp: true).compact_blank if db_path.exist? | ||
| lines = (lines || []).reject { |l| l.start_with?("#{name}(") } | ||
|
ooye-sanket marked this conversation as resolved.
Outdated
|
||
| lines << line if line | ||
| db_path.write("#{lines.sort.join("\n")}\n") | ||
| end | ||
|
|
||
| sig { params(formula: Formula).returns(T.nilable(String)) } | ||
| def db_line(formula) | ||
| return if formula.disabled? || formula.deprecated? | ||
|
|
||
| exes = executables_from_manifest(formula) | ||
| "#{formula.full_name}(#{formula.pkg_version}):#{exes.join(" ")}" | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The reason we added Now that we're going to run this on every merge where we can detect which formulae are updated, I don't think we need the pkg_version anymore |
||
| end | ||
|
|
||
| sig { params(formula: Formula).returns(T::Array[String]) } | ||
| def executables_from_manifest(formula) | ||
| return [] unless formula.bottled? | ||
|
|
||
| manifest_path = HOMEBREW_CACHE.glob("#{formula.name}_bottle_manifest--*").first | ||
| if manifest_path.blank? | ||
| bottle = formula.bottle | ||
| return [] unless bottle | ||
|
|
||
| bottle.fetch | ||
| manifest_path = HOMEBREW_CACHE.glob("#{formula.name}_bottle_manifest--*").first | ||
| end | ||
| return [] if manifest_path.blank? | ||
|
|
||
| manifest = JSON.parse(manifest_path.read) | ||
| exec_files = manifest.dig("manifests", 0, "annotations", "sh.brew.path_exec_files") | ||
| return [] if exec_files.blank? | ||
|
|
||
| exec_files.split.map { |f| File.basename(f) }.sort | ||
| rescue JSON::ParserError => e | ||
| opoo "Failed to parse bottle manifest for #{formula.name}: #{e.message}" | ||
| [] | ||
| end | ||
|
Comment on lines
+59
to
+80
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can this share any logic or constants with the relevant |
||
| end | ||
| end | ||
| end | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| # frozen_string_literal: true | ||
|
|
||
| require "cmd/shared_examples/args_parse" | ||
| require "dev-cmd/which-entry" | ||
|
|
||
| RSpec.describe Homebrew::DevCmd::WhichEntry do | ||
| it_behaves_like "parseable arguments" | ||
| end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This shouldn't be necessary, you may need to run
brew typecheck --updateto avoid the need forT.unsafe.