Improve completions (and elisp) output in caveats

Instead of repeatedly outputting the same identical messages across
multiple packages and repeating them all for every package after they
were all installed: just output the identical messages in the final
caveats output instead.
This commit is contained in:
Mike McQuaid 2025-06-06 17:09:28 +01:00
parent b23bc5e0fe
commit ff710f8191
No known key found for this signature in database
5 changed files with 62 additions and 42 deletions

View File

@ -14,40 +14,54 @@ class Caveats
sig { params(formula: Formula).void } sig { params(formula: Formula).void }
def initialize(formula) def initialize(formula)
@formula = formula @formula = formula
@caveats = T.let(nil, T.nilable(String))
@completions_and_elisp = T.let(nil, T.nilable(T::Array[String]))
end end
sig { returns(String) } sig { returns(String) }
def caveats def caveats
caveats = [] @caveats ||= begin
build = formula.build caveats = []
begin build = formula.build
formula.build = Tab.for_formula(formula) begin
string = formula.caveats.to_s formula.build = Tab.for_formula(formula)
caveats << "#{string.chomp}\n" unless string.empty? string = formula.caveats.to_s
ensure caveats << "#{string.chomp}\n" unless string.empty?
formula.build = build ensure
formula.build = build
end
caveats << keg_only_text
caveats << service_caveats
caveats.compact.join("\n")
end end
caveats << keg_only_text
valid_shells = [:bash, :zsh, :fish, :pwsh].freeze
current_shell = Utils::Shell.preferred || Utils::Shell.parent
shells = if current_shell.present? &&
(shell_sym = current_shell.to_sym) &&
valid_shells.include?(shell_sym)
[shell_sym]
else
valid_shells
end
shells.each do |shell|
caveats << function_completion_caveats(shell)
end
caveats << service_caveats
caveats << elisp_caveats
caveats.compact.join("\n")
end end
delegate [:empty?, :to_s] => :caveats sig { returns(T::Boolean) }
def empty?
caveats.blank? && completions_and_elisp.blank?
end
delegate [:to_s] => :caveats
sig { returns(T::Array[String]) }
def completions_and_elisp
@completions_and_elisp ||= begin
valid_shells = [:bash, :zsh, :fish, :pwsh].freeze
current_shell = Utils::Shell.preferred || Utils::Shell.parent
shells = if current_shell.present? &&
(shell_sym = current_shell.to_sym) &&
valid_shells.include?(shell_sym)
[shell_sym]
else
valid_shells
end
completions_and_elisp = shells.map do |shell|
function_completion_caveats(shell)
end
completions_and_elisp << elisp_caveats
completions_and_elisp.compact
end
end
sig { params(skip_reason: T::Boolean).returns(T.nilable(String)) } sig { params(skip_reason: T::Boolean).returns(T.nilable(String)) }
def keg_only_text(skip_reason: false) def keg_only_text(skip_reason: false)

View File

@ -892,9 +892,11 @@ on_request: installed_on_request?, options:)
return if quiet? return if quiet?
caveats = Caveats.new(formula) caveats = Caveats.new(formula)
return if caveats.empty? return if caveats.empty?
Homebrew.messages.record_completions_and_elisp(caveats.completions_and_elisp)
return if caveats.caveats.empty?
@show_summary_heading = true @show_summary_heading = true
ohai "Caveats", caveats.to_s ohai "Caveats", caveats.to_s
Homebrew.messages.record_caveats(formula.name, caveats) Homebrew.messages.record_caveats(formula.name, caveats)

View File

@ -16,6 +16,7 @@ class Messages
sig { void } sig { void }
def initialize def initialize
@caveats = T.let([], T::Array[T::Hash[Symbol, Symbol]]) @caveats = T.let([], T::Array[T::Hash[Symbol, Symbol]])
@completions_and_elisp = T.let(Set.new, T::Set[String])
@package_count = T.let(0, Integer) @package_count = T.let(0, Integer)
@install_times = T.let([], T::Array[T::Hash[String, Float]]) @install_times = T.let([], T::Array[T::Hash[String, Float]])
end end
@ -25,6 +26,11 @@ class Messages
@caveats.push(package:, caveats:) @caveats.push(package:, caveats:)
end end
sig { params(completions_and_elisp: T::Array[String]).void }
def record_completions_and_elisp(completions_and_elisp)
@completions_and_elisp.merge(completions_and_elisp)
end
sig { params(package: String, elapsed_time: Float).void } sig { params(package: String, elapsed_time: Float).void }
def package_installed(package, elapsed_time) def package_installed(package, elapsed_time)
@package_count += 1 @package_count += 1
@ -40,13 +46,14 @@ class Messages
sig { params(force: T::Boolean).void } sig { params(force: T::Boolean).void }
def display_caveats(force: false) def display_caveats(force: false)
return if @package_count.zero? return if @package_count.zero?
return if @package_count == 1 && !force return if @caveats.empty? && @completions_and_elisp.empty?
return if @caveats.empty?
oh1 "Caveats" oh1 "Caveats" unless @completions_and_elisp.empty?
@caveats.each do |c| @completions_and_elisp.each { |c| puts c }
ohai c[:package], c[:caveats] return if @package_count == 1 && !force
end
oh1 "Caveats" if @completions_and_elisp.empty?
@caveats.each { |c| ohai c[:package], c[:caveats] }
end end
sig { void } sig { void }

View File

@ -6,9 +6,6 @@
class Caveats class Caveats
sig { params(args: T.untyped, block: T.untyped).returns(T::Boolean) }
def empty?(*args, &block); end
sig { params(args: T.untyped, block: T.untyped).returns(String) } sig { params(args: T.untyped, block: T.untyped).returns(String) }
def to_s(*args, &block); end def to_s(*args, &block); end
end end

View File

@ -242,7 +242,7 @@ RSpec.describe Caveats do
url "foo-1.0" url "foo-1.0"
end end
end end
let(:caveats) { described_class.new(f).caveats } let(:caveats) { described_class.new(f) }
let(:path) { f.prefix.resolved_path } let(:path) { f.prefix.resolved_path }
let(:bash_completion_dir) { path/"etc/bash_completion.d" } let(:bash_completion_dir) { path/"etc/bash_completion.d" }
@ -261,25 +261,25 @@ RSpec.describe Caveats do
it "includes where Bash completions have been installed to" do it "includes where Bash completions have been installed to" do
bash_completion_dir.mkpath bash_completion_dir.mkpath
FileUtils.touch bash_completion_dir/f.name FileUtils.touch bash_completion_dir/f.name
expect(caveats).to include(HOMEBREW_PREFIX/"etc/bash_completion.d") expect(caveats.completions_and_elisp.join).to include(HOMEBREW_PREFIX/"etc/bash_completion.d")
end end
it "includes where fish completions have been installed to" do it "includes where fish completions have been installed to" do
fish_vendor_completions.mkpath fish_vendor_completions.mkpath
FileUtils.touch fish_vendor_completions/f.name FileUtils.touch fish_vendor_completions/f.name
expect(caveats).to include(HOMEBREW_PREFIX/"share/fish/vendor_completions.d") expect(caveats.completions_and_elisp.join).to include(HOMEBREW_PREFIX/"share/fish/vendor_completions.d")
end end
it "includes where zsh completions have been installed to" do it "includes where zsh completions have been installed to" do
zsh_site_functions.mkpath zsh_site_functions.mkpath
FileUtils.touch zsh_site_functions/f.name FileUtils.touch zsh_site_functions/f.name
expect(caveats).to include(HOMEBREW_PREFIX/"share/zsh/site-functions") expect(caveats.completions_and_elisp.join).to include(HOMEBREW_PREFIX/"share/zsh/site-functions")
end end
it "includes where pwsh completions have been installed to" do it "includes where pwsh completions have been installed to" do
pwsh_completion_dir.mkpath pwsh_completion_dir.mkpath
FileUtils.touch pwsh_completion_dir/f.name FileUtils.touch pwsh_completion_dir/f.name
expect(caveats).to include(HOMEBREW_PREFIX/"share/pwsh/completions") expect(caveats.completions_and_elisp.join).to include(HOMEBREW_PREFIX/"share/pwsh/completions")
end end
end end
end end