|  | # 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()) |