Load casks from the JSON API with HOMEBREW_INSTALL_FROM_API
This commit is contained in:
parent
ea0b786388
commit
374b61584b
@ -10,10 +10,45 @@ module Homebrew
|
|||||||
class << self
|
class << self
|
||||||
extend T::Sig
|
extend T::Sig
|
||||||
|
|
||||||
|
MAX_RETRIES = 3
|
||||||
|
|
||||||
|
sig { returns(String) }
|
||||||
|
def cached_cask_json_file
|
||||||
|
HOMEBREW_CACHE_API/"cask.json"
|
||||||
|
end
|
||||||
|
|
||||||
sig { params(name: String).returns(Hash) }
|
sig { params(name: String).returns(Hash) }
|
||||||
def fetch(name)
|
def fetch(name)
|
||||||
Homebrew::API.fetch "cask/#{name}.json"
|
Homebrew::API.fetch "cask/#{name}.json"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { returns(Hash) }
|
||||||
|
def all_casks
|
||||||
|
@all_casks ||= begin
|
||||||
|
retry_count = 0
|
||||||
|
|
||||||
|
url = "https://formulae.brew.sh/api/cask.json"
|
||||||
|
json_casks = begin
|
||||||
|
curl_args = %W[--compressed --silent #{url}]
|
||||||
|
if cached_cask_json_file.exist? && !cached_cask_json_file.empty?
|
||||||
|
curl_args.prepend("--time-cond", cached_cask_json_file)
|
||||||
|
end
|
||||||
|
curl_download(*curl_args, to: cached_cask_json_file, max_time: 5)
|
||||||
|
|
||||||
|
JSON.parse(cached_cask_json_file.read)
|
||||||
|
rescue JSON::ParserError
|
||||||
|
cached_cask_json_file.unlink
|
||||||
|
retry_count += 1
|
||||||
|
odie "Cannot download non-corrupt #{url}!" if retry_count > MAX_RETRIES
|
||||||
|
|
||||||
|
retry
|
||||||
|
end
|
||||||
|
|
||||||
|
json_casks.to_h do |json_cask|
|
||||||
|
[json_cask["token"], json_cask.except("token")]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -186,6 +186,91 @@ module Cask
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Loads a cask from the JSON API.
|
||||||
|
class FromAPILoader
|
||||||
|
attr_reader :token, :path
|
||||||
|
|
||||||
|
FLIGHT_STANZAS = [:preflight, :postflight, :uninstall_preflight, :uninstall_postflight].freeze
|
||||||
|
|
||||||
|
def self.can_load?(ref)
|
||||||
|
Homebrew::API::Cask.all_casks.key? ref
|
||||||
|
end
|
||||||
|
|
||||||
|
def initialize(token)
|
||||||
|
@token = token
|
||||||
|
@path = CaskLoader.default_path(token)
|
||||||
|
end
|
||||||
|
|
||||||
|
def load(config:)
|
||||||
|
json_cask = Homebrew::API::Cask.all_casks[token]
|
||||||
|
cask_source = Homebrew::API::CaskSource.fetch(token)
|
||||||
|
|
||||||
|
if (bottle_tag = ::Utils::Bottles.tag.to_s.presence) &&
|
||||||
|
(variations = json_cask["variations"].presence) &&
|
||||||
|
(variation = variations[bottle_tag].presence)
|
||||||
|
json_cask = json_cask.merge(variation)
|
||||||
|
end
|
||||||
|
|
||||||
|
json_cask.deep_symbolize_keys!
|
||||||
|
|
||||||
|
Cask.new(token, source: cask_source, config: config) do
|
||||||
|
version json_cask[:version]
|
||||||
|
|
||||||
|
if json_cask[:sha256] == "no_check"
|
||||||
|
sha256 :no_check
|
||||||
|
else
|
||||||
|
sha256 json_cask[:sha256]
|
||||||
|
end
|
||||||
|
|
||||||
|
url json_cask[:url]
|
||||||
|
appcast json_cask[:appcast] if json_cask[:appcast].present?
|
||||||
|
json_cask[:name].each do |cask_name|
|
||||||
|
name cask_name
|
||||||
|
end
|
||||||
|
desc json_cask[:desc]
|
||||||
|
homepage json_cask[:homepage]
|
||||||
|
|
||||||
|
auto_updates json_cask[:auto_updates] if json_cask[:auto_updates].present?
|
||||||
|
conflicts_with(**json_cask[:conflicts_with]) if json_cask[:conflicts_with].present?
|
||||||
|
|
||||||
|
if json_cask[:depends_on].present?
|
||||||
|
dep_hash = json_cask[:depends_on].to_h do |dep_key, dep_value|
|
||||||
|
next [dep_key, dep_value] unless dep_key == :macos
|
||||||
|
|
||||||
|
dep_type = dep_value.keys.first
|
||||||
|
if dep_type == :==
|
||||||
|
version_symbols = dep_value[dep_type].map do |version|
|
||||||
|
MacOSVersions::SYMBOLS.key(version) || version
|
||||||
|
end
|
||||||
|
next [dep_key, version_symbols]
|
||||||
|
end
|
||||||
|
|
||||||
|
version_symbol = dep_value[dep_type].first
|
||||||
|
version_symbol = MacOSVersions::SYMBOLS.key(version_symbol) || version_symbol
|
||||||
|
[dep_key, "#{dep_type} :#{version_symbol}"]
|
||||||
|
end.compact
|
||||||
|
depends_on(**dep_hash)
|
||||||
|
end
|
||||||
|
|
||||||
|
if json_cask[:container].present?
|
||||||
|
container_hash = json_cask[:container].to_h do |container_key, container_value|
|
||||||
|
next [container_key, container_value] unless container_key == :type
|
||||||
|
|
||||||
|
[container_key, container_value.to_sym]
|
||||||
|
end
|
||||||
|
container(**container_hash)
|
||||||
|
end
|
||||||
|
|
||||||
|
json_cask[:artifacts].each do |artifact|
|
||||||
|
key = artifact.keys.first
|
||||||
|
send(key, *artifact[key])
|
||||||
|
end
|
||||||
|
|
||||||
|
caveats json_cask[:caveats] if json_cask[:caveats].present?
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# Pseudo-loader which raises an error when trying to load the corresponding cask.
|
# Pseudo-loader which raises an error when trying to load the corresponding cask.
|
||||||
class NullLoader < FromPathLoader
|
class NullLoader < FromPathLoader
|
||||||
extend T::Sig
|
extend T::Sig
|
||||||
@ -225,15 +310,15 @@ module Cask
|
|||||||
next unless loader_class.can_load?(ref)
|
next unless loader_class.can_load?(ref)
|
||||||
|
|
||||||
if loader_class == FromTapLoader && Homebrew::EnvConfig.install_from_api? &&
|
if loader_class == FromTapLoader && Homebrew::EnvConfig.install_from_api? &&
|
||||||
ref.start_with?("homebrew/cask/") && Homebrew::API::CaskSource.available?(ref)
|
ref.start_with?("homebrew/cask/") && FromAPILoader.can_load?(ref)
|
||||||
return FromContentLoader.new(Homebrew::API::CaskSource.fetch(ref))
|
return FromAPILoader.new(ref)
|
||||||
end
|
end
|
||||||
|
|
||||||
return loader_class.new(ref)
|
return loader_class.new(ref)
|
||||||
end
|
end
|
||||||
|
|
||||||
if Homebrew::EnvConfig.install_from_api? && !need_path && Homebrew::API::CaskSource.available?(ref)
|
if Homebrew::EnvConfig.install_from_api? && !need_path && Homebrew::API::CaskSource.available?(ref)
|
||||||
return FromContentLoader.new(Homebrew::API::CaskSource.fetch(ref))
|
return FromAPILoader.new(ref)
|
||||||
end
|
end
|
||||||
|
|
||||||
return FromTapPathLoader.new(default_path(ref)) if FromTapPathLoader.can_load?(default_path(ref))
|
return FromTapPathLoader.new(default_path(ref)) if FromTapPathLoader.can_load?(default_path(ref))
|
||||||
|
|||||||
@ -754,28 +754,32 @@ EOS
|
|||||||
if [[ -n "${HOMEBREW_INSTALL_FROM_API}" ]]
|
if [[ -n "${HOMEBREW_INSTALL_FROM_API}" ]]
|
||||||
then
|
then
|
||||||
mkdir -p "${HOMEBREW_CACHE}/api"
|
mkdir -p "${HOMEBREW_CACHE}/api"
|
||||||
if [[ -f "${HOMEBREW_CACHE}/api/formula.json" ]]
|
|
||||||
|
for formula_or_cask in formula cask
|
||||||
|
do
|
||||||
|
if [[ -f "${HOMEBREW_CACHE}/api/${formula_or_cask}.json" ]]
|
||||||
then
|
then
|
||||||
INITIAL_JSON_BYTESIZE="$(wc -c "${HOMEBREW_CACHE}"/api/formula.json)"
|
INITIAL_JSON_BYTESIZE="$(wc -c "${HOMEBREW_CACHE}"/api/"${formula_or_cask}".json)"
|
||||||
fi
|
fi
|
||||||
curl \
|
curl \
|
||||||
"${CURL_DISABLE_CURLRC_ARGS[@]}" \
|
"${CURL_DISABLE_CURLRC_ARGS[@]}" \
|
||||||
--fail --compressed --silent --max-time 5 \
|
--fail --compressed --silent --max-time 5 \
|
||||||
--location --remote-time --output "${HOMEBREW_CACHE}/api/formula.json" \
|
--location --remote-time --output "${HOMEBREW_CACHE}/api/${formula_or_cask}.json" \
|
||||||
--time-cond "${HOMEBREW_CACHE}/api/formula.json" \
|
--time-cond "${HOMEBREW_CACHE}/api/${formula_or_cask}.json" \
|
||||||
--user-agent "${HOMEBREW_USER_AGENT_CURL}" \
|
--user-agent "${HOMEBREW_USER_AGENT_CURL}" \
|
||||||
"https://formulae.brew.sh/api/formula.json"
|
"https://formulae.brew.sh/api/${formula_or_cask}.json"
|
||||||
curl_exit_code=$?
|
curl_exit_code=$?
|
||||||
if [[ ${curl_exit_code} -eq 0 ]]
|
if [[ ${curl_exit_code} -eq 0 ]]
|
||||||
then
|
then
|
||||||
CURRENT_JSON_BYTESIZE="$(wc -c "${HOMEBREW_CACHE}"/api/formula.json)"
|
CURRENT_JSON_BYTESIZE="$(wc -c "${HOMEBREW_CACHE}"/api/"${formula_or_cask}".json)"
|
||||||
if [[ "${INITIAL_JSON_BYTESIZE}" != "${CURRENT_JSON_BYTESIZE}" ]]
|
if [[ "${INITIAL_JSON_BYTESIZE}" != "${CURRENT_JSON_BYTESIZE}" ]]
|
||||||
then
|
then
|
||||||
HOMEBREW_UPDATED="1"
|
HOMEBREW_UPDATED="1"
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
echo "Failed to download formula.json!" >>"${update_failed_file}"
|
echo "Failed to download ${formula_or_cask}.json!" >>"${update_failed_file}"
|
||||||
fi
|
fi
|
||||||
|
done
|
||||||
fi
|
fi
|
||||||
|
|
||||||
safe_cd "${HOMEBREW_REPOSITORY}"
|
safe_cd "${HOMEBREW_REPOSITORY}"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user