Compare commits

...

4 Commits

Author SHA1 Message Date
MasterofJOKers e7e286fbf3 Support not having [filters] in config
Not everybody might have a default_project set ...
2022-09-20 22:56:37 +02:00
MasterofJOKers 6e2d639034 Support NOT in --status of issues 2022-09-20 22:56:31 +02:00
MasterofJOKers 471855beb6 Fix multiple=True for components in issues 2022-09-20 22:56:10 +02:00
MasterofJOKers 57afd1c82b Add implementation for issue show 2022-09-20 22:55:04 +02:00
1 changed files with 88 additions and 29 deletions

View File

@ -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
def _format_links(client, issue):
lines = []
issuelinks = getattr(issue.fields, 'issuelinks', [])
if issuelinks:
lines.append("Issue Links")
# TODO group by type?
for issuelink in issuelinks:
other_issue = getattr(issuelink, 'inwardIssue', getattr(issuelink, 'outwardIssue', None))
summary = indent('\n'.join(wrap(other_issue.fields.summary, width=72)), prefix=' ' * 4)
lines.append(f" {issuelink.type} - {other_issue.key}\n{summary}")
remote_links = client.remote_links(issue.id)
if remote_links:
if lines:
lines.append('')
lines.append("Remote Links:")
for link in remote_links:
# TODO tabulate?
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):
issuelinks = getattr(issue.fields, 'issuelinks', [])
if issuelinks:
print("\nIssue Links")
# TODO group by type?
for issuelink in issuelinks:
other_issue = getattr(issuelink, 'inwardIssue', issuelink.outwardIssue)
summary = indent('\n'.join(wrap(other_issue.fields.summary, width=72)), prefix=' ' * 4)
print(f" {issuelink.type} - {other_issue.key}\n{summary}")
remote_links = client.remote_links(issue.id)
if remote_links:
print("\nRemote Links:")
for link in remote_links:
# TODO tabulate?
print(f" {link.object.title} => {link.object.url}")
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('')