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.
10 sys
.path
.append(os
.path
.join(os
.path
.dirname(__file__
), '..', 'common'))
15 # Model definitions for rappor.xml content
16 _SUMMARY_TYPE
= models
.TextNodeType('summary')
18 _PARAMETERS_TYPE
= models
.ObjectNodeType('parameters',
34 _RAPPOR_PARAMETERS_TYPE
= models
.ObjectNodeType('rappor-parameters',
35 extra_newlines
=(1, 1, 1),
36 string_attributes
=['name'],
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),
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'],
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'],
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'],
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),
82 models
.ChildType('metrics', _RAPPOR_METRIC_TYPE
, True),
85 _RAPPOR_CONFIGURATION_TYPE
= models
.ObjectNodeType('rappor-configuration',
86 extra_newlines
=(1, 1, 1),
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.
104 metrics: A list of rappor metric description objects.
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.
118 type_names: The set of valid type names.
119 metrics: A list of rappor metric description objects.
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.
134 config: The parsed rappor.xml contents.
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
))
146 """Preform cleanup on description contents, such as sorting metrics.
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.
161 original_xml: A string containing the original xml file contents.
164 A Pretty printed xml string.
166 comments
, config
= RAPPOR_XML_TYPE
.Parse(original_xml
)
168 errors
= GetErrors(config
)
171 logging
.error("%s", error
)
176 return RAPPOR_XML_TYPE
.PrettyPrint(comments
, config
)
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
))