Merge pull request #5085 from alyssais/bump_formula_pr-no_fork

bump-formula-pr: gracefully handle unforkable repositories
This commit is contained in:
Mike McQuaid 2018-10-12 11:05:08 +01:00 committed by GitHub
commit 662641557e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 41 additions and 25 deletions

View File

@ -345,7 +345,7 @@ module Homebrew
shallow = !git_dir.empty? && File.exist?("#{git_dir}/shallow")
if args.dry_run?
ohai "fork repository with GitHub API"
ohai "try to fork repository with GitHub API"
ohai "git fetch --unshallow origin" if shallow
ohai "git checkout --no-track -b #{branch} origin/master"
ohai "git commit --no-edit --verbose --message='#{formula.name} " \
@ -359,18 +359,24 @@ module Homebrew
response = GitHub.create_fork(formula.tap.full_name)
# GitHub API responds immediately but fork takes a few seconds to be ready.
sleep 3
if system("git", "config", "--local", "--get-regexp", "remote\..*\.url", "git@github.com:.*")
remote_url = response.fetch("ssh_url")
else
remote_url = response.fetch("clone_url")
end
username = response.fetch("owner").fetch("login")
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
rescue *GitHub.api_errors => e
formula.path.atomic_write(backup_file) unless args.dry_run?
odie "Unable to fork: #{e.message}!"
end
if system("git", "config", "--local", "--get-regexp", "remote\..*\.url", "git@github.com:.*")
remote_url = response.fetch("ssh_url")
else
remote_url = response.fetch("clone_url")
end
username = response.fetch("owner").fetch("login")
safe_system "git", "fetch", "--unshallow", "origin" if shallow
safe_system "git", "checkout", "--no-track", "-b", branch, "origin/master"
safe_system "git", "commit", "--no-edit", "--verbose",

View File

@ -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