From f7f04bae26bbe7157fdfc2abb178eff91f215584 Mon Sep 17 00:00:00 2001 From: Mike McQuaid Date: Thu, 16 Feb 2023 12:05:38 +0000 Subject: [PATCH] api: use formulae.brew.sh for cask-source API again. GitHub's raw endpoint is proving hilariously unreliable for us here. --- Library/Homebrew/api.rb | 30 ++++++++++++++++++-------- Library/Homebrew/api/cask.rb | 2 +- Library/Homebrew/test/api/cask_spec.rb | 1 + Library/Homebrew/test/api_spec.rb | 10 ++++++--- 4 files changed, 30 insertions(+), 13 deletions(-) diff --git a/Library/Homebrew/api.rb b/Library/Homebrew/api.rb index aa8f782652..12d076c95f 100644 --- a/Library/Homebrew/api.rb +++ b/Library/Homebrew/api.rb @@ -94,17 +94,29 @@ module Homebrew end end - sig { params(filepath: String, repo: String, git_head: T.nilable(String)).returns(String) } - def self.fetch_file_source(filepath, repo:, git_head: nil) - git_head ||= "master" - endpoint = "#{git_head}/#{filepath}" - return cache[endpoint] if cache.present? && cache.key?(endpoint) + sig { params(name: String, git_head: T.nilable(String)).returns(String) } + def self.fetch_homebrew_cask_source(name, git_head: nil) + git_head = "master" if git_head.blank? + raw_endpoint = "#{git_head}/Casks/#{name}.rb" + return cache[raw_endpoint] if cache.present? && cache.key?(raw_endpoint) - raw_url = "https://raw.githubusercontent.com/#{repo}/#{endpoint}" - output = Utils::Curl.curl_output("--fail", raw_url) - raise ArgumentError, "No file found at #{Tty.underline}#{raw_url}#{Tty.reset}" unless output.success? + # This API sometimes returns random 404s so needs a fallback at formulae.brew.sh. + raw_source_url = "https://raw.githubusercontent.com/Homebrew/homebrew-cask/#{raw_endpoint}" + api_source_url = "#{HOMEBREW_API_DEFAULT_DOMAIN}/cask-source/#{name}.rb" + output = Utils::Curl.curl_output("--fail", raw_source_url) - cache[endpoint] = output.stdout + if !output.success? || output.blank? + output = Utils::Curl.curl_output("--fail", api_source_url) + if !output.success? || output.blank? + raise ArgumentError, <<~EOS + No valid file found at either of: + #{Tty.underline}#{raw_source_url}#{Tty.reset} + #{Tty.underline}#{api_source_url}#{Tty.reset} + EOS + end + end + + cache[raw_endpoint] = output.stdout end sig { params(json: Hash).returns(Hash) } diff --git a/Library/Homebrew/api/cask.rb b/Library/Homebrew/api/cask.rb index fab01bb288..a4dac3540e 100644 --- a/Library/Homebrew/api/cask.rb +++ b/Library/Homebrew/api/cask.rb @@ -17,7 +17,7 @@ module Homebrew sig { params(token: String, git_head: T.nilable(String)).returns(String) } def fetch_source(token, git_head: nil) - Homebrew::API.fetch_file_source "Casks/#{token}.rb", repo: "Homebrew/homebrew-cask", git_head: git_head + Homebrew::API.fetch_homebrew_cask_source token, git_head: git_head end sig { returns(Hash) } diff --git a/Library/Homebrew/test/api/cask_spec.rb b/Library/Homebrew/test/api/cask_spec.rb index 5fb66577dc..36e08b7076 100644 --- a/Library/Homebrew/test/api/cask_spec.rb +++ b/Library/Homebrew/test/api/cask_spec.rb @@ -8,6 +8,7 @@ describe Homebrew::API::Cask do before do stub_const("Homebrew::API::HOMEBREW_CACHE_API", cache_dir) + Homebrew::API.clear_cache end def mock_curl_download(stdout:) diff --git a/Library/Homebrew/test/api_spec.rb b/Library/Homebrew/test/api_spec.rb index 6d639e5c0f..e001f269fb 100644 --- a/Library/Homebrew/test/api_spec.rb +++ b/Library/Homebrew/test/api_spec.rb @@ -9,6 +9,10 @@ describe Homebrew::API do let(:json_hash) { JSON.parse(json) } let(:json_invalid) { '{"foo":"bar"' } + before do + described_class.clear_cache + end + def mock_curl_output(stdout: "", success: true) curl_output = OpenStruct.new(stdout: stdout, success?: success) allow(Utils::Curl).to receive(:curl_output).and_return curl_output @@ -68,15 +72,15 @@ describe Homebrew::API do describe "::fetch_file_source" do it "fetches a file" do mock_curl_output stdout: json - fetched_json = described_class.fetch_file_source("foo.json", repo: "Homebrew/homebrew-core", git_head: "master") + fetched_json = described_class.fetch_homebrew_cask_source("foo", git_head: "master") expect(fetched_json).to eq json end it "raises an error if the file does not exist" do mock_curl_output success: false expect { - described_class.fetch_file_source("bar.txt", repo: "Homebrew/homebrew-core", git_head: "master") - }.to raise_error(ArgumentError, /No file found/) + described_class.fetch_homebrew_cask_source("bar", git_head: "master") + }.to raise_error(ArgumentError, /No valid file found/) end end end