Compare commits

...

4 Commits

@ -2,7 +2,7 @@ import configparser
import functools
import os
from pathlib import Path
from textwrap import indent, shorten, wrap
from textwrap import dedent, indent, shorten, wrap
from typing import Any, Callable, Dict
import click
@ -90,8 +90,9 @@ def version(client):
@main.command()
@click.option('--project', help='Project to filter for. Default: take from config [filters]/default_project')
@click.option('--component', 'components', help='Filter for issues with *any* of the given components')
@click.option('--status', multiple=True, help='Filter for issues with *any* of the given statuses')
@click.option('--component', 'components', multiple=True, help='Filter for issues with *any* of the given components')
@click.option('--status', multiple=True, help='Filter for issues with *any* of the given statuses. '
'! at the beginning means NOT.')
@click.option('--label', 'labels', multiple=True, help='Filter for issues with all the given labels')
@click.option('--text', 'texts', multiple=True, help='Filter for issues containing all the given strings')
@click.option('--flagged/--not-flagged', is_flag=True, default=None, help='Filter issues being flagged or not flagged')
@ -102,10 +103,8 @@ def version(client):
@pass_client
@pass_config
def issues(config, client, project, components, status, labels, texts, flagged, order, asc, jql):
filters_config = config['filters']
if not project and filters_config and 'default_project' in filters_config:
project = filters_config['default_project']
if not project and config.has_section('filters') and config.get('filters', 'default_project'):
project = config['filters']['default_project']
project_jql = f"project = {project}"
# TODO add filtering by created since
@ -124,9 +123,14 @@ def issues(config, client, project, components, status, labels, texts, flagged,
filters.append(components_jql)
if status:
status_list = ', '.join([f'"{s}"' for s in status])
status_jql = f"status IN ({status_list})"
filters.append(status_jql)
status_list = ', '.join([f'"{s}"' for s in status if not s.startswith('!')])
if status_list:
status_jql = f"status IN ({status_list})"
filters.append(status_jql)
status_list = ', '.join([f'"{s[1:]}"' for s in status if s.startswith('!')])
if status_list:
status_jql = f"status NOT IN ({status_list})"
filters.append(status_jql)
if labels:
labels_jql = ' AND '.join([f'labels = "{label}"' for label in labels])
@ -268,26 +272,34 @@ def link():
pass
@link.command('list')
@pass_issue
@pass_client
def link_list(client, issue):
def _format_links(client, issue):
lines = []
issuelinks = getattr(issue.fields, 'issuelinks', [])
if issuelinks:
print("\nIssue Links")
lines.append("Issue Links")
# TODO group by type?
for issuelink in issuelinks:
other_issue = getattr(issuelink, 'inwardIssue', issuelink.outwardIssue)
other_issue = getattr(issuelink, 'inwardIssue', getattr(issuelink, 'outwardIssue', None))
summary = indent('\n'.join(wrap(other_issue.fields.summary, width=72)), prefix=' ' * 4)
print(f" {issuelink.type} - {other_issue.key}\n{summary}")
lines.append(f" {issuelink.type} - {other_issue.key}\n{summary}")
remote_links = client.remote_links(issue.id)
if remote_links:
print("\nRemote Links:")
if lines:
lines.append('')
lines.append("Remote Links:")
for link in remote_links:
# TODO tabulate?
print(f" {link.object.title} => {link.object.url}")
lines.append(f" {link.object.title} => {link.object.url}")
return '\n'.join(lines)
@link.command('list')
@pass_issue
@pass_client
def link_list(client, issue):
print(_format_links(client, issue))
def prompt(description: str, *, multiline_ok: bool = True, initial_content: str = '', empty_ok: bool = False) -> str:
@ -396,11 +408,58 @@ def label_edit(issue):
@pass_issue
def debug(issue):
import IPython
IPython.embed
IPython.embed()
@issue.command()
@pass_issue
def show(issue):
@pass_client
def show(client, issue):
"""Show a lot of information about the issue"""
raise NotImplementedError
print(f"{issue.key} on {issue.fields.status} as {issue.fields.issuetype} assigned to {issue.fields.assignee}")
if getattr(issue.fields, 'parent', None):
parent = issue.fields.parent
print(f" parent: {parent.key} on {parent.fields.status} as {parent.fields.issuetype}")
summary = indent('\n'.join(wrap(parent.fields.summary, width=72)), prefix=' ' * 4)
print(f"{summary}")
print(indent(dedent(f"""\
created: {issue.fields.created}
components: {', '.join(issue.fields.components)}
flagged: {getattr(issue.fields, 'flagged', False)}
labels: {', '.join(issue.fields.labels)}
priority: {issue.fields.priority}
reporter: {issue.fields.reporter}"""),
' ' * 2))
def _header(s):
# print(f"\n {s}\n {'+' * len(s)}")
print(f"\n +++ {s} +++")
summary = indent('\n'.join(wrap(issue.fields.summary, replace_whitespace=False)), prefix=' ' * 2)
_header('summary')
print(summary)
description = indent('\n'.join(wrap(issue.fields.description or '', replace_whitespace=False)), prefix=' ' * 2)
_header('description')
print(description)
_header('attachments')
for i, attachment in enumerate(issue.fields.attachment):
print(f" * {attachment.filename} by {attachment.author}")
print(f" {attachment.content}")
print(f" {attachment.mimeType} with {attachment.size} B")
_header('links')
links = _format_links(client, issue)
if links:
print(indent(links, prefix=' ' * 2))
_header('comments')
for i, comment in enumerate(issue.fields.comment.comments):
if i != 0:
print('')
print(f" {comment.created} - {comment.author}")
body = indent('\n'.join(wrap(comment.body, replace_whitespace=False)), ' ' * 4)
print(body)
print('')

Loading…
Cancel
Save