fixup! Upload upstream chromium 76.0.3809.146
[platform/framework/web/chromium-efl.git] / buildtools / checkdeps / results.py
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