| OLD | NEW |
| (Empty) |
| 1 # Copyright (c) 2012 The Chromium 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 | |
| 5 | |
| 6 """Results object and results formatters for checkdeps tool.""" | |
| 7 | |
| 8 | |
| 9 import json | |
| 10 | |
| 11 | |
| 12 class DependencyViolation(object): | |
| 13 """A single dependency violation.""" | |
| 14 | |
| 15 def __init__(self, include_path, violated_rule, rules): | |
| 16 # The include or import path that is in violation of a rule. | |
| 17 self.include_path = include_path | |
| 18 | |
| 19 # The violated rule. | |
| 20 self.violated_rule = violated_rule | |
| 21 | |
| 22 # The set of rules containing self.violated_rule. | |
| 23 self.rules = rules | |
| 24 | |
| 25 | |
| 26 class DependeeStatus(object): | |
| 27 """Results object for a dependee file.""" | |
| 28 | |
| 29 def __init__(self, dependee_path): | |
| 30 # Path of the file whose nonconforming dependencies are listed in | |
| 31 # self.violations. | |
| 32 self.dependee_path = dependee_path | |
| 33 | |
| 34 # List of DependencyViolation objects that apply to the dependee | |
| 35 # file. May be empty. | |
| 36 self.violations = [] | |
| 37 | |
| 38 def AddViolation(self, violation): | |
| 39 """Adds a violation.""" | |
| 40 self.violations.append(violation) | |
| 41 | |
| 42 def HasViolations(self): | |
| 43 """Returns True if this dependee is violating one or more rules.""" | |
| 44 return not not self.violations | |
| 45 | |
| 46 | |
| 47 class ResultsFormatter(object): | |
| 48 """Base class for results formatters.""" | |
| 49 | |
| 50 def AddError(self, dependee_status): | |
| 51 """Add a formatted result to |self.results| for |dependee_status|, | |
| 52 which is guaranteed to return True for | |
| 53 |dependee_status.HasViolations|. | |
| 54 """ | |
| 55 raise NotImplementedError() | |
| 56 | |
| 57 def GetResults(self): | |
| 58 """Returns the results. May be overridden e.g. to process the | |
| 59 results that have been accumulated. | |
| 60 """ | |
| 61 raise NotImplementedError() | |
| 62 | |
| 63 def PrintResults(self): | |
| 64 """Prints the results to stdout.""" | |
| 65 raise NotImplementedError() | |
| 66 | |
| 67 | |
| 68 class NormalResultsFormatter(ResultsFormatter): | |
| 69 """A results formatting object that produces the classical, | |
| 70 detailed, human-readable output of the checkdeps tool. | |
| 71 """ | |
| 72 | |
| 73 def __init__(self, verbose): | |
| 74 self.results = [] | |
| 75 self.verbose = verbose | |
| 76 | |
| 77 def AddError(self, dependee_status): | |
| 78 lines = [] | |
| 79 lines.append('\nERROR in %s' % dependee_status.dependee_path) | |
| 80 for violation in dependee_status.violations: | |
| 81 lines.append(self.FormatViolation(violation, self.verbose)) | |
| 82 self.results.append('\n'.join(lines)) | |
| 83 | |
| 84 @staticmethod | |
| 85 def FormatViolation(violation, verbose=False): | |
| 86 lines = [] | |
| 87 if verbose: | |
| 88 lines.append(' For %s' % violation.rules) | |
| 89 lines.append( | |
| 90 ' Illegal include: "%s"\n Because of %s' % | |
| 91 (violation.include_path, str(violation.violated_rule))) | |
| 92 return '\n'.join(lines) | |
| 93 | |
| 94 def GetResults(self): | |
| 95 return self.results | |
| 96 | |
| 97 def PrintResults(self): | |
| 98 for result in self.results: | |
| 99 print result | |
| 100 if self.results: | |
| 101 print '\nFAILED\n' | |
| 102 | |
| 103 | |
| 104 class JSONResultsFormatter(ResultsFormatter): | |
| 105 """A results formatter that outputs results to a file as JSON.""" | |
| 106 | |
| 107 def __init__(self, output_path, wrapped_formatter=None): | |
| 108 self.output_path = output_path | |
| 109 self.wrapped_formatter = wrapped_formatter | |
| 110 | |
| 111 self.results = [] | |
| 112 | |
| 113 def AddError(self, dependee_status): | |
| 114 self.results.append({ | |
| 115 'dependee_path': dependee_status.dependee_path, | |
| 116 'violations': [{ | |
| 117 'include_path': violation.include_path, | |
| 118 'violated_rule': violation.violated_rule.AsDependencyTuple(), | |
| 119 } for violation in dependee_status.violations] | |
| 120 }) | |
| 121 | |
| 122 if self.wrapped_formatter: | |
| 123 self.wrapped_formatter.AddError(dependee_status) | |
| 124 | |
| 125 def GetResults(self): | |
| 126 with open(self.output_path, 'w') as f: | |
| 127 f.write(json.dumps(self.results)) | |
| 128 | |
| 129 return self.results | |
| 130 | |
| 131 def PrintResults(self): | |
| 132 if self.wrapped_formatter: | |
| 133 self.wrapped_formatter.PrintResults() | |
| 134 return | |
| 135 | |
| 136 print self.results | |
| 137 | |
| 138 | |
| 139 class TemporaryRulesFormatter(ResultsFormatter): | |
| 140 """A results formatter that produces a single line per nonconforming | |
| 141 include. The combined output is suitable for directly pasting into a | |
| 142 DEPS file as a list of temporary-allow rules. | |
| 143 """ | |
| 144 | |
| 145 def __init__(self): | |
| 146 self.violations = set() | |
| 147 | |
| 148 def AddError(self, dependee_status): | |
| 149 for violation in dependee_status.violations: | |
| 150 self.violations.add(violation.include_path) | |
| 151 | |
| 152 def GetResults(self): | |
| 153 return [' "!%s",' % path for path in sorted(self.violations)] | |
| 154 | |
| 155 def PrintResults(self): | |
| 156 for result in self.GetResults(): | |
| 157 print result | |
| 158 | |
| 159 | |
| 160 class CountViolationsFormatter(ResultsFormatter): | |
| 161 """A results formatter that produces a number, the count of #include | |
| 162 statements that are in violation of the dependency rules. | |
| 163 | |
| 164 Note that you normally want to instantiate DepsChecker with | |
| 165 ignore_temp_rules=True when you use this formatter. | |
| 166 """ | |
| 167 | |
| 168 def __init__(self): | |
| 169 self.count = 0 | |
| 170 | |
| 171 def AddError(self, dependee_status): | |
| 172 self.count += len(dependee_status.violations) | |
| 173 | |
| 174 def GetResults(self): | |
| 175 return '%d' % self.count | |
| 176 | |
| 177 def PrintResults(self): | |
| 178 print self.count | |
| OLD | NEW |