-
-
Notifications
You must be signed in to change notification settings - Fork 10.1k
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
tap: memoize loading installed taps #16806
Changes from all commits
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 |
---|---|---|
|
@@ -5,6 +5,7 @@ | |
require "completions" | ||
require "extend/cachable" | ||
require "description_cache_store" | ||
require "set" | ||
require "settings" | ||
|
||
# A {Tap} is used to extend the formulae provided by Homebrew core. | ||
|
@@ -401,6 +402,7 @@ def install(quiet: false, clone_target: nil, force_auto_update: nil, | |
|
||
Commands.rebuild_commands_completion_list | ||
link_completions_and_manpages | ||
Tap.registry << self | ||
|
||
formatted_contents = contents.presence&.to_sentence&.dup&.prepend(" ") | ||
$stderr.puts "Tapped#{formatted_contents} (#{path.abv})." unless quiet | ||
|
@@ -511,6 +513,7 @@ def uninstall(manual: false) | |
|
||
Commands.rebuild_commands_completion_list | ||
clear_cache | ||
Tap.registry.delete(self) | ||
|
||
return if !manual || !official? | ||
|
||
|
@@ -880,27 +883,32 @@ def ==(other) | |
other = Tap.fetch(other) if other.is_a?(String) | ||
self.class == other.class && name == other.name | ||
end | ||
alias eql? == | ||
|
||
def self.each(&block) | ||
return to_enum unless block | ||
sig { returns(Integer) } | ||
def hash | ||
[self.class, name].hash | ||
end | ||
|
||
installed_taps = if TAP_DIRECTORY.directory? | ||
TAP_DIRECTORY.subdirs | ||
.flat_map(&:subdirs) | ||
.map(&method(:from_path)) | ||
else | ||
[] | ||
end | ||
# A set with all installed and core taps. | ||
# | ||
# @private | ||
sig { returns(T::Set[Tap]) } | ||
apainintheneck marked this conversation as resolved.
Show resolved
Hide resolved
|
||
def self.registry | ||
cache[:registry] ||= Set.new.tap do |set| | ||
if TAP_DIRECTORY.directory? | ||
set.merge TAP_DIRECTORY.subdirs | ||
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. Doesn't 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. No, it always returns
|
||
.flat_map(&:subdirs) | ||
.map(&method(:from_path)) | ||
end | ||
|
||
available_taps = if Homebrew::EnvConfig.no_install_from_api? | ||
installed_taps | ||
else | ||
default_taps = T.let([CoreTap.instance], T::Array[Tap]) | ||
default_taps << CoreCaskTap.instance if OS.mac? # rubocop:disable Homebrew/MoveToExtendOS | ||
installed_taps + default_taps | ||
end.sort_by(&:name).uniq | ||
set << CoreTap.instance | ||
set << CoreCaskTap.instance if OS.mac? # rubocop:disable Homebrew/MoveToExtendOS | ||
end | ||
end | ||
|
||
available_taps.each(&block) | ||
def self.each(&block) | ||
registry.each(&block) | ||
end | ||
|
||
# An array of all installed {Tap} names. | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -140,10 +140,6 @@ def setup_completion(link:) | |
end | ||
end | ||
|
||
specify "::names" do | ||
expect(described_class.names.sort).to eq(["homebrew/core", "homebrew/foo"]) | ||
end | ||
|
||
Comment on lines
-143
to
-146
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. This will be deprecated soonish so I figured we might as well remove the test instead of updating it. I guess we weren't automatically including the core cask tap on macOS before in this list. |
||
specify "attributes" do | ||
expect(homebrew_foo_tap.user).to eq("Homebrew") | ||
expect(homebrew_foo_tap.repo).to eq("foo") | ||
|
@@ -404,17 +400,20 @@ def setup_completion(link:) | |
setup_completion link: true | ||
|
||
tap = described_class.new("Homebrew", "bar") | ||
expect(described_class.registry).not_to include(tap) | ||
|
||
tap.install clone_target: homebrew_foo_tap.path/".git" | ||
|
||
expect(tap).to be_installed | ||
expect(described_class.registry).to include(tap) | ||
expect(HOMEBREW_PREFIX/"share/man/man1/brew-tap-cmd.1").to be_a_file | ||
expect(HOMEBREW_PREFIX/"etc/bash_completion.d/brew-tap-cmd").to be_a_file | ||
expect(HOMEBREW_PREFIX/"share/zsh/site-functions/_brew-tap-cmd").to be_a_file | ||
expect(HOMEBREW_PREFIX/"share/fish/vendor_completions.d/brew-tap-cmd.fish").to be_a_file | ||
tap.uninstall | ||
|
||
expect(tap).not_to be_installed | ||
expect(described_class.registry).not_to include(tap) | ||
expect(HOMEBREW_PREFIX/"share/man/man1/brew-tap-cmd.1").not_to exist | ||
expect(HOMEBREW_PREFIX/"share/man/man1").not_to exist | ||
expect(HOMEBREW_PREFIX/"etc/bash_completion.d/brew-tap-cmd").not_to exist | ||
|
@@ -501,6 +500,24 @@ def setup_completion(link:) | |
end | ||
end | ||
|
||
describe ".registry" do | ||
it "includes the core and cask taps by default", :needs_macos do | ||
expect(described_class.registry).to include(CoreTap.instance, CoreCaskTap.instance) | ||
end | ||
|
||
it "includes the core tap and excludes the cask tap by default", :needs_linux do | ||
expect(described_class.registry).to include(CoreTap.instance) | ||
expect(described_class.registry).not_to include(CoreCaskTap.instance) | ||
end | ||
|
||
it "ignores a second instance of the same tap" do | ||
expect { described_class.registry << described_class.new("example", "first") } | ||
.to change { described_class.registry.size }.by(1) | ||
expect { described_class.registry << described_class.new("example", "first") } | ||
.not_to(change { described_class.registry.size }) | ||
end | ||
end | ||
|
||
describe "Formula Lists" do | ||
describe "#formula_renames" do | ||
it "returns the formula_renames hash" do | ||
|
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.
Do we actually need the class here? It shouldn't be possible to get a
Tap
for e.g.homebrew/core
anyways.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.
It is considered good practice to include, in case this is ever used in mixed-type collections: https://ruby-doc.org/3.2.2/Object.html#method-i-hash