diff --git a/sprintly_commit_parser/commit_parser.py b/sprintly_commit_parser/commit_parser.py index 3d5f1fd..9761f77 100644 --- a/sprintly_commit_parser/commit_parser.py +++ b/sprintly_commit_parser/commit_parser.py @@ -2,23 +2,37 @@ TICKET_PREFIX = '(?:#|(?:ticket|issue|item|defect|bug)[: ]?)' -TICKET_RE = re.compile(TICKET_PREFIX + '([0-9]+)', re.I | re.UNICODE) +TICKET_ID = '(([0-9]+:)?([0-9]+))' +TICKET_RE = re.compile(TICKET_PREFIX + TICKET_ID, re.I | re.UNICODE) def items_mentioned(string): if string is None or string.strip() == "": return [] - return [int(x) for x in TICKET_RE.findall(string)] + + items = [] + for _ in TICKET_RE.findall(string): + x = _[0] + if ':' in x: + product_id, item_number = x.split(':') + ticket_id = { + 'product_id': int(product_id), + 'item_number': int(item_number) + } + else: + ticket_id = int(x) + + items.append(ticket_id) + + return items class CommitParser(object): - _ticket_reference = TICKET_PREFIX + '[0-9]+' + _ticket_reference = TICKET_PREFIX + TICKET_ID _ticket_command = (r'(?P[A-Za-z]*) ?(task|issue|defect|bug|item|ticket|:)?.?' - '(?P%s(?:(?:[, &]*|[ ,]+?and[ ]?)%s)*)' % - (_ticket_reference, _ticket_reference)) + '(?P%s(?:(?:[, &]*|[ ,]+?and[ ]?)%s)*)' % (_ticket_reference, _ticket_reference)) _command_re = re.compile(_ticket_command, re.I | re.UNICODE) - _ticket_re = re.compile(TICKET_PREFIX + '([0-9]+)', re.I | re.UNICODE) _parsers = ['commands'] _item_cmds = {'close': 'close_ticket', 'closed': 'close_ticket', @@ -61,12 +75,17 @@ def _parse_commands(self, message): cmd_groups = CommitParser._command_re.findall(message) commands = [] - for cmd, junk, tkts in cmd_groups: + + x = lambda bit: (bit and bit not in [':']) + + for group in cmd_groups: + bits = filter(bool, group) + cmd, tkts = (bits[0], bits[1]) try: command = CommitParser._item_cmds[cmd.lower()] tickets = items_mentioned(tkts) for t in tickets: - commands.append({command: int(t)}) + commands.append({command: t}) except KeyError: pass diff --git a/tests.py b/tests.py index 2622fc3..34bf4d5 100644 --- a/tests.py +++ b/tests.py @@ -29,14 +29,10 @@ class CommitParserTests(unittest.TestCase): cases = [ ['And', "Built teaser page with signup form that posts to the 'nubook' user's subscriber list. This closes #77 and #78 Ref #1", [{'close_ticket': 77}, {'close_ticket': 78}, {'reference_ticket': 1}]], - ['See', 'Added blah to blah. See: #1.', [{'reference_ticket': 1}]], - ['See alternate', 'Added blah to blah. See: ticket:1.', [{'reference_ticket': 1}]], - ['Fixes alternate', 'Added blah to blah. fixes ticket:1.', [{'close_ticket': 1}]], ['Closes alternate', 'Added blah to blah. closes item:1.', [{'close_ticket': 1}]], ['Closes defect alternate', 'Added blah to blah. closes defect:1.', [{'close_ticket': 1}]], ['Fixes', 'Added blah to blah. Fixes #1.', [{'close_ticket': 1}]], - ['Fixes task', 'Added blah to blah. Fixes Task #1.', [{'close_ticket': 1}]], - ['Refs task', 'Added blah to blah. Refs Task #1.', [{'reference_ticket': 1}]], + ['Fixes', 'Added blah to blah. Fixes #336699:1.', [{'close_ticket': {'item_number': 1, 'product_id': 336699}}]], ['References', 'References #1.', [{'reference_ticket': 1}]], ['Fixes and', 'Added blah to blah. Fixes #1 and #2', [{'close_ticket': 1}, {'close_ticket': 2}]],