Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 12 additions & 3 deletions Library/Homebrew/api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ module API

HOMEBREW_CACHE_API = T.let((HOMEBREW_CACHE/"api").freeze, Pathname)
HOMEBREW_CACHE_API_SOURCE = T.let((HOMEBREW_CACHE/"api-source").freeze, Pathname)
TAP_MIGRATIONS_STALE_SECONDS = T.let(86400, Integer) # 1 day

sig { params(endpoint: String).returns(T::Hash[String, T.untyped]) }
def self.fetch(endpoint)
Expand All @@ -33,11 +34,11 @@ def self.fetch(endpoint)
end

sig {
params(endpoint: String, target: Pathname,
stale_seconds: Integer).returns([T.any(T::Array[T.untyped], T::Hash[String, T.untyped]), T::Boolean])
params(endpoint: String, target: Pathname, stale_seconds: Integer, download_queue: T.nilable(DownloadQueue))
.returns([T.any(T::Array[T.untyped], T::Hash[String, T.untyped]), T::Boolean])
}
def self.fetch_json_api_file(endpoint, target: HOMEBREW_CACHE_API/endpoint,
stale_seconds: Homebrew::EnvConfig.api_auto_update_secs.to_i)
stale_seconds: Homebrew::EnvConfig.api_auto_update_secs.to_i, download_queue: nil)
# Lazy-load dependency.
require "development_tools"

Expand Down Expand Up @@ -65,6 +66,14 @@ def self.fetch_json_api_file(endpoint, target: HOMEBREW_CACHE_API/endpoint,
((Time.now - stale_seconds) < target.mtime))
skip_download ||= Homebrew.running_as_root_but_not_owned_by_root?

if download_queue
unless skip_download
download = Homebrew::API::Download.new(url, nil, cache: HOMEBREW_CACHE_API, require_checksum: false)
download_queue.enqueue(download)
end
return [{}, false]
end

json_data = begin
begin
args = curl_args.dup
Expand Down
31 changes: 30 additions & 1 deletion Library/Homebrew/api/cask.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
# frozen_string_literal: true

require "cachable"
require "api"
require "api/download"
require "download_queue"

module Homebrew
module API
Expand Down Expand Up @@ -52,9 +54,26 @@ def self.cached_json_file_path
HOMEBREW_CACHE_API/api_filename
end

sig {
params(download_queue: T.nilable(::Homebrew::DownloadQueue))
.returns([T.any(T::Array[T.untyped], T::Hash[String, T.untyped]), T::Boolean])
}
def self.fetch_api!(download_queue: nil)
Homebrew::API.fetch_json_api_file api_filename, download_queue:
end

sig {
params(download_queue: T.nilable(::Homebrew::DownloadQueue))
.returns([T.any(T::Array[T.untyped], T::Hash[String, T.untyped]), T::Boolean])
}
def self.fetch_tap_migrations!(download_queue: nil)
stale_seconds = Homebrew::API::TAP_MIGRATIONS_STALE_SECONDS
Homebrew::API.fetch_json_api_file "cask_tap_migrations.jws.json", stale_seconds:, download_queue:
end

sig { returns(T::Boolean) }
def self.download_and_cache_data!
json_casks, updated = Homebrew::API.fetch_json_api_file api_filename
json_casks, updated = fetch_api!

cache["renames"] = {}
cache["casks"] = json_casks.to_h do |json_cask|
Expand Down Expand Up @@ -91,6 +110,16 @@ def self.all_renames
cache.fetch("renames")
end

sig { returns(T::Hash[String, T.untyped]) }
def self.tap_migrations
unless cache.key?("tap_migrations")
json_migrations, = fetch_tap_migrations!
cache["tap_migrations"] = json_migrations
end

cache.fetch("tap_migrations")
end

sig { params(regenerate: T::Boolean).void }
def self.write_names(regenerate: false)
download_and_cache_data! unless cache.key?("casks")
Expand Down
19 changes: 14 additions & 5 deletions Library/Homebrew/api/download.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,20 @@ class Download

sig {
params(
url: String,
checksum: T.nilable(Checksum),
mirrors: T::Array[String],
cache: T.nilable(Pathname),
url: String,
checksum: T.nilable(Checksum),
mirrors: T::Array[String],
cache: T.nilable(Pathname),
require_checksum: T::Boolean,
).void
}
def initialize(url, checksum, mirrors: [], cache: nil)
def initialize(url, checksum, mirrors: [], cache: nil, require_checksum: true)
super()
@url = T.let(URL.new(url, using: API::DownloadStrategy), URL)
@checksum = checksum
@mirrors = mirrors
@cache = cache
@require_checksum = require_checksum
end

sig { override.returns(API::DownloadStrategy) }
Expand All @@ -55,6 +57,13 @@ def cache
def symlink_location
downloader.symlink_location
end

private

sig { override.returns(T::Boolean) }
def silence_checksum_missing_error?
!@require_checksum
end
end
end
end
45 changes: 26 additions & 19 deletions Library/Homebrew/api/formula.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
# frozen_string_literal: true

require "cachable"
require "api"
require "api/download"
require "download_queue"

module Homebrew
module API
Expand Down Expand Up @@ -52,9 +54,26 @@ def self.cached_json_file_path
HOMEBREW_CACHE_API/api_filename
end

sig {
params(download_queue: T.nilable(Homebrew::DownloadQueue))
.returns([T.any(T::Array[T.untyped], T::Hash[String, T.untyped]), T::Boolean])
}
def self.fetch_api!(download_queue: nil)
Homebrew::API.fetch_json_api_file api_filename, download_queue:
end

sig {
params(download_queue: T.nilable(Homebrew::DownloadQueue))
.returns([T.any(T::Array[T.untyped], T::Hash[String, T.untyped]), T::Boolean])
}
def self.fetch_tap_migrations!(download_queue: nil)
stale_seconds = Homebrew::API::TAP_MIGRATIONS_STALE_SECONDS
Homebrew::API.fetch_json_api_file "formula_tap_migrations.jws.json", stale_seconds:, download_queue:
end

sig { returns(T::Boolean) }
def self.download_and_cache_data!
json_formulae, updated = Homebrew::API.fetch_json_api_file api_filename
json_formulae, updated = fetch_api!

cache["aliases"] = {}
cache["renames"] = {}
Expand All @@ -80,7 +99,7 @@ def self.all_formulae
write_names_and_aliases(regenerate: json_updated)
end

cache["formulae"]
cache.fetch("formulae")
end

sig { returns(T::Hash[String, String]) }
Expand All @@ -90,7 +109,7 @@ def self.all_aliases
write_names_and_aliases(regenerate: json_updated)
end

cache["aliases"]
cache.fetch("aliases")
end

sig { returns(T::Hash[String, String]) }
Expand All @@ -100,29 +119,17 @@ def self.all_renames
write_names_and_aliases(regenerate: json_updated)
end

cache["renames"]
cache.fetch("renames")
end

sig { returns(T::Hash[String, T.untyped]) }
def self.tap_migrations
# Not sure that we need to reload here.
unless cache.key?("tap_migrations")
json_updated = download_and_cache_data!
write_names_and_aliases(regenerate: json_updated)
end

cache["tap_migrations"]
end

sig { returns(String) }
def self.tap_git_head
# Note sure we need to reload here.
unless cache.key?("tap_git_head")
json_updated = download_and_cache_data!
write_names_and_aliases(regenerate: json_updated)
json_migrations, = fetch_tap_migrations!
cache["tap_migrations"] = json_migrations
end

cache["tap_git_head"]
cache.fetch("tap_migrations")
end

sig { params(regenerate: T::Boolean).void }
Expand Down
17 changes: 17 additions & 0 deletions Library/Homebrew/brew.rb
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,23 @@
cmd_class = Homebrew::AbstractCommand.command(cmd)
Homebrew.running_command = cmd
if cmd_class
if Homebrew::EnvConfig.download_concurrency > 1
require "download_queue"
require "api"
require "api/formula"
require "api/cask"
download_queue = Homebrew::DownloadQueue.new
Homebrew::API::Formula.fetch_api!(download_queue:)
Homebrew::API::Formula.fetch_tap_migrations!(download_queue:)
Homebrew::API::Cask.fetch_api!(download_queue:)
Homebrew::API::Cask.fetch_tap_migrations!(download_queue:)
begin
download_queue.fetch
ensure
download_queue.shutdown
end
end

command_instance = cmd_class.new

require "utils/analytics"
Expand Down
2 changes: 2 additions & 0 deletions Library/Homebrew/download_queue.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ def enqueue(downloadable)
if pour && download.bottle?
UnpackStrategy.detect(download.cached_download, prioritize_extension: true)
.extract_nestedly(to: HOMEBREW_CELLAR)
elsif download.api?
FileUtils.touch(download.cached_download, mtime: Time.now)
end
end
end
Expand Down
3 changes: 3 additions & 0 deletions Library/Homebrew/retryable_download.rb
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,9 @@ def download_name = downloadable.download_name
sig { returns(T::Boolean) }
def bottle? = downloadable.is_a?(Bottle)

sig { returns(T::Boolean) }
def api? = downloadable.is_a?(API::Download)

private

sig { returns(Downloadable) }
Expand Down
11 changes: 2 additions & 9 deletions Library/Homebrew/tap.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,6 @@ class Tap
HOMEBREW_TAP_STYLE_EXCEPTIONS_DIR = "style_exceptions"
private_constant :HOMEBREW_TAP_STYLE_EXCEPTIONS_DIR

TAP_MIGRATIONS_STALE_SECONDS = 86400 # 1 day
private_constant :TAP_MIGRATIONS_STALE_SECONDS

HOMEBREW_TAP_JSON_FILES = %W[
#{HOMEBREW_TAP_FORMULA_RENAMES_FILE}
#{HOMEBREW_TAP_CASK_RENAMES_FILE}
Expand Down Expand Up @@ -1312,9 +1309,7 @@ def tap_migrations
ensure_installed!
super
else
migrations, = Homebrew::API.fetch_json_api_file "formula_tap_migrations.jws.json",
stale_seconds: TAP_MIGRATIONS_STALE_SECONDS
migrations
Homebrew::API::Formula.tap_migrations
end
end

Expand Down Expand Up @@ -1471,9 +1466,7 @@ def tap_migrations
@tap_migrations ||= if Homebrew::EnvConfig.no_install_from_api?
super
else
migrations, = Homebrew::API.fetch_json_api_file "cask_tap_migrations.jws.json",
stale_seconds: TAP_MIGRATIONS_STALE_SECONDS
migrations
Homebrew::API::Cask.tap_migrations
end
end
end
Expand Down
Loading