def commit_message_filter(msg): # type: (bytes) -> Tuple[bytes, Dict[Text, Text]] metadata = {} m = commitparser.BUG_RE.match(msg) if m: bug_bytes, bug_number = m.groups()[:2] if msg.startswith(bug_bytes): prefix = re.compile(br"^%s[^\w\d\[\(]*" % bug_bytes) msg = prefix.sub(b"", msg) metadata[u"bugzilla-url"] = env.bz.bugzilla_url(int(bug_number)) reviewers = u", ".join( item.decode("utf8", "replace") for item in commitparser.parse_reviewers(msg)) if reviewers: metadata["gecko-reviewers"] = reviewers msg = commitparser.replace_reviewers(msg, "") msg = commitparser.strip_commit_metadata(msg) description = msg.splitlines() if description: summary = description.pop(0) summary = summary.rstrip(b"!#$%&(*+,-/:;<=>@[\\^_`{|~").rstrip() msg = summary + (b"\n" + b"\n".join(description) if description else b"") return msg, metadata
def _build_commit_desc(commit_desc, backed_out_urls): # Build commit description and PR body. desc = commitparser.strip_commit_metadata(commit_desc).strip() if backed_out_urls: desc += '\n\n' for url in backed_out_urls: desc += 'Backs out %s' % url return desc
def test_strip_commit_metadata(self): self.assertEqual(strip_commit_metadata(b'foo'), b'foo') self.assertEqual(strip_commit_metadata(b'foo\n\nbar'), b'foo\n\nbar') self.assertEqual( strip_commit_metadata( b'Bug 1 - foo\n\nMozReview-Commit-ID: abcdef'), b'Bug 1 - foo') self.assertEqual( strip_commit_metadata( b'Bug 1 - foo\n\nMore description\n\nFoo-Bar: baz\n\n'), b'Bug 1 - foo\n\nMore description\n\nFoo-Bar: baz') self.assertEqual( strip_commit_metadata( b'Bug 1 - foo\n\nMozReview-Commit-ID: abcdef\n\nTrailing desc' ), b'Bug 1 - foo\n\n\nTrailing desc')
def commit_message_filter(msg): metadata = {} m = commitparser.BUG_RE.match(msg) if m: bug_str, bug_number = m.groups()[:2] if msg.startswith(bug_str): prefix = re.compile(r"^%s[^\w\d\[\(]*" % bug_str) msg = prefix.sub("", msg) metadata["bugzilla-url"] = env.bz.bugzilla_url(bug_number) reviewers = ", ".join(commitparser.parse_reviewers(msg)) if reviewers: metadata["gecko-reviewers"] = reviewers msg = commitparser.replace_reviewers(msg, "") msg = commitparser.strip_commit_metadata(msg) description = msg.splitlines() if description: summary = description.pop(0) summary = summary.rstrip("!#$%&(*+,-/:;<=>@[\\^_`{|~").rstrip() description = "\n".join(description) msg = summary + ("\n" + description if description else "") return msg, metadata
def test_strip_commit_metadata(self): self.assertEqual(strip_commit_metadata('foo'), 'foo') self.assertEqual(strip_commit_metadata('foo\n\nbar'), 'foo\n\nbar') self.assertEqual(strip_commit_metadata( 'Bug 1 - foo\n\nMozReview-Commit-ID: abcdef'), 'Bug 1 - foo') self.assertEqual(strip_commit_metadata( 'Bug 1 - foo\n\nMore description\n\nFoo-Bar: baz\n\n'), 'Bug 1 - foo\n\nMore description\n\nFoo-Bar: baz') self.assertEqual(strip_commit_metadata( 'Bug 1 - foo\n\nMozReview-Commit-ID: abcdef\n\nTrailing desc'), 'Bug 1 - foo\n\n\nTrailing desc') # unicode in should get unicode out res = strip_commit_metadata(u'foo\n\nbar') self.assertEqual(res, u'foo\n\nbar') self.assertIsInstance(res, unicode)
def test_strip_commit_metadata(self): self.assertEqual(strip_commit_metadata('foo'), 'foo') self.assertEqual(strip_commit_metadata('foo\n\nbar'), 'foo\n\nbar') self.assertEqual(strip_commit_metadata( 'Bug 1 - foo\n\nMozReview-Commit-ID: abcdef'), 'Bug 1 - foo') self.assertEqual(strip_commit_metadata( 'Bug 1 - foo\n\nMore description\n\nFoo-Bar: baz\n\n'), 'Bug 1 - foo\n\nMore description\n\nFoo-Bar: baz') self.assertEqual(strip_commit_metadata( 'Bug 1 - foo\n\nMozReview-Commit-ID: abcdef\n\nTrailing desc'), 'Bug 1 - foo\n\n\nTrailing desc') # unicode in should get unicode out res = strip_commit_metadata(u'foo\n\nbar') self.assertEqual(res, u'foo\n\nbar') self.assertIsInstance(res, unicode)
def update_bugzilla_attachments(bugzilla, bug_id, children_to_post, children_to_obsolete): attachment_updates = BugzillaAttachmentUpdates(bugzilla, bug_id) for child in children_to_obsolete: attachment_updates.obsolete_review_attachments(get_obj_url(child)) # We publish attachments for each commit/child to Bugzilla so that # reviewers can easily track their requests. # The review request exposes a list of usernames for reviewers. We need # to convert these to Bugzilla emails in order to make the request into # Bugzilla. # # It may seem like there is a data syncing problem here where usernames # may get out of sync with the reality from Bugzilla. Fortunately, # Review Board is smarter than that. Internally, the target_people list # is stored with foreign keys into the numeric primary key of the user # table. If the RB username changes, this won't impact target_people # nor the stored mapping to the numeric Bugzilla ID, which is # immutable. # # But we do have a potential data syncing problem with the stored email # address. Review Board's stored email address could be stale. So # instead of using it directly, we query Bugzilla and map the stored, # immutable numeric Bugzilla userid into an email address. This lookup # could be avoided if Bugzilla accepted a numeric userid in the # requestee parameter when modifying an attachment. user_email_cache = {} for review_request_draft, review_request in children_to_post: reviewers = {} for u in review_request_draft.target_people.all(): bum = BugzillaUserMap.objects.get(user=u) email = user_email_cache.get(bum.bugzilla_user_id) if email is None: user_data = bugzilla.get_user_from_userid(bum.bugzilla_user_id) # Since we're making the API call, we might as well ensure the # local database is up to date. users = get_or_create_bugzilla_users(user_data) email = users[0].email user_email_cache[bum.bugzilla_user_id] = email reviewers[email] = False for review in gen_latest_reviews(review_request): # The last review given by this reviewer had a ship-it, so we # will carry their r+ forward. If someone had manually changed # their flag on bugzilla, we may be setting it back to r+, but # we will consider the manual flag change on bugzilla user # error for now. if review.ship_it: reviewers[review.user.email] = True rr_url = get_obj_url(review_request) diff_url = '%sdiff/#index_header' % rr_url # Only post a comment if the diffset has actually changed comment = '' if review_request_draft.get_latest_diffset(): diffset_count = review_request.diffset_history.diffsets.count() if diffset_count < 1: # We don't need the first line, since it is also the attachment # summary, which is displayed in the comment. full_commit_msg = review_request_draft.description.partition( '\n')[2].strip() full_commit_msg = strip_commit_metadata(full_commit_msg) if full_commit_msg: full_commit_msg += '\n\n' comment = '%sReview commit: %s\nSee other reviews: %s' % ( full_commit_msg, diff_url, rr_url ) else: comment = ('Review request updated; see interdiff: ' '%sdiff/%d-%d/\n' % (rr_url, diffset_count, diffset_count + 1)) attachment_updates.create_or_update_attachment( review_request.id, review_request_draft.summary, comment, diff_url, reviewers) attachment_updates.do_updates()
def create_or_update_attachment(self, review_request, review_request_draft, flags): """Create or update the MozReview attachment using the provided flags. The `flags` parameter is an array of flags to set/update/clear. This array matches the Bugzilla flag API: Setting: { 'id': flag.id 'name': 'review', 'status': '?', 'requestee': reviewer.email } Clearing: { 'id': flag.id, 'status': 'X' } """ logger.info('Posting review request %s to bug %d.' % (review_request.id, self.bug_id)) rr_url = get_obj_url(review_request) diff_url = get_diff_url(review_request) # Build the comment. Only post a comment if the diffset has # actually changed. comment = '' if review_request_draft.get_latest_diffset(): diffset_count = review_request.diffset_history.diffsets.count() if diffset_count < 1: # We don't need the first line, since it is also the attachment # summary, which is displayed in the comment. full_commit_msg = review_request_draft.description.partition( '\n')[2].strip() full_commit_msg = strip_commit_metadata(full_commit_msg) if full_commit_msg: full_commit_msg += '\n\n' comment = '%sReview commit: %s\nSee other reviews: %s' % ( full_commit_msg, diff_url, rr_url) else: comment = ('Review request updated; see interdiff: ' '%sdiff/%d-%d/\n' % (rr_url, diffset_count, diffset_count + 1)) # Set up attachment metadata. attachment = self.get_attachment(review_request) params = {} if attachment: params['attachment_id'] = attachment['id'] if attachment['is_obsolete']: params['is_obsolete'] = False else: params['data'] = diff_url params['content_type'] = 'text/x-review-board-request' params['file_name'] = 'reviewboard-%d-url.txt' % review_request.id params['summary'] = replace_reviewers(review_request_draft.summary, None) params['comment'] = comment if flags: params['flags'] = flags if attachment: self.updates.append(params) else: self.creates.append(params)