def comment(globs: AttrDict, message: str, stdin: bool, bugs: List[int]): """Commenting on bugs.""" if stdin: message = click.get_text_stream().read() elif message: message = message else: message = template.edit_text() for bug in bugs: globs.req_post('{}/comments'.format(bug), body={'body': message}, model='Comment')
def reopen(globs: AttrDict, stdin: bool, message: str, bugs: List[int]): """Reopening closed bugs.""" if stdin: message = click.get_text_stream().read() elif not message: try: message = template.edit_text() except template.EmptyMessageError: # Message isn't required for reopening, but it is good practice message = None for bug in bugs: if message: globs.req_post('{}/comments'.format(bug), body={'body': message}, model='Comment') globs.req_post(bug, body={'state': 'open'}, model='Issue')
def milestones(globs: AttrDict, order: str, state: str, create: str, list: bool): """Repository milestones.""" if not list and not create: fail('No action specified!') return 1 milestones_url = '{}/repos/{}/milestones'.format(globs.host_url, globs.project) r, milestones = globs.req_get(milestones_url, model='Milestone') if list: tmpl = template.get_template('view', '/list_milestones.txt') columns = utils.T.width if utils.T.width else 80 max_id = max(i.number for i in milestones) id_len = len(str(max_id)) result = tmpl.render(milestones=milestones, order=order, state=state, project=globs.repo_obj(), id_len=id_len, max_title=columns - id_len - 2) if result: utils.pager(result, pager=globs.pager) elif create: data = {'title': create} r, milestone = globs.req_post('', body=data, model='Milestone') success('Milestone {:d} created'.format(milestone.number))
def milestone(globs: AttrDict, milestone: str, bugs: List[int]): """Issue milestones.""" milestones_url = '{}/repos/{}/milestones'.format(globs.host_url, globs.project) r, milestones = globs.req_get(milestones_url, model='Milestone') milestone_mapping = dict((m.title, m.number) for m in milestones) try: milestone = milestone_mapping[milestone] except KeyError: raise ValueError('No such milestone {:!r}'.format(milestone)) for bug_no in bugs: globs.req_post(bug_no, body={'milestone': milestone}, model='Milestone')
def setup(globs: AttrDict, local: bool): """Setup GitHub access token.""" if not utils.SYSTEM_CERTS: warn('Falling back on bundled certificates') if utils.CURL_CERTS: warn('Using certs specified in $CURL_CERTS') default_user = os.getenv('GITHUB_USER', utils.get_git_config_val('github.user', getpass.getuser())) user = click.prompt('GitHub user', default_user) if not user: user = default_user password = click.prompt('GitHub password', hide_input=True, confirmation_prompt=False) private = click.confirm('Support private repositories') data = { 'scopes': ['repo' if private else 'public_repo'], 'note': 'hubugs', 'note_url': 'https://github.com/JNRowe/hubugs' } # Unfortunately, we need to forcibly define the header to workaround # GitHub sending a 404(in an effort to stop information leakage) header = { 'Authorization': 'Basic ' + b64encode(':'.join([user, password])) } r, auth = globs.req_post('https://api.github.com/authorizations', body=data, headers=header, model='Authorisation', token=False) utils.set_git_config_val('hubugs.token', auth.token, local) success('Configuration complete!')
def label(globs: AttrDict, add: List[str], create: List[str], remove: List[str], list: bool, bugs: List[int]): """Labelling bugs.""" label_names = utils.sync_labels(globs, add, create) if list: click.echo(', '.join(sorted(label_names))) return for bug_no in bugs: r, bug = globs.req_get(bug_no, model='Issue') labels = [label.name for label in bug.labels] labels.extend(add + create) for string in remove: labels.remove(string) globs.req_post(bug_no, body={'labels': labels}, model='Label')
def edit(globs: AttrDict, stdin: bool, title: str, body:str, bugs: List[int]): """Editing bugs.""" if (title or stdin) and len(bugs) > 1: raise ValueError('Can not use --stdin or command line title/body ' 'with multiple bugs') for bug in bugs: if stdin: text = click.get_text_stream().readlines() elif not title: r, current = globs.req_get(bug, model='Issue') current_data = {'title': current.title, 'body': current.body} text = template.edit_text('open', current_data).splitlines() if stdin or not title: title = text[0] body = '\n'.join(text[1:]) else: title = title body = body data = {'title': title, 'body': body} globs.req_post(bug, body=data, model='Issue')
def open_bug(globs: AttrDict, add: List[str], create: List[str], stdin: bool, title: str, body: str): """Opening new bugs.""" utils.sync_labels(globs, add, create) if stdin: text = click.get_text_stream('stdin').readlines() elif not title: text = template.edit_text('open').splitlines() if stdin or not title: title = text[0] body = '\n'.join(text[1:]) else: title = title body = body data = {'title': title, 'body': body, 'labels': add + create} r, bug = globs.req_post('', body=data, model='Issue') success('Bug {:d} opened'.format(bug.number))
def report_bug(globs: AttrDict): """Report a new bug against hubugs.""" local = globs.project == 'JNRowe/hubugs' globs.project = 'JNRowe/hubugs' import html2text, jinja2, pygments # NOQA: E401 versions = dict([(m.__name__, getattr(m, '__version__', 'No version info')) for m in (click, html2text, httplib2, jinja2, pygments)]) data = { 'local': local, 'sys': sys, 'version': _version.dotted, 'versions': versions, 'certs': utils.CA_CERTS, } text = template.edit_text('hubugs_report', data).splitlines() title = text[0] body = '\n'.join(text[1:]) data = {'title': title, 'body': body} r, bug = globs.req_post('', body=data, model='Issue') success('Bug {:d} opened against hubugs, thanks!'.format(bug.number))