| # Copyright (c) 2011 The Chromium OS Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| import re |
| import sys |
| |
| |
| class VerifyException(Exception): |
| pass |
| |
| |
| class HookFailure(object): |
| """Contains an error message and a list of error details.""" |
| def __init__(self, msg, items=None): |
| self.msg = msg |
| self.items = items |
| |
| |
| _INDENT = ' ' * 4 |
| _PROJECT_INFO = 'Errors in PROJECT *%s*!' |
| |
| def _PrintWithIndent(msg, indent_level): |
| """Print a block of text with a specified indent level to stderr. |
| |
| Args: |
| msg: A string to print (may contain newlines). |
| indent_level: The number of indents to prefix each line with. Each indent |
| is four characters wide. |
| """ |
| regex = re.compile(r'^', re.M) |
| msg = regex.sub(_INDENT * indent_level, msg) |
| print >> sys.stderr, msg |
| |
| |
| def _FormatCommitDesc(desc): |
| """Returns the properly prefixed commit description.""" |
| regex = re.compile(r'^', re.M) |
| return regex.sub('>', desc) |
| |
| |
| def _FormatHookFailure(hook_failure): |
| """Returns the properly formatted VerifyException as a string.""" |
| item_prefix = '\n%s* ' % _INDENT |
| formatted_items = '' |
| if hook_failure.items: |
| formatted_items = item_prefix + item_prefix.join(hook_failure.items) |
| return '* ' + hook_failure.msg + formatted_items |
| |
| |
| def PrintErrorForProject(project, error): |
| """Prints the project and its error. |
| |
| Args: |
| project: project name |
| error: An instance of the HookFailure class |
| """ |
| _PrintWithIndent(_PROJECT_INFO % project, 0) |
| _PrintWithIndent(_FormatHookFailure(error), 1) |
| print >> sys.stderr, '' |
| |
| |
| def PrintErrorsForCommit(project, commit, commit_desc, error_list): |
| """Prints the hook error to stderr with project and commit context |
| |
| A sample error output for a project would be: |
| ---------------------------------------------------------------------------- |
| Errors in PROJECT *chromiumos/repohooks*! |
| COMMIT 10041758: |
| Description: |
| >staged |
| > |
| >TEST=some |
| >Change-Id: I2c4f545a20a659541c02be16aa9dc440c876a604 |
| > |
| Errors: |
| * Changelist description needs BUG field (after first line) |
| * Found line ending with white space in: |
| * src/repohooks/pre-upload.py, line 307 |
| * Found lines longer than 80 characters (first 5 shown): |
| * src/repohooks/pre-upload.py, line 335, 85 chars |
| ---------------------------------------------------------------------------- |
| |
| Args: |
| project: project name |
| commit: the commit hash the errors belong to |
| commit_desc: a string containing the commit message |
| error_list: a list of HookFailure instances |
| """ |
| _PrintWithIndent(_PROJECT_INFO % project, 0) |
| |
| formatted_desc = _FormatCommitDesc(commit_desc) |
| _PrintWithIndent('COMMIT %s:' % commit[:8], 1) |
| _PrintWithIndent('Description:', 2) |
| _PrintWithIndent(formatted_desc, 3) |
| _PrintWithIndent('Errors:', 2) |
| |
| for error in error_list: |
| _PrintWithIndent(_FormatHookFailure(error), 3) |
| |
| print >> sys.stderr, '' |
| |