Add support for adding and removing labels from an issue
authorAndrew Nicols <andrew@nicols.co.uk>
Tue, 9 Dec 2014 07:02:58 +0000 (15:02 +0800)
committerAndrew Nicols <andrew@nicols.co.uk>
Wed, 17 Dec 2014 05:59:01 +0000 (13:59 +0800)
extra/bash_completion
mdk/commands/tracker.py
mdk/jira.py

index e363576..4ee74ca 100644 (file)
@@ -216,7 +216,7 @@ function _mdk() {
                 fi
                 ;;
             tracker)
-                OPTS="--testing"
+                OPTS="--testing --add-labels --remove-labels"
                 ;;
             update)
                 OPTS="--integration --stable --all --upgrade --update-cache"
index 4817bb7..5153973 100644 (file)
@@ -46,6 +46,24 @@ class TrackerCommand(Command):
                 'help': 'MDL issue number. Guessed from the current branch if not specified.',
                 'nargs': '?'
             }
+        ),
+        (
+            ['--add-labels'],
+            {
+                'action': 'store',
+                'help': 'Add the specified labels to the issue',
+                'nargs': '+',
+                'dest':  'addlabels'
+            }
+        ),
+        (
+            ['--remove-labels'],
+            {
+                'action': 'store',
+                'help': 'Remove the specified labels from the issue',
+                'nargs': '+',
+                'dest':  'removelabels'
+            }
         )
     ]
     _description = 'Retrieve information from the tracker'
@@ -70,8 +88,54 @@ class TrackerCommand(Command):
 
         self.Jira = Jira()
         self.mdl = 'MDL-' + re.sub(r'(MDL|mdl)(-|_)?', '', issue)
+
+        changesMade = False
+        labelChanges = {
+            'added': [],
+            'removed': [],
+            'nochange': []
+        }
+
+        if args.addlabels:
+            result = self.Jira.addLabels(self.mdl, args.addlabels)
+            labelChanges['added'].extend(result['added'])
+            labelChanges['nochange'].extend(result['nochange'])
+
+            if len(result['added']):
+                changesMade = True
+
+        if args.removelabels:
+            result = self.Jira.removeLabels(self.mdl, args.removelabels)
+            labelChanges['removed'].extend(result['removed'])
+            labelChanges['nochange'].extend(result['nochange'])
+
+            if len(result['removed']):
+                changesMade = True
+
         self.info(args)
 
+        if changesMade or len(labelChanges['nochange']):
+            if changesMade:
+                print u'Changes were made to this issue:'
+
+            if len(labelChanges['added']):
+                labels = u'{0}: {1}'.format('Labels added', ', '.join(labelChanges['added']))
+                for l in textwrap.wrap(labels, 68, initial_indent='* ', subsequent_indent='    '):
+                    print l
+
+            if len(labelChanges['removed']):
+                labels = u'{0}: {1}'.format('Labels removed', ', '.join(labelChanges['removed']))
+                for l in textwrap.wrap(labels, 68, initial_indent='* ', subsequent_indent='    '):
+                    print l
+
+            if len(labelChanges['nochange']):
+                print u'Some changes were not made to this issue:'
+                labels = u'{0}: {1}'.format('Labels unchanged', ', '.join(labelChanges['nochange']))
+                for l in textwrap.wrap(labels, 68, initial_indent='* ', subsequent_indent='    '):
+                    print l
+
+            print u'-' * 72
+
     def info(self, args):
         """Display classic information about an issue"""
         issue = self.Jira.getIssue(self.mdl)
@@ -88,6 +152,12 @@ class TrackerCommand(Command):
         print u'  {0} - {1} - {2}'.format(issue['fields']['issuetype']['name'], issue['fields']['priority']['name'], u'https://tracker.moodle.org/browse/' + issue['key'])
         status = u'{0} {1} {2}'.format(issue['fields']['status']['name'], resolution, resolutiondate).strip()
         print u'  {0}'.format(status)
+
+        if issue['fields']['labels']:
+            labels = u'{0}: {1}'.format('Labels', ', '.join(issue['fields']['labels']))
+            for l in textwrap.wrap(labels, 68, initial_indent='  ', subsequent_indent='    '):
+                print l
+
         vw = u'[ V: %d - W: %d ]' % (issue['fields']['votes']['votes'], issue['fields']['watches']['watchCount'])
         print '{0:->70}--'.format(vw)
         print u'{0:<20}: {1} ({2}) on {3}'.format('Reporter', issue['fields']['reporter']['displayName'], issue['fields']['reporter']['name'], created)
index 32d0429..00194c2 100644 (file)
@@ -353,6 +353,59 @@ class Jira(object):
 
         return True
 
+    def getLabels(self, key):
+        """Get a dict of labels
+        """
+        issueInfo = self.getIssue(key, fields='labels')
+        return issueInfo.get('fields').get('labels', [])
+
+    def addLabels(self, key, newLabels):
+        labels = self.getLabels(key)
+
+        results = {
+            'added': [],
+            'nochange': []
+        }
+
+        for label in newLabels:
+            label = unicode(label)
+            if label not in labels:
+                labels.append(label)
+                results['added'].append(label)
+            else:
+                results['nochange'].append(label)
+
+        update = {'fields': {'labels': labels}}
+        resp = self.request('issue/%s' % (str(key)), method='PUT', data=json.dumps(update))
+
+        if resp['status'] != 204:
+            raise JiraException('Issue was not updated: %s' % (str(resp['status'])))
+
+        return results
+
+    def removeLabels(self, key, oldLabels):
+        labels = self.getLabels(key)
+
+        results = {
+            'removed': [],
+            'nochange': []
+        }
+
+        for label in oldLabels:
+            label = unicode(label)
+            if label in labels:
+                labels.remove(label)
+                results['removed'].append(label)
+            else:
+                results['nochange'].append(label)
+
+        update = {'fields': {'labels': labels}}
+        resp = self.request('issue/%s' % (str(key)), method='PUT', data=json.dumps(update))
+
+        if resp['status'] != 204:
+            raise JiraException('Issue was not updated: %s' % (str(resp['status'])))
+
+        return results
 
 class JiraException(Exception):
     pass