From ce823a944c83e6bbf608bdccd914ca322fd0b119 Mon Sep 17 00:00:00 2001 From: sidpremkumar Date: Jul 16 2019 15:01:47 +0000 Subject: [PATCH 1/3] adding another catch for updating descrtiption --- diff --git a/sync2jira/downstream.py b/sync2jira/downstream.py index f76f3c2..b054c14 100644 --- a/sync2jira/downstream.py +++ b/sync2jira/downstream.py @@ -862,7 +862,7 @@ def _update_description(existing, issue): issue.content, new_description[index1+index2+1:]) - elif '] Upstream issue status:' in new_description: + elif '] Upstream issue status:' in new_description and '] Upstream Reporter:' not in new_description: # We need to add a upstream reporter and description field upstream_reporter = '[%s] Upstream Reporter: %s' % ( issue.id, @@ -877,6 +877,12 @@ def _update_description(existing, issue): '\n' + upstream_description + new_description[index+1:]) + elif '] Upstream issue status:' not in new_description and '] Upstream Reporter:' in new_description: + # We need to just add the description field + new_description = re.sub( + r'\[%s\] Upstream Reporter: %s (\w\W)*' % (issue.id, issue.reporter['fullname']), + r'[%s] Upstream Reporter: %s \nUpstream Description: {quote} %s {quote}' % + (issue.id, issue.reporter['fullname'], issue.content), new_description) else: # Just add reporter and description to the top upstream_reporter = '[%s] Upstream Reporter: %s' % ( @@ -891,7 +897,7 @@ def _update_description(existing, issue): # Now that we've updated the description (i.e. added # issue.id) we can delete the link in the description if its still there. new_description = re.sub( - r'\[%s\]' % issue.url, + r'%s' % issue.url, r'', new_description ) From dca62f1d643490c5b932827977fb1643e6db32d7 Mon Sep 17 00:00:00 2001 From: sidpremkumar Date: Jul 16 2019 17:11:34 +0000 Subject: [PATCH 2/3] adding regex matches to all description updates --- diff --git a/sync2jira/downstream.py b/sync2jira/downstream.py index b054c14..8d33ee2 100644 --- a/sync2jira/downstream.py +++ b/sync2jira/downstream.py @@ -844,6 +844,8 @@ def _update_tags(updates, existing, issue): def _update_description(existing, issue): new_description = existing.fields.description + if not new_description: + new_description = '' if 'Upstream description' in new_description: # If we just need to update the content of the description new_description = re.sub( @@ -852,36 +854,31 @@ def _update_description(existing, issue): new_description) elif '] Upstream issue status:' in new_description and '] Upstream Reporter:' in new_description: # We need to add a description field - # Need to find the 2nd new line as we already have - # Reporter and Status - index1 = new_description.find('\n') - index2 = new_description[index1+1:].find('\n') - new_description = "%s \nUpstream description: " \ - "{quote}%s{quote}\n%s" % \ - (new_description[:index1+index2+1], - issue.content, - new_description[index1+index2+1:]) + today = datetime.today() + new_description = re.sub(r'\[[\w\W]*\] Upstream issue status: %s\n\[%s\] Upstream Reporter: %s' % ( + issue.status, issue.id, issue.reporter['fullname']), + r'[%s] Upstream issue status: %s\n[%s] Upstream Reporter: %s\n' + r'Upstream description: {quote}%s{quote}' % ( + today.strftime("%a %b %y - %H:%M"), issue.status, issue.id, + issue.reporter['fullname'], + issue.content), + new_description) elif '] Upstream issue status:' in new_description and '] Upstream Reporter:' not in new_description: # We need to add a upstream reporter and description field - upstream_reporter = '[%s] Upstream Reporter: %s' % ( - issue.id, - issue.reporter['fullname'] - ) - upstream_description = "%s \nUpstream description: " \ - "{quote}%s{quote}" % \ - (upstream_reporter, issue.content) - # Add it to the old description - index = new_description.find('\n') - new_description = (new_description[:index] + - '\n' + - upstream_description + - new_description[index+1:]) + today = datetime.today() + new_description = re.sub(r'\[[\w\W]*\] Upstream issue status: %s' % issue.status, + r'[%s] Upstream issue status: %s\n' + r'[%s] Upstream Reporter: %s\n' + r'Upstream description: {quote}%s{quote}' % + (today.strftime("%a %b %y - %H:%M"), issue.status, issue.id, + issue.reporter['fullname'], issue.content), + new_description) elif '] Upstream issue status:' not in new_description and '] Upstream Reporter:' in new_description: # We need to just add the description field new_description = re.sub( - r'\[%s\] Upstream Reporter: %s (\w\W)*' % (issue.id, issue.reporter['fullname']), - r'[%s] Upstream Reporter: %s \nUpstream Description: {quote} %s {quote}' % + r'\[%s\] Upstream Reporter: %s [\w\W]*' % (issue.id, issue.reporter['fullname']), + r'[%s] Upstream Reporter: %s \nUpstream description: {quote} %s {quote}' % (issue.id, issue.reporter['fullname'], issue.content), new_description) else: # Just add reporter and description to the top diff --git a/tests/test_downstream.py b/tests/test_downstream.py index ca729f3..6553428 100644 --- a/tests/test_downstream.py +++ b/tests/test_downstream.py @@ -832,12 +832,18 @@ class TestDownstream(unittest.TestCase): {'description': '[123] Upstream Reporter: mock_user \n' 'Upstream description: {quote}mock_content{quote}'}) - def test_update_description_add_reporter(self): + @mock.patch(PATH + 'datetime') + def test_update_description_add_reporter(self, + mock_datetime): """ This function tests '_update_description' where we have to add a description and upstream reporter field """ # Set up return values self.mock_downstream.fields.description = '[123] Upstream issue status: Open\n' + self.mock_issue.status = 'Open' + self.mock_issue.id = '123' + self.mock_issue.reporter = {'fullname': 'mock_user'} + mock_datetime.today.return_value = self.mock_today # Call the function d._update_description( @@ -845,7 +851,10 @@ class TestDownstream(unittest.TestCase): issue=self.mock_issue ) # Assert all calls were made correctly - self.mock_downstream.update.assert_called_with({'description': '[123] Upstream issue status: Open\n[1234] Upstream Reporter: mock_user \nUpstream description: {quote}mock_content{quote}'}) + self.mock_downstream.update.assert_called_with( + {'description': '[mock_today] Upstream issue status: Open\n[123]' + ' Upstream Reporter: mock_user\nUpstream description:' + ' {quote}mock_content{quote}\n'}) def test_update_description_add_reporter_no_status(self): """ @@ -865,13 +874,19 @@ class TestDownstream(unittest.TestCase): {'description': '[1234] Upstream Reporter: mock_user \n' 'Upstream description: {quote}mock_content{quote} \n '}) - def test_update_description_add_description(self): + @mock.patch(PATH + 'datetime') + def test_update_description_add_description(self, + mock_datetime): """ This function tests '_update_description' where we have a reporter and status already """ # Set up return values self.mock_downstream.fields.description = '[123] Upstream issue status: Open\n' \ '[123] Upstream Reporter: mock_user\n' + self.mock_issue.status = 'Open' + self.mock_issue.id = '123' + self.mock_issue.reporter = {'fullname': 'mock_user'} + mock_datetime.today.return_value = self.mock_today # Call the function d._update_description( @@ -881,9 +896,9 @@ class TestDownstream(unittest.TestCase): # Assert all calls were made correctly self.mock_downstream.update.assert_called_with( - {'description': '[123] Upstream issue status: Open\n' - '[123] Upstream Reporter: mock_user \n' - 'Upstream description: {quote}mock_content{quote}\n\n'}) + {'description': '[mock_today] Upstream issue status: Open\n' + '[123] Upstream Reporter: mock_user\n' + 'Upstream description: {quote}mock_content{quote}\n'}) def test_verify_tags(self): """ @@ -1168,8 +1183,8 @@ class TestDownstream(unittest.TestCase): @mock.patch('jira.client.JIRA') - def check_comments_for_duplicates(self, - mock_client): + def test_check_comments_for_duplicates(self, + mock_client): """ Tests 'check_comments_for_duplicates' function """ @@ -1182,7 +1197,7 @@ class TestDownstream(unittest.TestCase): # Call the function response = d.check_comments_for_duplicate( - client=self.mock_client, + client=mock_client, result=self.mock_downstream, username='mock_user' ) From 44b1f75bf901c0c2cd9920d41777426189b3e865 Mon Sep 17 00:00:00 2001 From: sidpremkumar Date: Jul 16 2019 17:28:52 +0000 Subject: [PATCH 3/3] Adding regex and upstream reporter to title update --- diff --git a/sync2jira/downstream.py b/sync2jira/downstream.py index 8d33ee2..042e7d9 100644 --- a/sync2jira/downstream.py +++ b/sync2jira/downstream.py @@ -627,9 +627,7 @@ def _update_jira_issue(existing, issue, client): if 'title' in updates: # Update the title if needed if issue.title != existing.fields.summary: - data = {'summary': issue.title} - existing.update(data) - log.info(' Updated title') + _update_title(issue, existing) # Only synchronize transition (status) for listings that op-in if any('transition' in item for item in updates): @@ -703,6 +701,53 @@ def _update_transition(client, existing, issue): log.warning(' Could not update JIRA closed_status for %s' % issue.title) +def _update_title(issue, existing): + """ + Helper function to sync upstream/downstream title + Args: + issue (sync2jira.intermediary.Issue): Upstream issue + existing (jira.resource.Issue): Existing JIRA issue + Returns: + Nothing + """ + new_description = existing.fields.description + if not new_description: + new_description = '' + if '] Upstream Reporter:' not in new_description: + # We have to add the issue ID to the description so we can find it again + if '] Upstream issue status:' in new_description: + # We have to use regex to update the upstream reporter + today = datetime.today() + new_description = re.sub( + r'\[[\w\W]*\] Upstream issue status: %s' % issue.status, + '[%s] Upstream issue status: %s\n[%s] Upstream Reporter: %s' + % (today.strftime("%a %b %y - %H:%M"), + issue.status, issue.id, issue.reporter['fullname']), + new_description) + else: + # We can just add it to the top + new_description = '[%s] Upstream Repoter: %s' % \ + (issue.id, issue.reporter['fullname']) + new_description + # Update the description + # Now that we've updated the description (i.e. added + # issue.id) we can delete the link in the description if its still there. + new_description = re.sub( + r'%s' % issue.url, + r'', + new_description + ) + + # Now we can update the JIRA issue if we need to + if new_description != existing.fields.description: + data = {'description': new_description} + existing.update(data) + log.info(' Updated description') + # Then we can update the title + data = {'summary': issue.title} + existing.update(data) + log.info(' Updated title') + + def _update_comments(client, existing, issue): """ Helper function to sync comments between existing JIRA issue and upstream issue