Skip to content

Commit

Permalink
Import JIRA sprint names as labels.
Browse files Browse the repository at this point in the history
  • Loading branch information
ralphbean committed Sep 9, 2016
1 parent e8302d9 commit 088f68b
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 11 deletions.
14 changes: 9 additions & 5 deletions bugwarrior/docs/services/jira.rst
Original file line number Diff line number Diff line change
Expand Up @@ -68,18 +68,22 @@ If your Jira instance is only available over HTTPS, and you're running into

jira.verify_ssl = False

Import Labels as Tags
+++++++++++++++++++++
Import Labels and Sprints as Tags
+++++++++++++++++++++++++++++++++

The Jira issue tracker allows you to attach labels to issues; to
use those labels as tags, you can use the ``jira.import_labels_as_tags``
option::

jira.import_labels_as_tags = True

Also, if you would like to control how these labels are created, you can
specify a template used for converting the Jira label into a Taskwarrior
tag.
You can also import the names of any sprints associated with an issue as tags,
by setting the ``jira.import_sprints`` option::

jira.import_sprints = True

If you would like to control how these labels are created, you can specify a
template used for converting the Jira label into a Taskwarrior tag.

For example, to prefix all incoming labels with the string 'jira_' (perhaps
to differentiate them from any existing tags you might have), you could
Expand Down
60 changes: 54 additions & 6 deletions bugwarrior/services/jira.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
from bugwarrior.config import asbool, die
from bugwarrior.services import IssueService, Issue

import logging
log = logging.getLogger(__name__)

# The below `ObliviousCookieJar` and `JIRA` classes are MIT Licensed.
# They were taken from this wonderful commit by @GaretJax
# https://github.com/GaretJax/lancet/commit/f175cb2ec9a2135fb78188cf0b9f621b51d88977
Expand All @@ -36,6 +39,16 @@ def _create_http_basic_session(self, username, password):
def close(self):
self._session.close()

def _parse_sprint_string(sprint):
""" Parse the big ugly sprint string stored by JIRA.
They look like:
com.atlassian.greenhopper.service.sprint.Sprint@4c9c41a5[id=2322,rapid
ViewId=1173,state=ACTIVE,name=Sprint 1,startDate=2016-09-06T16:08:07.4
55Z,endDate=2016-09-23T16:08:00.000Z,completeDate=<null>,sequence=2322]
"""
entries = sprint[sprint.index('[')+1:sprint.index(']')].split(',')
return dict([entry.split('=') for entry in entries])

class JiraIssue(Issue):
SUMMARY = 'jirasummary'
Expand Down Expand Up @@ -116,6 +129,28 @@ def get_entry(self):
return timestamp.strftime('%Y%m%dT%H%M%S') + timezone

def get_tags(self):
return self._get_tags_from_labels() + self._get_tags_from_sprints()

def _get_tags_from_sprints(self):
tags = []

if not self.origin['import_sprints']:
return tags

context = self.record.copy()
label_template = Template(self.origin['label_template'])

sprints = self.record.get('fields', {}).get(self.origin['sprint_field'], [])
for sprint in sprints:
# Parse this big ugly string.
sprint = _parse_sprint_string(sprint)
# Extract the name and render it into a label
context.update({'label': sprint['name']})
tags.append(label_template.render(context))

return tags

def _get_tags_from_labels(self):
tags = []

if not self.origin['import_labels_as_tags']:
Expand All @@ -125,12 +160,8 @@ def get_tags(self):
label_template = Template(self.origin['label_template'])

for label in self.record.get('fields', {}).get('labels', []):
context.update({
'label': label
})
tags.append(
label_template.render(context)
)
context.update({'label': label})
tags.append(label_template.render(context))

return tags

Expand Down Expand Up @@ -206,10 +237,25 @@ def __init__(self, *args, **kw):
self.import_labels_as_tags = self.config_get_default(
'import_labels_as_tags', default=False, to_type=asbool
)
self.import_sprints = self.config_get_default(
'import_sprints', default=False, to_type=asbool
)
self.label_template = self.config_get_default(
'label_template', default='{{label}}', to_type=six.text_type
)

if self.import_sprints:
sprint_fields = [field for field in self.jira.fields()
if field['name'] == 'Sprint']
if len(sprint_fields) > 1:
log.warn("More than one sprint custom field found. Ignoring sprints.")
self.import_sprints = False
elif len(sprint_fields) < 1:
log.warn("No sprint custom field found. Ignoring sprints.")
self.import_sprints = False
else:
self.sprint_field = sprint_fields[0]['id']

@classmethod
def get_keyring_service(cls, config, section):
username = config.get(section, cls._get_key('username'))
Expand All @@ -220,6 +266,8 @@ def get_service_metadata(self):
return {
'url': self.url,
'import_labels_as_tags': self.import_labels_as_tags,
'import_sprints': self.import_sprints,
'sprint_field': self.sprint_field,
'label_template': self.label_template,
}

Expand Down

0 comments on commit 088f68b

Please sign in to comment.