diff --git a/Library/Homebrew/dev-cmd/bump-formula-pr.rb b/Library/Homebrew/dev-cmd/bump-formula-pr.rb index 69f1450f2b..16f3d24af6 100644 --- a/Library/Homebrew/dev-cmd/bump-formula-pr.rb +++ b/Library/Homebrew/dev-cmd/bump-formula-pr.rb @@ -366,15 +366,12 @@ module Homebrew remote_url = response.fetch("clone_url") end username = response.fetch("owner").fetch("login") - rescue *GitHub.api_errors + rescue GitHub::AuthenticationFailedError => e + raise unless e.github_message =~ /forking is disabled/ # If the repository is private, forking might be disabled. # Create branches in the repository itself instead. remote_url = Utils.popen_read("git remote get-url --push origin").chomp username = formula.tap.user - repo_name = "homebrew-#{formula.tap.repo}" - unless GitHub.repository(username, repo_name).fetch("private") - raise - end rescue *GitHub.api_errors => e formula.path.atomic_write(backup_file) unless args.dry_run? odie "Unable to fork: #{e.message}!" diff --git a/Library/Homebrew/utils/github.rb b/Library/Homebrew/utils/github.rb index e6fc4ef43a..cbfe76a218 100644 --- a/Library/Homebrew/utils/github.rb +++ b/Library/Homebrew/utils/github.rb @@ -15,13 +15,22 @@ module GitHub PR_ENV_KEY = "HOMEBREW_NEW_FORMULA_PULL_REQUEST_URL".freeze PR_ENV = ENV[PR_ENV_KEY] - Error = Class.new(RuntimeError) - HTTPNotFoundError = Class.new(Error) + class Error < RuntimeError + attr_reader :github_message + end + + class HTTPNotFoundError < Error + def initialize(github_message) + @github_message = github_message + super + end + end class RateLimitExceededError < Error - def initialize(reset, error) + def initialize(reset, github_message) + @github_message = github_message super <<~EOS - GitHub API Error: #{error} + GitHub API Error: #{github_message} Try again in #{pretty_ratelimit_reset(reset)}, or create a personal access token: #{ALL_SCOPES_URL} and then set the token as: export HOMEBREW_GITHUB_API_TOKEN="your_new_token" @@ -34,8 +43,9 @@ module GitHub end class AuthenticationFailedError < Error - def initialize(error) - message = "GitHub #{error}\n" + def initialize(github_message) + @github_message = github_message + message = "GitHub #{github_message}\n" if ENV["HOMEBREW_GITHUB_API_TOKEN"] message << <<~EOS HOMEBREW_GITHUB_API_TOKEN may be invalid or expired; check: @@ -193,6 +203,13 @@ module GitHub end def raise_api_error(output, errors, http_code, headers, scopes) + json = begin + JSON.parse(output) + rescue + nil + end + message = json&.[]("message") || "curl failed! #{errors}" + meta = {} headers.lines.each do |l| key, _, value = l.delete(":").partition(" ") @@ -204,25 +221,18 @@ module GitHub if meta.fetch("x-ratelimit-remaining", 1).to_i <= 0 reset = meta.fetch("x-ratelimit-reset").to_i - error = JSON.parse(output)["message"] - raise RateLimitExceededError.new(reset, error) + raise RateLimitExceededError.new(reset, message) end GitHub.api_credentials_error_message(meta, scopes) case http_code when "401", "403" - raise AuthenticationFailedError, output + raise AuthenticationFailedError, message when "404" - raise HTTPNotFoundError, output + raise HTTPNotFoundError, message else - error = begin - JSON.parse(output)["message"] - rescue - nil - end - error ||= "curl failed! #{errors}" - raise Error, error + raise Error, message end end