Upstream version 8.36.161.0
[platform/framework/web/crosswalk.git] / src / third_party / chromite / scripts / cbuildbot_view_config.py
1 # Copyright (c) 2013 The Chromium OS 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 """Script for dumping and/or comparing build config contents."""
6
7 import json
8 import pprint
9
10 from chromite.buildbot import cbuildbot_config
11 from chromite.lib import commandline
12 from chromite.lib import cros_build_lib
13
14
15 class _JSONEncoder(json.JSONEncoder):
16   """Json Encoder that encodes objects as their dictionaries."""
17   # pylint: disable=E0202
18   def default(self, obj):
19     return self.encode(obj.__dict__)
20
21
22 def _InjectDisplayPosition(config):
23   """Add field to help buildbot masters order builders on the waterfall.
24
25   Args:
26     config: A dict of build config items.
27
28   Returns:
29     A similar config where each config item has a new 'display_position' value.
30   """
31   def _GetSortKey(items):
32     my_config = items[1]
33     # Allow configs to override the display_position.
34     return (my_config.get('display_position', 1000000),
35             cbuildbot_config.GetDisplayPosition(my_config['name']),
36             my_config['internal'], my_config['vm_tests'])
37
38   source = sorted(config.iteritems(), key=_GetSortKey)
39   return dict((name, dict(value.items() + [('display_position', idx)]))
40               for idx, (name, value) in enumerate(source))
41
42
43 def _DumpConfigJson(cfg):
44   """Dump |cfg| contents in JSON format.
45
46   Args:
47     cfg: A single build config.
48   """
49   print json.dumps(cfg, cls=_JSONEncoder)
50
51
52 def _DumpConfigPrettyJson(cfg):
53   """Dump |cfg| contents in pretty JSON format.
54
55   Args:
56     cfg: A single build config.
57   """
58   print json.dumps(cfg, cls=_JSONEncoder,
59                    sort_keys=True, indent=4, separators=(',', ': '))
60
61
62 def _DumpConfigPrettyPrint(cfg):
63   """Dump |cfg| contents in pretty printer format.
64
65   Args:
66     cfg: A single build config.
67   """
68   pretty_printer = pprint.PrettyPrinter(indent=2)
69   pretty_printer.pprint(cfg)
70
71
72 def _CompareConfig(old_cfg, new_cfg):
73   """Compare two build configs targets, printing results.
74
75   Args:
76     old_cfg: The 'from' build config for comparison.
77     new_cfg: The 'to' build config for comparison.
78   """
79   new_cfg = json.loads(json.dumps(new_cfg, cls=_JSONEncoder))
80   for key in sorted(set(new_cfg.keys() + old_cfg.keys())):
81     obj1, obj2 = old_cfg.get(key), new_cfg.get(key)
82     if obj1 == obj2:
83       continue
84     elif obj1 is None:
85       print '%s: added to config\n' % (key,)
86       continue
87     elif obj2 is None:
88       print '%s: removed from config\n' % (key,)
89       continue
90
91     print '%s:' % (key,)
92
93     for subkey in sorted(set(obj1.keys() + obj2.keys())):
94       sobj1, sobj2 = obj1.get(subkey), obj2.get(subkey)
95       if sobj1 != sobj2:
96         print ' %s: %r, %r' % (subkey, sobj1, sobj2)
97
98     print
99
100
101 def GetParser():
102   """Creates the argparse parser."""
103   parser = commandline.ArgumentParser(description=__doc__)
104
105   # Put options that control the mode of script into mutually exclusive group.
106   mode = parser.add_mutually_exclusive_group(required=True)
107   mode.add_argument('-c', '--compare', action='store',
108                     type=commandline.argparse.FileType('rb'),
109                     default=None, metavar='file_name',
110                     help='Compare current config against a saved on disk '
111                          'serialized (json) dump of a config.')
112   mode.add_argument('-d', '--dump', action='store_true', default=False,
113                     help='Dump the configs in JSON format.')
114
115   parser.add_argument('--pretty', action='store_true', default=False,
116                       help='If dumping, make json output human readable.')
117   parser.add_argument('--for-buildbot', action='store_true', default=False,
118                       help='Include the display position in data.')
119   parser.add_argument('config_targets', metavar='config_target', nargs='*',
120                       help='Name of a cbuildbot config target.')
121
122   return parser
123
124
125 def main(argv):
126   parser = GetParser()
127   options = parser.parse_args(argv)
128
129   if options.pretty and not options.dump:
130     parser.error('The --pretty option does not make sense without --dump')
131
132   # Possibly translate config contents first.
133   convert = lambda x: x
134   if options.for_buildbot:
135     convert = _InjectDisplayPosition
136
137   config = convert(cbuildbot_config.config)
138
139   # If config_targets specified, only dump/load those.
140   if options.config_targets:
141     temp_config = dict()
142     for c in options.config_targets:
143       try:
144         temp_config[c] = config[c]
145       except KeyError:
146         cros_build_lib.Die('No such config id: %s', c)
147
148     config = temp_config
149
150   if config:
151     if options.dump:
152       if options.pretty:
153         _DumpConfigPrettyJson(config)
154       else:
155         _DumpConfigJson(config)
156     elif options.compare:
157       # Load the previously saved build config for comparison.
158       old_cfg = convert(json.load(options.compare))
159       _CompareConfig(old_cfg, config)
160
161   return 0