brew/Library/Homebrew/linkage_cache_store.rb

122 lines
3.6 KiB
Ruby
Raw Normal View History

require "set"
require "cache_store"
#
2018-05-22 14:46:14 +01:00
# `LinkageCacheStore` provides methods to fetch and mutate linkage-specific data used
# by the `brew linkage` command
#
2018-05-22 14:46:14 +01:00
class LinkageCacheStore < CacheStore
# @param [String] keg_name
2018-05-22 14:46:14 +01:00
# @param [CacheStoreDatabase] database
# @return [nil]
2018-05-22 14:46:14 +01:00
def initialize(keg_name, database)
@keg_name = keg_name
2018-05-22 14:46:14 +01:00
super(database)
end
# Returns `true` if the database has any value for the current `keg_name`
#
# @return [Boolean]
def has_keg_name?
!database.get(keg_name).nil?
end
# Inserts dylib-related information into the cache if it does not exist or
# updates data into the linkage cache if it does exist
#
# @param [Hash] array_values: hash containing KVPs of { :type => Array | Set }
# @param [Hash] hash_values: hash containing KVPs of { :type => Hash }
# @param [Array[Hash]] values
# @raise [TypeError] error if the values are not `Arary`, `Set`, or `Hash`
# @return [nil]
def update!(array_values: {}, hash_values: {}, **values)
values.each do |key, value|
if value.is_a?(Hash)
hash_values[key] = value
elsif value.is_a?(Array) || value.is_a?(Set)
array_values[key] = value
2018-03-06 11:42:45 -05:00
else
raise TypeError, <<~EOS
Can't store types that are not `Array`, `Set` or `Hash` in the
linkage store.
EOS
end
end
2018-05-22 14:46:14 +01:00
database.set keg_name, ruby_hash_to_json_string(
array_values: format_array_values(array_values),
hash_values: format_hash_values(hash_values),
)
end
2018-05-22 14:46:14 +01:00
# @param [Symbol] the type to fetch from the `LinkageCacheStore`
# @raise [TypeError] error if the type is not in `HASH_LINKAGE_TYPES` or
# `ARRAY_LINKAGE_TYPES`
# @return [Hash | Array]
def fetch_type(type)
if HASH_LINKAGE_TYPES.include?(type)
fetch_hash_values(type)
2018-03-06 11:42:45 -05:00
elsif ARRAY_LINKAGE_TYPES.include?(type)
fetch_array_values(type)
2018-03-06 11:42:45 -05:00
else
raise TypeError, <<~EOS
Can't fetch types that are not defined for the linkage store
EOS
end
end
# @return [nil]
def flush_cache!
2018-05-22 14:46:14 +01:00
database.delete(keg_name)
end
private
2018-05-22 14:46:14 +01:00
ARRAY_LINKAGE_TYPES = [:system_dylibs, :variable_dylibs, :broken_dylibs,
:indirect_deps, :undeclared_deps, :unnecessary_deps].freeze
HASH_LINKAGE_TYPES = [:brewed_dylibs, :reverse_links, :broken_deps].freeze
# @return [String] the key to lookup items in the `CacheStore`
attr_reader :keg_name
2018-05-22 14:46:14 +01:00
# @param [Symbol] the type to fetch from the `LinkageCacheStore`
# @return [Array]
def fetch_array_values(type)
2018-05-22 14:46:14 +01:00
keg_cache = database.get(keg_name)
return [] unless keg_cache
json_string_to_ruby_hash(keg_cache)["array_values"][type.to_s]
end
# @param [Symbol] type
# @return [Hash]
def fetch_hash_values(type)
2018-05-22 14:46:14 +01:00
keg_cache = database.get(keg_name)
return {} unless keg_cache
json_string_to_ruby_hash(keg_cache)["hash_values"][type.to_s]
end
# Formats the linkage data for `array_values` into a kind which can be parsed
# by the `json_string_to_ruby_hash` method. Internally converts ruby `Set`s to
# `Array`s
#
# @param [Hash]
# @return [String]
def format_array_values(hash)
hash.each_with_object({}) { |(k, v), h| h[k] = v.to_a }
end
# Formats the linkage data for `hash_values` into a kind which can be parsed
# by the `json_string_to_ruby_hash` method. Converts ruby `Set`s to `Array`s,
# and converts ruby `Pathname`s to `String`s
#
# @param [Hash]
# @return [String]
def format_hash_values(hash)
hash.each_with_object({}) do |(outer_key, outer_values), outer_hash|
outer_hash[outer_key] = outer_values.each_with_object({}) do |(k, v), h|
h[k] = v.to_a.map(&:to_s)
end
end
end
end