blob: 1a0f7dc8aca5ae4073374c7ebbf1707d39478508 [file] [log] [blame]
Ryan Cui1562fb82011-05-09 11:01:31 -07001# Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
Mike Frysingerae409522014-02-01 03:16:11 -05005"""Common errors thrown when repo presubmit checks fail."""
6
Mike Frysinger09d6a3d2013-10-08 22:21:03 -04007from __future__ import print_function
8
Ryan Cui1562fb82011-05-09 11:01:31 -07009import re
10import sys
11
12
13class VerifyException(Exception):
Mike Frysingerae409522014-02-01 03:16:11 -050014 """Basic sanity checks failed."""
Ryan Cui1562fb82011-05-09 11:01:31 -070015
16
17class HookFailure(object):
18 """Contains an error message and a list of error details."""
19 def __init__(self, msg, items=None):
20 self.msg = msg
21 self.items = items
22
23
24_INDENT = ' ' * 4
25_PROJECT_INFO = 'Errors in PROJECT *%s*!'
26
Mike Frysingerae409522014-02-01 03:16:11 -050027
Ryan Cui1562fb82011-05-09 11:01:31 -070028def _PrintWithIndent(msg, indent_level):
29 """Print a block of text with a specified indent level to stderr.
30
31 Args:
32 msg: A string to print (may contain newlines).
33 indent_level: The number of indents to prefix each line with. Each indent
34 is four characters wide.
35 """
36 regex = re.compile(r'^', re.M)
37 msg = regex.sub(_INDENT * indent_level, msg)
Mike Frysinger09d6a3d2013-10-08 22:21:03 -040038 print(msg, file=sys.stderr)
Ryan Cui1562fb82011-05-09 11:01:31 -070039
40
41def _FormatCommitDesc(desc):
42 """Returns the properly prefixed commit description."""
43 regex = re.compile(r'^', re.M)
44 return regex.sub('>', desc)
45
46
47def _FormatHookFailure(hook_failure):
48 """Returns the properly formatted VerifyException as a string."""
49 item_prefix = '\n%s* ' % _INDENT
50 formatted_items = ''
51 if hook_failure.items:
52 formatted_items = item_prefix + item_prefix.join(hook_failure.items)
53 return '* ' + hook_failure.msg + formatted_items
54
55
56def PrintErrorForProject(project, error):
57 """Prints the project and its error.
58
59 Args:
60 project: project name
61 error: An instance of the HookFailure class
62 """
63 _PrintWithIndent(_PROJECT_INFO % project, 0)
64 _PrintWithIndent(_FormatHookFailure(error), 1)
Mike Frysinger09d6a3d2013-10-08 22:21:03 -040065 print('', file=sys.stderr)
Ryan Cui1562fb82011-05-09 11:01:31 -070066
67
68def PrintErrorsForCommit(project, commit, commit_desc, error_list):
69 """Prints the hook error to stderr with project and commit context
70
71 A sample error output for a project would be:
72 ----------------------------------------------------------------------------
73 Errors in PROJECT *chromiumos/repohooks*!
74 COMMIT 10041758:
75 Description:
76 >staged
77 >
78 >TEST=some
79 >Change-Id: I2c4f545a20a659541c02be16aa9dc440c876a604
80 >
81 Errors:
82 * Changelist description needs BUG field (after first line)
83 * Found line ending with white space in:
84 * src/repohooks/pre-upload.py, line 307
85 * Found lines longer than 80 characters (first 5 shown):
86 * src/repohooks/pre-upload.py, line 335, 85 chars
87 ----------------------------------------------------------------------------
88
89 Args:
90 project: project name
91 commit: the commit hash the errors belong to
92 commit_desc: a string containing the commit message
93 error_list: a list of HookFailure instances
94 """
95 _PrintWithIndent(_PROJECT_INFO % project, 0)
96
97 formatted_desc = _FormatCommitDesc(commit_desc)
98 _PrintWithIndent('COMMIT %s:' % commit[:8], 1)
99 _PrintWithIndent('Description:', 2)
100 _PrintWithIndent(formatted_desc, 3)
101 _PrintWithIndent('Errors:', 2)
102
103 for error in error_list:
104 _PrintWithIndent(_FormatHookFailure(error), 3)
105
Mike Frysinger09d6a3d2013-10-08 22:21:03 -0400106 print('', file=sys.stderr)