cache taps
There are plenty of IO operations inside Tap object, and it will be more when implementing formula alias reverse look up(e.g. list all of alias names for a formula). So let's cache them. Some benchmark: $ time brew info $(brew ruby -e 'puts Formula.tap_names') > /dev/null Before: 6.40s user 2.42s system 96% cpu 9.134 total After: 4.75s user 0.77s system 97% cpu 5.637 total Closes Homebrew/homebrew#44377. Signed-off-by: Xu Cheng <xucheng@me.com>
This commit is contained in:
parent
6240e896b2
commit
3b520cf195
@ -69,7 +69,7 @@ module Homebrew
|
|||||||
def github_info(f)
|
def github_info(f)
|
||||||
if f.tap?
|
if f.tap?
|
||||||
user, repo = f.tap.split("/", 2)
|
user, repo = f.tap.split("/", 2)
|
||||||
tap = Tap.new user, repo.gsub(/^homebrew-/, "")
|
tap = Tap.fetch user, repo.gsub(/^homebrew-/, "")
|
||||||
if remote = tap.remote
|
if remote = tap.remote
|
||||||
path = f.path.relative_path_from(tap.path)
|
path = f.path.relative_path_from(tap.path)
|
||||||
github_remote_path(remote, path)
|
github_remote_path(remote, path)
|
||||||
|
|||||||
@ -46,7 +46,7 @@ module Homebrew
|
|||||||
if ARGV.named.empty?
|
if ARGV.named.empty?
|
||||||
formulae = Formula.files
|
formulae = Formula.files
|
||||||
else
|
else
|
||||||
tap = Tap.new(*tap_args)
|
tap = Tap.fetch(*tap_args)
|
||||||
raise TapUnavailableError, tap.name unless tap.installed?
|
raise TapUnavailableError, tap.name unless tap.installed?
|
||||||
formulae = tap.formula_files
|
formulae = tap.formula_files
|
||||||
end
|
end
|
||||||
|
|||||||
@ -6,7 +6,7 @@ module Homebrew
|
|||||||
taps = Tap
|
taps = Tap
|
||||||
else
|
else
|
||||||
taps = ARGV.named.map do |name|
|
taps = ARGV.named.map do |name|
|
||||||
Tap.new(*tap_args(name))
|
Tap.fetch(*tap_args(name))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -3,7 +3,7 @@ require "cmd/tap"
|
|||||||
module Homebrew
|
module Homebrew
|
||||||
def tap_pin
|
def tap_pin
|
||||||
ARGV.named.each do |name|
|
ARGV.named.each do |name|
|
||||||
tap = Tap.new(*tap_args(name))
|
tap = Tap.fetch(*tap_args(name))
|
||||||
tap.pin
|
tap.pin
|
||||||
ohai "Pinned #{tap.name}"
|
ohai "Pinned #{tap.name}"
|
||||||
end
|
end
|
||||||
|
|||||||
@ -3,7 +3,7 @@ require "cmd/tap"
|
|||||||
module Homebrew
|
module Homebrew
|
||||||
def tap_unpin
|
def tap_unpin
|
||||||
ARGV.named.each do |name|
|
ARGV.named.each do |name|
|
||||||
tap = Tap.new(*tap_args(name))
|
tap = Tap.fetch(*tap_args(name))
|
||||||
tap.unpin
|
tap.unpin
|
||||||
ohai "Unpinned #{tap.name}"
|
ohai "Unpinned #{tap.name}"
|
||||||
end
|
end
|
||||||
|
|||||||
@ -23,7 +23,7 @@ module Homebrew
|
|||||||
# ensure git is installed
|
# ensure git is installed
|
||||||
Utils.ensure_git_installed!
|
Utils.ensure_git_installed!
|
||||||
|
|
||||||
tap = Tap.new user, repo
|
tap = Tap.fetch user, repo
|
||||||
return false if tap.installed?
|
return false if tap.installed?
|
||||||
ohai "Tapping #{tap}"
|
ohai "Tapping #{tap}"
|
||||||
remote = clone_target || "https://github.com/#{tap.user}/homebrew-#{tap.repo}"
|
remote = clone_target || "https://github.com/#{tap.user}/homebrew-#{tap.repo}"
|
||||||
|
|||||||
@ -39,20 +39,20 @@ module Homebrew
|
|||||||
|
|
||||||
def resolve_test_tap
|
def resolve_test_tap
|
||||||
tap = ARGV.value("tap")
|
tap = ARGV.value("tap")
|
||||||
return Tap.new(*tap_args(tap)) if tap
|
return Tap.fetch(*tap_args(tap)) if tap
|
||||||
|
|
||||||
if ENV["UPSTREAM_BOT_PARAMS"]
|
if ENV["UPSTREAM_BOT_PARAMS"]
|
||||||
bot_argv = ENV["UPSTREAM_BOT_PARAMS"].split " "
|
bot_argv = ENV["UPSTREAM_BOT_PARAMS"].split " "
|
||||||
bot_argv.extend HomebrewArgvExtension
|
bot_argv.extend HomebrewArgvExtension
|
||||||
tap = bot_argv.value("tap")
|
tap = bot_argv.value("tap")
|
||||||
return Tap.new(*tap_args(tap)) if tap
|
return Tap.fetch(*tap_args(tap)) if tap
|
||||||
end
|
end
|
||||||
|
|
||||||
if git_url = ENV["UPSTREAM_GIT_URL"] || ENV["GIT_URL"]
|
if git_url = ENV["UPSTREAM_GIT_URL"] || ENV["GIT_URL"]
|
||||||
# Also can get tap from Jenkins GIT_URL.
|
# Also can get tap from Jenkins GIT_URL.
|
||||||
url_path = git_url.sub(%r{^https?://github\.com/}, "").chomp("/")
|
url_path = git_url.sub(%r{^https?://github\.com/}, "").chomp("/")
|
||||||
HOMEBREW_TAP_ARGS_REGEX =~ url_path
|
HOMEBREW_TAP_ARGS_REGEX =~ url_path
|
||||||
return Tap.new($1, $3) if $1 && $3 && $3 != "homebrew"
|
return Tap.fetch($1, $3) if $1 && $3 && $3 != "homebrew"
|
||||||
end
|
end
|
||||||
|
|
||||||
# return nil means we are testing core repo.
|
# return nil means we are testing core repo.
|
||||||
|
|||||||
@ -6,7 +6,7 @@ module Homebrew
|
|||||||
raise "Usage is `brew untap <tap-name>`" if ARGV.empty?
|
raise "Usage is `brew untap <tap-name>`" if ARGV.empty?
|
||||||
|
|
||||||
ARGV.named.each do |tapname|
|
ARGV.named.each do |tapname|
|
||||||
tap = Tap.new(*tap_args(tapname))
|
tap = Tap.fetch(*tap_args(tapname))
|
||||||
|
|
||||||
raise TapUnavailableError, tap.name unless tap.installed?
|
raise TapUnavailableError, tap.name unless tap.installed?
|
||||||
puts "Untapping #{tap}... (#{tap.path.abv})"
|
puts "Untapping #{tap}... (#{tap.path.abv})"
|
||||||
|
|||||||
@ -63,6 +63,8 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Tap.clear_cache
|
||||||
|
|
||||||
# automatically tap any migrated formulae's new tap
|
# automatically tap any migrated formulae's new tap
|
||||||
report.select_formula(:D).each do |f|
|
report.select_formula(:D).each do |f|
|
||||||
next unless (dir = HOMEBREW_CELLAR/f).exist?
|
next unless (dir = HOMEBREW_CELLAR/f).exist?
|
||||||
@ -372,7 +374,7 @@ class Report
|
|||||||
user = $1
|
user = $1
|
||||||
repo = $2.sub("homebrew-", "")
|
repo = $2.sub("homebrew-", "")
|
||||||
oldname = path.basename(".rb").to_s
|
oldname = path.basename(".rb").to_s
|
||||||
next unless newname = Tap.new(user, repo).formula_renames[oldname]
|
next unless newname = Tap.fetch(user, repo).formula_renames[oldname]
|
||||||
else
|
else
|
||||||
oldname = path.basename(".rb").to_s
|
oldname = path.basename(".rb").to_s
|
||||||
next unless newname = FORMULA_RENAMES[oldname]
|
next unless newname = FORMULA_RENAMES[oldname]
|
||||||
|
|||||||
@ -273,7 +273,7 @@ class Formula
|
|||||||
end
|
end
|
||||||
elsif tap?
|
elsif tap?
|
||||||
user, repo = tap.split("/")
|
user, repo = tap.split("/")
|
||||||
formula_renames = Tap.new(user, repo.sub("homebrew-", "")).formula_renames
|
formula_renames = Tap.fetch(user, repo.sub("homebrew-", "")).formula_renames
|
||||||
if formula_renames.value?(name)
|
if formula_renames.value?(name)
|
||||||
formula_renames.to_a.rassoc(name).first
|
formula_renames.to_a.rassoc(name).first
|
||||||
end
|
end
|
||||||
|
|||||||
@ -145,7 +145,7 @@ class Formulary
|
|||||||
|
|
||||||
def initialize(tapped_name)
|
def initialize(tapped_name)
|
||||||
user, repo, name = tapped_name.split("/", 3).map(&:downcase)
|
user, repo, name = tapped_name.split("/", 3).map(&:downcase)
|
||||||
@tap = Tap.new user, repo.sub(/^homebrew-/, "")
|
@tap = Tap.fetch user, repo.sub(/^homebrew-/, "")
|
||||||
name = @tap.formula_renames.fetch(name, name)
|
name = @tap.formula_renames.fetch(name, name)
|
||||||
path = @tap.formula_files.detect { |file| file.basename(".rb").to_s == name }
|
path = @tap.formula_files.detect { |file| file.basename(".rb").to_s == name }
|
||||||
|
|
||||||
|
|||||||
@ -9,6 +9,17 @@ require "utils/json"
|
|||||||
class Tap
|
class Tap
|
||||||
TAP_DIRECTORY = HOMEBREW_LIBRARY/"Taps"
|
TAP_DIRECTORY = HOMEBREW_LIBRARY/"Taps"
|
||||||
|
|
||||||
|
CACHE = {}
|
||||||
|
|
||||||
|
def self.clear_cache
|
||||||
|
CACHE.clear
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.fetch(user, repo)
|
||||||
|
cache_key = "#{user}/#{repo}".downcase
|
||||||
|
CACHE.fetch(cache_key) { |key| CACHE[key] = Tap.new(user, repo) }
|
||||||
|
end
|
||||||
|
|
||||||
extend Enumerable
|
extend Enumerable
|
||||||
|
|
||||||
# The user name of this {Tap}. Usually, it's the Github username of
|
# The user name of this {Tap}. Usually, it's the Github username of
|
||||||
@ -86,31 +97,33 @@ class Tap
|
|||||||
|
|
||||||
# an array of all {Formula} files of this {Tap}.
|
# an array of all {Formula} files of this {Tap}.
|
||||||
def formula_files
|
def formula_files
|
||||||
dir = [@path/"Formula", @path/"HomebrewFormula", @path].detect(&:directory?)
|
@formula_files ||= if dir = [@path/"Formula", @path/"HomebrewFormula", @path].detect(&:directory?)
|
||||||
return [] unless dir
|
dir.children.select { |p| p.extname == ".rb" }
|
||||||
dir.children.select { |p| p.extname == ".rb" }
|
else
|
||||||
|
[]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# an array of all {Formula} names of this {Tap}.
|
# an array of all {Formula} names of this {Tap}.
|
||||||
def formula_names
|
def formula_names
|
||||||
formula_files.map { |f| "#{name}/#{f.basename(".rb")}" }
|
@formula_names ||= formula_files.map { |f| "#{name}/#{f.basename(".rb")}" }
|
||||||
end
|
end
|
||||||
|
|
||||||
# an array of all alias files of this {Tap}.
|
# an array of all alias files of this {Tap}.
|
||||||
# @private
|
# @private
|
||||||
def alias_files
|
def alias_files
|
||||||
Pathname.glob("#{path}/Aliases/*").select(&:file?)
|
@alias_files ||= Pathname.glob("#{path}/Aliases/*").select(&:file?)
|
||||||
end
|
end
|
||||||
|
|
||||||
# an array of all aliases of this {Tap}.
|
# an array of all aliases of this {Tap}.
|
||||||
# @private
|
# @private
|
||||||
def aliases
|
def aliases
|
||||||
alias_files.map { |f| "#{name}/#{f.basename}" }
|
@aliases ||= alias_files.map { |f| "#{name}/#{f.basename}" }
|
||||||
end
|
end
|
||||||
|
|
||||||
# an array of all commands files of this {Tap}.
|
# an array of all commands files of this {Tap}.
|
||||||
def command_files
|
def command_files
|
||||||
Pathname.glob("#{path}/cmd/brew-*").select(&:executable?)
|
@command_files ||= Pathname.glob("#{path}/cmd/brew-*").select(&:executable?)
|
||||||
end
|
end
|
||||||
|
|
||||||
def pinned_symlink_path
|
def pinned_symlink_path
|
||||||
@ -118,13 +131,15 @@ class Tap
|
|||||||
end
|
end
|
||||||
|
|
||||||
def pinned?
|
def pinned?
|
||||||
@pinned ||= pinned_symlink_path.directory?
|
return @pinned if instance_variable_defined?(:@pinned)
|
||||||
|
@pinned = pinned_symlink_path.directory?
|
||||||
end
|
end
|
||||||
|
|
||||||
def pin
|
def pin
|
||||||
raise TapUnavailableError, name unless installed?
|
raise TapUnavailableError, name unless installed?
|
||||||
raise TapPinStatusError.new(name, true) if pinned?
|
raise TapPinStatusError.new(name, true) if pinned?
|
||||||
pinned_symlink_path.make_relative_symlink(@path)
|
pinned_symlink_path.make_relative_symlink(@path)
|
||||||
|
@pinned = true
|
||||||
end
|
end
|
||||||
|
|
||||||
def unpin
|
def unpin
|
||||||
@ -132,6 +147,7 @@ class Tap
|
|||||||
raise TapPinStatusError.new(name, false) unless pinned?
|
raise TapPinStatusError.new(name, false) unless pinned?
|
||||||
pinned_symlink_path.delete
|
pinned_symlink_path.delete
|
||||||
pinned_symlink_path.dirname.rmdir_if_possible
|
pinned_symlink_path.dirname.rmdir_if_possible
|
||||||
|
@pinned = false
|
||||||
end
|
end
|
||||||
|
|
||||||
def to_hash
|
def to_hash
|
||||||
@ -170,7 +186,7 @@ class Tap
|
|||||||
|
|
||||||
TAP_DIRECTORY.subdirs.each do |user|
|
TAP_DIRECTORY.subdirs.each do |user|
|
||||||
user.subdirs.each do |repo|
|
user.subdirs.each do |repo|
|
||||||
yield new(user.basename.to_s, repo.basename.to_s.sub("homebrew-", ""))
|
yield fetch(user.basename.to_s, repo.basename.to_s.sub("homebrew-", ""))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user