utils/github: Handle users not having any GitHub credentials

- When running `brew request-bottle`, users who don't have credentials
  in the macOS keychain (ie, Linux users) or `HOMEBREW_GITHUB_API_TOKEN`
  receive "Error: Not Found" from the GitHub API returning a 404.
- This is cryptic and confusing for newcomers to Linux maintenance, and
  potentially confusing to other folks using `open_api` where
  credentials are expected yet unset.
- This adds a new `MissingAuthenticationError` to handle the case where
  the GitHub API returns 404 and there are no creds yet API scopes are
  required.

Before:

```
issyl0@sky:/home/linuxbrew/.linuxbrew/Homebrew$ brew request-bottle hello
==> Dispatching request to Homebrew/linuxbrew-core for hello
Error: Not Found
```

After:

```
issyl0@sky:/home/linuxbrew/.linuxbrew/Homebrew$ brew request-bottle hello
==> Dispatching request to Homebrew/linuxbrew-core for hello
Error: No GitHub credentials found in Keychain or environment.
Create a GitHub personal access token:
    https://github.com/settings/tokens/new?scopes=gist,public_repo&description=Homebrew
  echo 'export HOMEBREW_GITHUB_API_TOKEN=your_token_here' >> ~/.profile
```
This commit is contained in:
Issy Long 2021-02-04 23:35:15 +00:00
parent e98a913783
commit ccb6d5e834
No known key found for this signature in database
GPG Key ID: 8247C390DADC67D4

View File

@ -24,6 +24,11 @@ module GitHub
ALL_SCOPES_URL = Formatter.url( ALL_SCOPES_URL = Formatter.url(
"https://github.com/settings/tokens/new?scopes=#{ALL_SCOPES.join(",")}&description=Homebrew", "https://github.com/settings/tokens/new?scopes=#{ALL_SCOPES.join(",")}&description=Homebrew",
).freeze ).freeze
CREATE_GITHUB_PAT_MESSAGE = <<~EOS
Create a GitHub personal access token:
#{ALL_SCOPES_URL}
#{Utils::Shell.set_variable_in_profile("HOMEBREW_GITHUB_API_TOKEN", "your_token_here")}
EOS
# Generic API error. # Generic API error.
class Error < RuntimeError class Error < RuntimeError
@ -79,6 +84,15 @@ module GitHub
end end
end end
# Error when the user has no GitHub API credentials set at all (macOS keychain or envvar).
class MissingAuthenticationError < Error
def initialize
message = +"No GitHub credentials found in Keychain or environment.\n"
message << CREATE_GITHUB_PAT_MESSAGE
super message
end
end
# Error when the API returns a validation error. # Error when the API returns a validation error.
class ValidationFailedError < Error class ValidationFailedError < Error
def initialize(github_message, errors) def initialize(github_message, errors)
@ -277,6 +291,8 @@ module GitHub
when "401", "403" when "401", "403"
raise AuthenticationFailedError, message raise AuthenticationFailedError, message
when "404" when "404"
raise MissingAuthenticationError if api_credentials_type == :none && scopes.present?
raise HTTPNotFoundError, message raise HTTPNotFoundError, message
when "422" when "422"
errors = json&.[]("errors") || [] errors = json&.[]("errors") || []