mirror of
https://github.com/Homebrew/brew.git
synced 2025-07-14 16:09:03 +08:00
152 lines
4.2 KiB
Ruby
152 lines
4.2 KiB
Ruby
![]() |
require "formula"
|
||
|
require "csv"
|
||
|
|
||
|
class Descriptions
|
||
|
CACHE_FILE = HOMEBREW_CACHE + "desc_cache"
|
||
|
|
||
|
def self.cache
|
||
|
@cache || self.load_cache
|
||
|
end
|
||
|
|
||
|
# If the cache file exists, load it into, and return, a hash; otherwise,
|
||
|
# return nil.
|
||
|
def self.load_cache
|
||
|
if CACHE_FILE.exist?
|
||
|
@cache = {}
|
||
|
CSV.foreach(CACHE_FILE) { |name, desc| @cache[name] = desc }
|
||
|
@cache
|
||
|
end
|
||
|
end
|
||
|
|
||
|
# Write the cache to disk after ensuring the existence of the containing
|
||
|
# directory.
|
||
|
def self.save_cache
|
||
|
HOMEBREW_CACHE.mkpath
|
||
|
CSV.open(CACHE_FILE, 'w') do |csv|
|
||
|
@cache.each do |name, desc|
|
||
|
csv << [name, desc]
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
# Create a hash mapping all formulae to their descriptions;
|
||
|
# save it for future use.
|
||
|
def self.generate_cache
|
||
|
@cache = {}
|
||
|
Formula.map do |f|
|
||
|
@cache[f.full_name] = f.desc
|
||
|
end
|
||
|
self.save_cache
|
||
|
end
|
||
|
|
||
|
# Return true if the cache exists, and neither Homebrew nor any of the Taps
|
||
|
# repos were updated more recently than it was.
|
||
|
def self.cache_fresh?
|
||
|
if CACHE_FILE.exist?
|
||
|
cache_date = File.mtime(CACHE_FILE)
|
||
|
|
||
|
ref_master = ".git/refs/heads/master"
|
||
|
master = HOMEBREW_REPOSITORY/ref_master
|
||
|
|
||
|
last_update = (master.exist? ? File.mtime(master) : Time.at(0))
|
||
|
|
||
|
Dir.glob(HOMEBREW_LIBRARY/"Taps/**"/ref_master).each do |repo|
|
||
|
repo_mtime = File.mtime(repo)
|
||
|
last_update = repo_mtime if repo_mtime > last_update
|
||
|
end
|
||
|
last_update <= cache_date
|
||
|
end
|
||
|
end
|
||
|
|
||
|
# Create the cache if it doesn't already exist.
|
||
|
def self.ensure_cache
|
||
|
self.generate_cache unless self.cache_fresh? && self.cache
|
||
|
end
|
||
|
|
||
|
# Take a {Report}, as generated by cmd/update.rb.
|
||
|
# Unless the cache file exists, do nothing.
|
||
|
# If it does exist, but the Report is empty, just touch the cache file.
|
||
|
# Otherwise, use the report to update the cache.
|
||
|
def self.update_cache(report)
|
||
|
if CACHE_FILE.exist?
|
||
|
if report.empty?
|
||
|
FileUtils.touch CACHE_FILE
|
||
|
else
|
||
|
renamings = report.select_formula(:R)
|
||
|
alterations = report.select_formula(:A) + report.select_formula(:M) +
|
||
|
renamings.map(&:last)
|
||
|
self.cache_formulae(alterations, :save => false)
|
||
|
self.uncache_formulae(report.select_formula(:D) +
|
||
|
renamings.map(&:first))
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
# Given an array of formula names, add them and their descriptions to the
|
||
|
# cache. Save the updated cache to disk, unless explicitly told not to.
|
||
|
def self.cache_formulae(formula_names, options = { :save => true })
|
||
|
if self.cache
|
||
|
formula_names.each { |name| @cache[name] = Formula[name].desc }
|
||
|
self.save_cache if options[:save]
|
||
|
end
|
||
|
end
|
||
|
|
||
|
# Given an array of formula names, remove them and their descriptions from
|
||
|
# the cache. Save the updated cache to disk, unless explicitly told not to.
|
||
|
def self.uncache_formulae(formula_names, options = { :save => true })
|
||
|
if self.cache
|
||
|
formula_names.each { |name| @cache.delete(name) }
|
||
|
self.save_cache if options[:save]
|
||
|
end
|
||
|
end
|
||
|
|
||
|
# Given an array of formula names, return a {Descriptions} object mapping
|
||
|
# those names to their descriptions.
|
||
|
def self.named(names)
|
||
|
self.ensure_cache
|
||
|
|
||
|
results = {}
|
||
|
unless names.empty?
|
||
|
results = names.inject({}) do |accum, name|
|
||
|
accum[name] = @cache[name]
|
||
|
accum
|
||
|
end
|
||
|
end
|
||
|
|
||
|
new(results)
|
||
|
end
|
||
|
|
||
|
# Given a regex, find all formulae whose specified fields contain a match.
|
||
|
def self.search(regex, field = :either)
|
||
|
self.ensure_cache
|
||
|
|
||
|
results = case field
|
||
|
when :name
|
||
|
@cache.select { |name, _| name =~ regex }
|
||
|
when :desc
|
||
|
@cache.select { |_, desc| desc =~ regex }
|
||
|
when :either
|
||
|
@cache.select { |name, desc| (name =~ regex) || (desc =~ regex) }
|
||
|
end
|
||
|
|
||
|
results = Hash[results] if RUBY_VERSION <= "1.8.7"
|
||
|
|
||
|
new(results)
|
||
|
end
|
||
|
|
||
|
# Create an actual instance.
|
||
|
def initialize(descriptions)
|
||
|
@descriptions = descriptions
|
||
|
end
|
||
|
|
||
|
# Take search results -- a hash mapping formula names to descriptions -- and
|
||
|
# print them.
|
||
|
def print
|
||
|
blank = "#{Tty.yellow}[no description]#{Tty.reset}"
|
||
|
@descriptions.keys.sort.each do |name|
|
||
|
description = @descriptions[name] || blank
|
||
|
puts "#{Tty.white}#{name}:#{Tty.reset} #{description}"
|
||
|
end
|
||
|
end
|
||
|
end
|