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 # Import the metrics/common module for pretty print xml.
11 sys
.path
.append(os
.path
.join(os
.path
.dirname(__file__
), '..', 'common'))
16 # Model definitions for rappor.xml content
17 _SUMMARY_TYPE
= models
.TextNodeType('summary')
19 _PARAMETERS_TYPE
= models
.ObjectNodeType('parameters',
35 _RAPPOR_PARAMETERS_TYPE
= models
.ObjectNodeType('rappor-parameters',
36 extra_newlines
=(1, 1, 1),
37 string_attributes
=['name'],
39 models
.ChildType('summary', _SUMMARY_TYPE
, False),
40 models
.ChildType('parameters', _PARAMETERS_TYPE
, False),
43 _RAPPOR_PARAMETERS_TYPES_TYPE
= models
.ObjectNodeType('rappor-parameter-types',
44 extra_newlines
=(1, 1, 1),
47 models
.ChildType('types', _RAPPOR_PARAMETERS_TYPE
, True),
50 _OWNER_TYPE
= models
.TextNodeType('owner', single_line
=True)
52 _RAPPOR_METRIC_TYPE
= models
.ObjectNodeType('rappor-metric',
53 extra_newlines
=(1, 1, 1),
54 string_attributes
=['name', 'type'],
56 models
.ChildType('owners', _OWNER_TYPE
, True),
57 models
.ChildType('summary', _SUMMARY_TYPE
, False),
60 _RAPPOR_METRICS_TYPE
= models
.ObjectNodeType('rappor-metrics',
61 extra_newlines
=(1, 1, 1),
64 models
.ChildType('metrics', _RAPPOR_METRIC_TYPE
, True),
67 _RAPPOR_CONFIGURATION_TYPE
= models
.ObjectNodeType('rappor-configuration',
68 extra_newlines
=(1, 1, 1),
71 models
.ChildType('parameterTypes', _RAPPOR_PARAMETERS_TYPES_TYPE
, False),
72 models
.ChildType('metrics', _RAPPOR_METRICS_TYPE
, False),
75 RAPPOR_XML_TYPE
= models
.DocumentType(_RAPPOR_CONFIGURATION_TYPE
)
78 def GetTypeNames(config
):
79 return set(p
['name'] for p
in config
['parameterTypes']['types'])
82 def HasMissingOwners(metrics
):
83 """Check that all of the metrics have owners.
86 metrics: A list of rappor metric description objects.
89 True iff some metrics are missing owners.
91 missing_owners
= [m
for m
in metrics
if not m
['owners']]
92 for metric
in missing_owners
:
93 logging
.error('Rappor metric "%s" is missing an owner.', metric
['name'])
95 return bool(missing_owners
)
98 def HasInvalidTypes(type_names
, metrics
):
99 """Check that all of the metrics have valid types.
102 type_names: The set of valid type names.
103 metrics: A list of rappor metric description objects.
106 True iff some metrics have invalid types.
108 invalid_types
= [m
for m
in metrics
if m
['type'] not in type_names
]
109 for metric
in invalid_types
:
110 logging
.error('Rappor metric "%s" has invalid type "%s"',
111 metric
['name'], metric
['type'])
112 return bool(invalid_types
)
115 def HasErrors(config
):
116 """Check that rappor.xml passes some basic validation checks.
119 config: The parsed rappor.xml contents.
122 True iff there are validation errors.
124 metrics
= config
['metrics']['metrics']
125 type_names
= GetTypeNames(config
)
126 return (HasMissingOwners(metrics
) or
127 HasInvalidTypes(type_names
, metrics
))
131 """Preform cleanup on description contents, such as sorting metrics.
134 config: The parsed rappor.xml contents.
136 types
= config
['parameterTypes']['types']
137 types
.sort(key
=lambda x
: x
['name'])
138 metrics
= config
['metrics']['metrics']
139 metrics
.sort(key
=lambda x
: x
['name'])
142 def UpdateXML(original_xml
):
143 """Parse the original xml and return a pretty printed version.
146 original_xml: A string containing the original xml file contents.
149 A Pretty printed xml string.
151 comments
, config
= RAPPOR_XML_TYPE
.Parse(original_xml
)
153 if HasErrors(config
):
158 return RAPPOR_XML_TYPE
.PrettyPrint(comments
, config
)
162 presubmit_util
.DoPresubmitMain(argv
, 'rappor.xml', 'rappor.old.xml',
163 'pretty_print.py', UpdateXML
)
166 if '__main__' == __name__
:
167 sys
.exit(main(sys
.argv
))