87 lines
2.2 KiB
Python
87 lines
2.2 KiB
Python
"""
|
|
JQL query builder.
|
|
"""
|
|
|
|
from typing import Optional, List
|
|
|
|
|
|
class JQL:
|
|
"""Fluent JQL builder."""
|
|
|
|
def __init__(self):
|
|
self._parts: List[str] = []
|
|
self._order: Optional[str] = None
|
|
|
|
def _q(self, val: str) -> str:
|
|
return f'"{val}"' if " " in val else val
|
|
|
|
# Conditions
|
|
def assigned_to_me(self) -> "JQL":
|
|
self._parts.append("assignee = currentUser()")
|
|
return self
|
|
|
|
def project(self, key: str) -> "JQL":
|
|
self._parts.append(f"project = {self._q(key)}")
|
|
return self
|
|
|
|
def sprint_open(self) -> "JQL":
|
|
self._parts.append("sprint in openSprints()")
|
|
return self
|
|
|
|
def in_backlog(self) -> "JQL":
|
|
self._parts.append("sprint is EMPTY")
|
|
return self
|
|
|
|
def not_done(self) -> "JQL":
|
|
self._parts.append("statusCategory != Done")
|
|
return self
|
|
|
|
def status(self, name: str) -> "JQL":
|
|
self._parts.append(f"status = {self._q(name)}")
|
|
return self
|
|
|
|
def label(self, name: str) -> "JQL":
|
|
self._parts.append(f"labels = {self._q(name)}")
|
|
return self
|
|
|
|
def text(self, search: str) -> "JQL":
|
|
self._parts.append(f'text ~ "{search}"')
|
|
return self
|
|
|
|
def issue_type(self, name: str) -> "JQL":
|
|
self._parts.append(f"issuetype = {self._q(name)}")
|
|
return self
|
|
|
|
def raw(self, jql: str) -> "JQL":
|
|
self._parts.append(jql)
|
|
return self
|
|
|
|
# Ordering
|
|
def order_by(self, field: str, desc: bool = True) -> "JQL":
|
|
self._order = f"ORDER BY {field} {'DESC' if desc else 'ASC'}"
|
|
return self
|
|
|
|
def build(self) -> str:
|
|
jql = " AND ".join(self._parts)
|
|
if self._order:
|
|
jql = f"{jql} {self._order}"
|
|
return jql.strip()
|
|
|
|
|
|
# Preset queries for main use cases
|
|
class Queries:
|
|
@staticmethod
|
|
def my_tickets(project: Optional[str] = None) -> JQL:
|
|
q = JQL().assigned_to_me().not_done().order_by("updated")
|
|
if project:
|
|
q.project(project)
|
|
return q
|
|
|
|
@staticmethod
|
|
def backlog(project: str) -> JQL:
|
|
return JQL().project(project).in_backlog().not_done().order_by("priority")
|
|
|
|
@staticmethod
|
|
def current_sprint(project: str) -> JQL:
|
|
return JQL().project(project).sprint_open().order_by("priority")
|