Chromium Code Reviews| Index: appengine/findit/lib/gitiles/repo_util.py |
| diff --git a/appengine/findit/lib/gitiles/repo_util.py b/appengine/findit/lib/gitiles/repo_util.py |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..790a6f796a45259a9e985d14aa3c860c5ca3c1e0 |
| --- /dev/null |
| +++ b/appengine/findit/lib/gitiles/repo_util.py |
| @@ -0,0 +1,71 @@ |
| +# Copyright 2016 The Chromium Authors. All rights reserved. |
|
stgao
2016/11/02 02:04:20
This module is not related to operation on a repo.
wrengr
2016/11/03 17:09:01
I'm not sure I follow? I agree that it's not an op
stgao
2016/11/03 17:28:40
I'm fine with it being with git-related modules, b
Sharu Jiang
2016/11/03 20:59:48
It is parsing commit messages from a git repo :)
Sharu Jiang
2016/11/03 20:59:48
How about code_review_util.py under the lib/?
|
| +# Use of this source code is governed by a BSD-style license that can be |
| +# found in the LICENSE file. |
| + |
| +import re |
| + |
| +CODE_REVIEW_URL_PATTERN = re.compile( |
| + '^(?:Review URL|Review-Url): (.*\d+).*$', re.IGNORECASE) |
| +COMMIT_POSITION_PATTERN = re.compile( |
| + '^Cr-Commit-Position: refs/heads/master@{#(\d+)}$', re.IGNORECASE) |
| +REVERTED_REVISION_PATTERN = re.compile( |
| + '^> Committed: https://.+/([0-9a-fA-F]{40})$', re.IGNORECASE) |
| +START_OF_CR_COMMIT_POSITION = -5 |
| + |
| + |
| +def ExtractCommitPositionAndCodeReviewUrl(message): |
| + """Returns the commit position and code review url in the commit message. |
| + |
| + A "commit position" is something similar to SVN version ids; i.e., |
| + numeric identifiers which are issued in sequential order. The reason |
| + we care about them is that they're easier for humans to read than |
| + the hashes that Git uses internally for identifying commits. We |
| + should never actually use them for *identifying* commits; they're |
| + only for pretty printing to humans. |
| + |
| + Returns: |
| + (commit_position, code_review_url) |
| + """ |
| + if not message: |
| + return (None, None) |
| + |
| + commit_position = None |
| + code_review_url = None |
| + |
| + # Commit position and code review url are in the last 5 lines. |
| + lines = message.strip().split('\n')[START_OF_CR_COMMIT_POSITION:] |
| + lines.reverse() |
| + |
| + for line in lines: |
| + if commit_position is None: |
| + match = COMMIT_POSITION_PATTERN.match(line) |
| + if match: |
| + commit_position = int(match.group(1)) |
| + |
| + if code_review_url is None: |
| + match = CODE_REVIEW_URL_PATTERN.match(line) |
| + if match: |
| + code_review_url = match.group(1) |
| + return (commit_position, code_review_url) |
| + |
| + |
| +def NormalizeEmail(email): |
| + """Normalizes the email from git repo. |
| + |
| + Some email is like: test@chromium.org@bbb929c8-8fbe-4397-9dbb-9b2b20218538. |
| + """ |
| + parts = email.split('@') |
| + return '@'.join(parts[0:2]) |
| + |
| + |
| +def GetRevertedRevision(message): |
| + """Parse message to get the reverted revision if there is one.""" |
| + lines = message.strip().splitlines() |
| + if not lines[0].lower().startswith('revert'): |
| + return None |
| + |
| + for line in reversed(lines): # pragma: no cover |
| + # TODO: Handle cases where no reverted_revision in reverting message. |
| + reverted_revision_match = REVERTED_REVISION_PATTERN.match(line) |
| + if reverted_revision_match: |
| + return reverted_revision_match.group(1) |