82 lines
2.4 KiB
Python
82 lines
2.4 KiB
Python
|
# Copyright (c) 2022 Nordic Semiconductor ASA
|
||
|
#
|
||
|
# SPDX-License-Identifier: Apache-2.0
|
||
|
|
||
|
'''
|
||
|
Generic GitHub helper routines which may be useful to other scripts.
|
||
|
|
||
|
This file is not meant to be run directly, but rather to be imported
|
||
|
as a module from other scripts.
|
||
|
'''
|
||
|
|
||
|
# Note that the type annotations are not currently checked by mypy.
|
||
|
# Unless that changes, they serve as documentation, rather than
|
||
|
# guarantees from a type checker.
|
||
|
|
||
|
# stdlib
|
||
|
import getpass
|
||
|
import os
|
||
|
import netrc
|
||
|
import sys
|
||
|
from typing import Dict
|
||
|
|
||
|
# third party
|
||
|
import github
|
||
|
|
||
|
def get_github_credentials(ask: bool = True) -> Dict[str, str]:
|
||
|
'''Get credentials for constructing a github.Github object.
|
||
|
|
||
|
This function tries to get github.com credentials from these
|
||
|
places, in order:
|
||
|
|
||
|
1. a ~/.netrc file, if one exists
|
||
|
2. a GITHUB_TOKEN environment variable
|
||
|
3. if the 'ask' kwarg is truthy, from the user on the
|
||
|
at the command line.
|
||
|
|
||
|
On failure, RuntimeError is raised.
|
||
|
|
||
|
Scripts often need credentials because anonym access to
|
||
|
api.github.com is rate limited more aggressively than
|
||
|
authenticated access. Scripts which use anonymous access are
|
||
|
therefore more likely to fail due to rate limiting.
|
||
|
|
||
|
The return value is a dict which can be passed to the
|
||
|
github.Github constructor as **kwargs.
|
||
|
|
||
|
:param ask: if truthy, the user will be prompted for credentials
|
||
|
if none are found from other sources
|
||
|
'''
|
||
|
|
||
|
try:
|
||
|
nrc = netrc.netrc()
|
||
|
except (FileNotFoundError, netrc.NetrcParseError):
|
||
|
nrc = None
|
||
|
|
||
|
if nrc is not None:
|
||
|
auth = nrc.authenticators('github.com')
|
||
|
if auth is not None:
|
||
|
return {'login_or_token': auth[0], 'password': auth[2]}
|
||
|
|
||
|
token = os.environ.get('GITHUB_TOKEN')
|
||
|
if token:
|
||
|
return {'login_or_token': token}
|
||
|
|
||
|
if ask:
|
||
|
print('Missing GitHub credentials:\n'
|
||
|
'~/.netrc file not found or has no github.com credentials, '
|
||
|
'and GITHUB_TOKEN is not set in the environment. '
|
||
|
'Please give your GitHub token.',
|
||
|
file=sys.stderr)
|
||
|
token = getpass.getpass('token: ')
|
||
|
return {'login_or_token': token}
|
||
|
|
||
|
raise RuntimeError('no credentials found')
|
||
|
|
||
|
def get_github_object(ask: bool = True) -> github.Github:
|
||
|
'''Get a github.Github object, created with credentials.
|
||
|
|
||
|
:param ask: passed to get_github_credentials()
|
||
|
'''
|
||
|
return github.Github(**get_github_credentials())
|