1a8f774549e35b743afae35e3436f73e8849e869depoger#!/usr/bin/python
2a8f774549e35b743afae35e3436f73e8849e869depoger# Copyright (c) 2014 The Chromium Authors. All rights reserved.
3a8f774549e35b743afae35e3436f73e8849e869depoger# Use of this source code is governed by a BSD-style license that can be
4a8f774549e35b743afae35e3436f73e8849e869depoger# found in the LICENSE file.
5a8f774549e35b743afae35e3436f73e8849e869depoger
6a8f774549e35b743afae35e3436f73e8849e869depoger"""Utility to duplicate a config in some subset of our GM expectation files.
7a8f774549e35b743afae35e3436f73e8849e869depoger
8a8f774549e35b743afae35e3436f73e8849e869depogerCreated for http://skbug.com/2752 ('split existing "gpu" GM results into "gl"
9a8f774549e35b743afae35e3436f73e8849e869depogerand "gles"')
10a8f774549e35b743afae35e3436f73e8849e869depoger
11a8f774549e35b743afae35e3436f73e8849e869depogerRun with -h to see usage.
12a8f774549e35b743afae35e3436f73e8849e869depoger
13a8f774549e35b743afae35e3436f73e8849e869depogerExample command lines:
14a8f774549e35b743afae35e3436f73e8849e869depoger  copy_config.py gl gles '.*Mac10.7.*'
15a8f774549e35b743afae35e3436f73e8849e869depoger
16a8f774549e35b743afae35e3436f73e8849e869depogerTODO(epoger): Once https://codereview.chromium.org/397103003/ is committed,
17a8f774549e35b743afae35e3436f73e8849e869depogerwe should add a unittest.  Until then, we can test this as follows:
18a8f774549e35b743afae35e3436f73e8849e869depoger
19a8f774549e35b743afae35e3436f73e8849e869depogerOLD=expectations/gm && NEW=/tmp/expectations && \
20a8f774549e35b743afae35e3436f73e8849e869depoger  rm -rf $NEW && \
21a8f774549e35b743afae35e3436f73e8849e869depoger  cp -a $OLD $NEW && \
22a8f774549e35b743afae35e3436f73e8849e869depoger  gm/copy_config.py 8888 8888-copy '.*Mac10.7.*' \
23a8f774549e35b743afae35e3436f73e8849e869depoger    --expectations-root $NEW && \
24a8f774549e35b743afae35e3436f73e8849e869depoger  diff --recursive $OLD $NEW
25a8f774549e35b743afae35e3436f73e8849e869depoger"""
26a8f774549e35b743afae35e3436f73e8849e869depoger__author__ = 'Elliot Poger'
27a8f774549e35b743afae35e3436f73e8849e869depoger
28a8f774549e35b743afae35e3436f73e8849e869depogerimport argparse
29a8f774549e35b743afae35e3436f73e8849e869depogerimport os
30a8f774549e35b743afae35e3436f73e8849e869depogerimport re
31a8f774549e35b743afae35e3436f73e8849e869depoger
32a8f774549e35b743afae35e3436f73e8849e869depogerimport gm_json
33a8f774549e35b743afae35e3436f73e8849e869depoger
34a8f774549e35b743afae35e3436f73e8849e869depogerDEFAULT_EXPECTATIONS_ROOT = os.path.join(
35a8f774549e35b743afae35e3436f73e8849e869depoger    os.path.dirname(__file__), os.pardir, 'expectations', 'gm')
36a8f774549e35b743afae35e3436f73e8849e869depogerIMAGE_FILENAME_RE = re.compile(gm_json.IMAGE_FILENAME_PATTERN)
37a8f774549e35b743afae35e3436f73e8849e869depoger
38a8f774549e35b743afae35e3436f73e8849e869depoger
39a8f774549e35b743afae35e3436f73e8849e869depogerclass Copier(object):
40a8f774549e35b743afae35e3436f73e8849e869depoger
41a8f774549e35b743afae35e3436f73e8849e869depoger  def __init__(self, args):
42a8f774549e35b743afae35e3436f73e8849e869depoger    """
43a8f774549e35b743afae35e3436f73e8849e869depoger    Params:
44a8f774549e35b743afae35e3436f73e8849e869depoger      args: the Namespace object generated by argparse.parse_args()
45a8f774549e35b743afae35e3436f73e8849e869depoger    """
46a8f774549e35b743afae35e3436f73e8849e869depoger    self._args = args
47a8f774549e35b743afae35e3436f73e8849e869depoger
48a8f774549e35b743afae35e3436f73e8849e869depoger  def run(self):
49a8f774549e35b743afae35e3436f73e8849e869depoger    """Perform all the duplications."""
50a8f774549e35b743afae35e3436f73e8849e869depoger    for path in self._get_file_list():
51a8f774549e35b743afae35e3436f73e8849e869depoger      self._duplicate_config(path=path,
52a8f774549e35b743afae35e3436f73e8849e869depoger                             old=self._args.old_config_name,
53a8f774549e35b743afae35e3436f73e8849e869depoger                             new=self._args.new_config_name)
54a8f774549e35b743afae35e3436f73e8849e869depoger
55a8f774549e35b743afae35e3436f73e8849e869depoger  def _duplicate_config(self, path, old, new):
56a8f774549e35b743afae35e3436f73e8849e869depoger    """Duplicates all instances of a config within a GM expectations file.
57a8f774549e35b743afae35e3436f73e8849e869depoger
58a8f774549e35b743afae35e3436f73e8849e869depoger    Params:
59a8f774549e35b743afae35e3436f73e8849e869depoger      path: path to file which will be modified in place
60a8f774549e35b743afae35e3436f73e8849e869depoger      old: old config name
61a8f774549e35b743afae35e3436f73e8849e869depoger      new: new config name
62a8f774549e35b743afae35e3436f73e8849e869depoger    """
63a8f774549e35b743afae35e3436f73e8849e869depoger    dic = gm_json.LoadFromFile(file_path=path)
64a8f774549e35b743afae35e3436f73e8849e869depoger    expected_results = dic[gm_json.JSONKEY_EXPECTEDRESULTS]
65a8f774549e35b743afae35e3436f73e8849e869depoger    orig_keys = expected_results.keys()
66a8f774549e35b743afae35e3436f73e8849e869depoger    for key in orig_keys:
67a8f774549e35b743afae35e3436f73e8849e869depoger      result = expected_results[key]
68a8f774549e35b743afae35e3436f73e8849e869depoger      (testname, config) = IMAGE_FILENAME_RE.match(key).groups()
69a8f774549e35b743afae35e3436f73e8849e869depoger      if config == old:
70a8f774549e35b743afae35e3436f73e8849e869depoger        config = new
71a8f774549e35b743afae35e3436f73e8849e869depoger        key = '%s_%s.png' % (testname, config)
72a8f774549e35b743afae35e3436f73e8849e869depoger        expected_results[key] = result
73a8f774549e35b743afae35e3436f73e8849e869depoger    gm_json.WriteToFile(json_dict=dic, file_path=path)
74a8f774549e35b743afae35e3436f73e8849e869depoger
75a8f774549e35b743afae35e3436f73e8849e869depoger  def _get_file_list(self):
76a8f774549e35b743afae35e3436f73e8849e869depoger    """Returns the list of files we want to operate on (the complete path
77a8f774549e35b743afae35e3436f73e8849e869depoger    to each file)."""
78a8f774549e35b743afae35e3436f73e8849e869depoger    root = self._args.expectations_root
79a8f774549e35b743afae35e3436f73e8849e869depoger    regex = re.compile(self._args.builder_name_pattern)
80a8f774549e35b743afae35e3436f73e8849e869depoger    return [os.path.join(root, builder, 'expected-results.json')
81a8f774549e35b743afae35e3436f73e8849e869depoger            for builder in os.listdir(root)
82a8f774549e35b743afae35e3436f73e8849e869depoger            if regex.match(builder)]
83a8f774549e35b743afae35e3436f73e8849e869depoger
84a8f774549e35b743afae35e3436f73e8849e869depoger
85a8f774549e35b743afae35e3436f73e8849e869depogerdef main():
86a8f774549e35b743afae35e3436f73e8849e869depoger  parser = argparse.ArgumentParser()
87a8f774549e35b743afae35e3436f73e8849e869depoger  parser.add_argument('old_config_name',
88a8f774549e35b743afae35e3436f73e8849e869depoger                      help=('Config we want to duplicate.'))
89a8f774549e35b743afae35e3436f73e8849e869depoger  parser.add_argument('new_config_name',
90a8f774549e35b743afae35e3436f73e8849e869depoger                      help=('Name of the new config we want to create.'))
91a8f774549e35b743afae35e3436f73e8849e869depoger  parser.add_argument('builder_name_pattern',
92a8f774549e35b743afae35e3436f73e8849e869depoger                      help=('Regex pattern describing which builders we want '
93a8f774549e35b743afae35e3436f73e8849e869depoger                            'to make the duplication for; \'.*\' to perform '
94a8f774549e35b743afae35e3436f73e8849e869depoger                            'the duplication on all builders.'))
95a8f774549e35b743afae35e3436f73e8849e869depoger  parser.add_argument('--expectations-root',
96a8f774549e35b743afae35e3436f73e8849e869depoger                      default=DEFAULT_EXPECTATIONS_ROOT,
97a8f774549e35b743afae35e3436f73e8849e869depoger                      help=('Root of the GM expectations dir; defaults to '
98a8f774549e35b743afae35e3436f73e8849e869depoger                            '%(default)s'))
99a8f774549e35b743afae35e3436f73e8849e869depoger  args = parser.parse_args()
100a8f774549e35b743afae35e3436f73e8849e869depoger  copier = Copier(args)
101a8f774549e35b743afae35e3436f73e8849e869depoger  copier.run()
102a8f774549e35b743afae35e3436f73e8849e869depoger
103a8f774549e35b743afae35e3436f73e8849e869depogerif __name__ == '__main__':
104a8f774549e35b743afae35e3436f73e8849e869depoger  main()
105