[sql] Remove _HAS_EXCEPTIONS=0 from build info.
[chromium-blink-merge.git] / tools / metrics / rappor / pretty_print.py
blob5e44ce40620ff052cc6daca1e5030e33320d09d5
1 #!/usr/bin/env python
2 # Copyright 2015 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
6 import logging
7 import os
8 import sys
10 sys.path.append(os.path.join(os.path.dirname(__file__), '..', 'common'))
11 import models
12 import presubmit_util
15 # Model definitions for rappor.xml content
16 _SUMMARY_TYPE = models.TextNodeType('summary')
18 _PARAMETERS_TYPE = models.ObjectNodeType('parameters',
19 int_attributes=[
20 'num-cohorts',
21 'bytes',
22 'hash-functions',
24 float_attributes=[
25 'fake-prob',
26 'fake-one-prob',
27 'one-coin-prob',
28 'zero-coin-prob',
30 string_attributes=[
31 'reporting-level'
34 _RAPPOR_PARAMETERS_TYPE = models.ObjectNodeType('rappor-parameters',
35 extra_newlines=(1, 1, 1),
36 string_attributes=['name'],
37 children=[
38 models.ChildType('summary', _SUMMARY_TYPE, False),
39 models.ChildType('parameters', _PARAMETERS_TYPE, False),
42 _RAPPOR_PARAMETERS_TYPES_TYPE = models.ObjectNodeType('rappor-parameter-types',
43 extra_newlines=(1, 1, 1),
44 dont_indent=True,
45 children=[
46 models.ChildType('types', _RAPPOR_PARAMETERS_TYPE, True),
49 _OWNER_TYPE = models.TextNodeType('owner', single_line=True)
51 _STRING_FIELD_TYPE = models.ObjectNodeType('string-field',
52 extra_newlines=(1, 1, 0),
53 string_attributes=['name'],
54 children=[
55 models.ChildType('summary', _SUMMARY_TYPE, False),
58 _FLAG_TYPE = models.TextNodeType('flag', single_line=True)
60 _FLAGS_FIELD_TYPE = models.ObjectNodeType('flags-field',
61 extra_newlines=(1, 1, 0),
62 string_attributes=['name'],
63 children=[
64 models.ChildType('flags', _FLAG_TYPE, True),
65 models.ChildType('summary', _SUMMARY_TYPE, False),
68 _RAPPOR_METRIC_TYPE = models.ObjectNodeType('rappor-metric',
69 extra_newlines=(1, 1, 1),
70 string_attributes=['name', 'type'],
71 children=[
72 models.ChildType('owners', _OWNER_TYPE, True),
73 models.ChildType('summary', _SUMMARY_TYPE, False),
74 models.ChildType('strings', _STRING_FIELD_TYPE, True),
75 models.ChildType('flags', _FLAGS_FIELD_TYPE, True),
78 _RAPPOR_METRICS_TYPE = models.ObjectNodeType('rappor-metrics',
79 extra_newlines=(1, 1, 1),
80 dont_indent=True,
81 children=[
82 models.ChildType('metrics', _RAPPOR_METRIC_TYPE, True),
85 _RAPPOR_CONFIGURATION_TYPE = models.ObjectNodeType('rappor-configuration',
86 extra_newlines=(1, 1, 1),
87 dont_indent=True,
88 children=[
89 models.ChildType('parameterTypes', _RAPPOR_PARAMETERS_TYPES_TYPE, False),
90 models.ChildType('metrics', _RAPPOR_METRICS_TYPE, False),
93 RAPPOR_XML_TYPE = models.DocumentType(_RAPPOR_CONFIGURATION_TYPE)
96 def GetTypeNames(config):
97 return set(p['name'] for p in config['parameterTypes']['types'])
100 def GetMissingOwnerErrors(metrics):
101 """Check that all of the metrics have owners.
103 Args:
104 metrics: A list of rappor metric description objects.
106 Returns:
107 A list of errors about metrics missing owners.
109 missing_owners = [m for m in metrics if not m['owners']]
110 return ['Rappor metric "%s" is missing an owner.' % metric['name']
111 for metric in missing_owners]
114 def GetInvalidTypeErrors(type_names, metrics):
115 """Check that all of the metrics have valid types.
117 Args:
118 type_names: The set of valid type names.
119 metrics: A list of rappor metric description objects.
121 Returns:
122 A list of errors about metrics with invalid_types.
124 invalid_types = [m for m in metrics if m['type'] not in type_names]
125 return ['Rappor metric "%s" has invalid type "%s"' % (
126 metric['name'], metric['type'])
127 for metric in invalid_types]
130 def GetErrors(config):
131 """Check that rappor.xml passes some basic validation checks.
133 Args:
134 config: The parsed rappor.xml contents.
136 Returns:
137 A list of validation errors.
139 metrics = config['metrics']['metrics']
140 type_names = GetTypeNames(config)
141 return (GetMissingOwnerErrors(metrics) or
142 GetInvalidTypeErrors(type_names, metrics))
145 def Cleanup(config):
146 """Preform cleanup on description contents, such as sorting metrics.
148 Args:
149 config: The parsed rappor.xml contents.
151 types = config['parameterTypes']['types']
152 types.sort(key=lambda x: x['name'])
153 metrics = config['metrics']['metrics']
154 metrics.sort(key=lambda x: x['name'])
157 def UpdateXML(original_xml):
158 """Parse the original xml and return a pretty printed version.
160 Args:
161 original_xml: A string containing the original xml file contents.
163 Returns:
164 A Pretty printed xml string.
166 comments, config = RAPPOR_XML_TYPE.Parse(original_xml)
168 errors = GetErrors(config)
169 if errors:
170 for error in errors:
171 logging.error("%s", error)
172 return None
174 Cleanup(config)
176 return RAPPOR_XML_TYPE.PrettyPrint(comments, config)
179 def main(argv):
180 presubmit_util.DoPresubmitMain(argv, 'rappor.xml', 'rappor.old.xml',
181 'pretty_print.py', UpdateXML)
184 if '__main__' == __name__:
185 sys.exit(main(sys.argv))