You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
81 lines
2.4 KiB
81 lines
2.4 KiB
# 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())
|
|
|