From 864475e14fa4f40d676206beda46967e0c598b10 Mon Sep 17 00:00:00 2001 From: Alyssa Ross Date: Thu, 11 Oct 2018 16:27:14 +0100 Subject: [PATCH] bump-formula-pr: use GitHub error message info This saves an API call, and is more accurate, because the repo API doesn't actually say whether forking is enabled, but this error message does. To do this, the original GitHub error message had to be accessible on the GitHub exceptions. --- Library/Homebrew/dev-cmd/bump-formula-pr.rb | 7 +--- Library/Homebrew/utils/github.rb | 44 +++++++++++++-------- 2 files changed, 29 insertions(+), 22 deletions(-) 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