2018-03-06 12:07:57 -05:00
|
|
|
require "set"
|
2018-02-28 10:39:15 -05:00
|
|
|
require "cache_store"
|
|
|
|
|
|
|
|
#
|
|
|
|
# `LinkageStore` provides methods to fetch and mutate linkage-specific data used
|
|
|
|
# by the `brew linkage` command
|
|
|
|
#
|
|
|
|
class LinkageStore < CacheStore
|
2018-03-06 11:42:45 -05:00
|
|
|
ARRAY_LINKAGE_TYPES = [:system_dylibs, :variable_dylibs, :broken_dylibs,
|
|
|
|
:indirect_deps, :undeclared_deps, :unnecessary_deps].freeze
|
2018-04-09 14:00:48 -04:00
|
|
|
HASH_LINKAGE_TYPES = [:brewed_dylibs, :reverse_links, :broken_deps].freeze
|
2018-02-28 10:39:15 -05:00
|
|
|
|
|
|
|
# @param [String] keg_name
|
2018-05-18 16:37:01 -04:00
|
|
|
# @param [DBM] db
|
2018-02-28 10:39:15 -05:00
|
|
|
# @return [nil]
|
2018-05-18 16:37:01 -04:00
|
|
|
def initialize(keg_name, db)
|
2018-02-28 10:39:15 -05:00
|
|
|
@keg_name = keg_name
|
2018-05-18 16:37:01 -04:00
|
|
|
super(db)
|
2018-02-28 10:39:15 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
# Inserts dylib-related information into the cache if it does not exist or
|
|
|
|
# updates data into the linkage cache if it does exist
|
|
|
|
#
|
2018-03-06 13:39:34 -05:00
|
|
|
# @param [Hash] array_values: hash containing KVPs of { :type => Array | Set }
|
|
|
|
# @param [Hash] hash_values: hash containing KVPs of { :type => Hash }
|
2018-02-28 10:39:15 -05:00
|
|
|
# @param [Array[Hash]] values
|
2018-03-06 13:39:34 -05:00
|
|
|
# @raise [TypeError] error if the values are not `Arary`, `Set`, or `Hash`
|
2018-02-28 10:39:15 -05:00
|
|
|
# @return [nil]
|
|
|
|
def update!(array_values: {}, hash_values: {}, **values)
|
|
|
|
values.each do |key, value|
|
2018-03-06 12:07:57 -05:00
|
|
|
if value.is_a?(Hash)
|
2018-02-28 10:39:15 -05:00
|
|
|
hash_values[key] = value
|
2018-03-06 12:07:57 -05:00
|
|
|
elsif value.is_a?(Array) || value.is_a?(Set)
|
2018-02-28 10:39:15 -05:00
|
|
|
array_values[key] = value
|
2018-03-06 11:42:45 -05:00
|
|
|
else
|
2018-03-06 13:39:34 -05:00
|
|
|
raise TypeError, <<~EOS
|
|
|
|
Can't store types that are not `Array`, `Set` or `Hash` in the
|
|
|
|
linkage store.
|
|
|
|
EOS
|
2018-02-28 10:39:15 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2018-05-18 16:37:01 -04:00
|
|
|
db[keg_name] = ruby_hash_to_json_string(
|
2018-02-28 10:39:15 -05:00
|
|
|
array_values: format_array_values(array_values),
|
|
|
|
hash_values: format_hash_values(hash_values),
|
|
|
|
)
|
|
|
|
end
|
|
|
|
|
2018-03-06 11:42:45 -05:00
|
|
|
# @param [Symbol] the type to fetch from the `LinkageStore`
|
2018-03-06 13:39:34 -05:00
|
|
|
# @raise [TypeError] error if the type is not in `HASH_LINKAGE_TYPES` or
|
|
|
|
# `ARRAY_LINKAGE_TYPES`
|
2018-02-28 10:39:15 -05:00
|
|
|
# @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)
|
2018-02-28 10:39:15 -05:00
|
|
|
fetch_array_values(type)
|
2018-03-06 11:42:45 -05:00
|
|
|
else
|
2018-03-06 13:39:34 -05:00
|
|
|
raise TypeError, <<~EOS
|
|
|
|
Can't fetch types that are not defined for the linkage store
|
|
|
|
EOS
|
2018-02-28 10:39:15 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
# @return [nil]
|
|
|
|
def flush_cache!
|
2018-05-18 16:37:01 -04:00
|
|
|
db.delete(keg_name)
|
2018-02-28 10:39:15 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
private
|
|
|
|
|
2018-03-06 13:39:34 -05:00
|
|
|
# @return [String] the key to lookup items in the `CacheStore`
|
2018-02-28 10:39:15 -05:00
|
|
|
attr_reader :keg_name
|
|
|
|
|
2018-03-06 13:39:34 -05:00
|
|
|
# @param [Symbol] the type to fetch from the `LinkageStore`
|
2018-02-28 10:39:15 -05:00
|
|
|
# @return [Array]
|
|
|
|
def fetch_array_values(type)
|
2018-05-18 16:37:01 -04:00
|
|
|
return [] unless db.key?(keg_name)
|
|
|
|
json_string_to_ruby_hash(db[keg_name])["array_values"][type.to_s]
|
2018-02-28 10:39:15 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
# @param [Symbol] type
|
|
|
|
# @return [Hash]
|
|
|
|
def fetch_hash_values(type)
|
2018-05-18 16:37:01 -04:00
|
|
|
return {} unless db.key?(keg_name)
|
|
|
|
json_string_to_ruby_hash(db[keg_name])["hash_values"][type.to_s]
|
2018-02-28 10:39:15 -05:00
|
|
|
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
|