| OLD | NEW |
| 1 #!/usr/bin/python | 1 #!/usr/bin/python |
| 2 | 2 |
| 3 """ | 3 """ |
| 4 Copyright 2013 Google Inc. | 4 Copyright 2013 Google Inc. |
| 5 | 5 |
| 6 Use of this source code is governed by a BSD-style license that can be | 6 Use of this source code is governed by a BSD-style license that can be |
| 7 found in the LICENSE file. | 7 found in the LICENSE file. |
| 8 | 8 |
| 9 Repackage expected/actual GM results as needed by our HTML rebaseline viewer. | 9 Repackage expected/actual GM results as needed by our HTML rebaseline viewer. |
| 10 """ | 10 """ |
| 11 | 11 |
| 12 # System-level imports | 12 # System-level imports |
| 13 import fnmatch | 13 import fnmatch |
| 14 import os | 14 import os |
| 15 import re | 15 import re |
| 16 | 16 |
| 17 # Must fix up PYTHONPATH before importing from within Skia |
| 18 # pylint: disable=W0611 |
| 19 import fix_pythonpath |
| 20 # pylint: enable=W0611 |
| 21 |
| 17 # Imports from within Skia | 22 # Imports from within Skia |
| 18 import fix_pythonpath # must do this first | |
| 19 import gm_json | 23 import gm_json |
| 20 import imagepairset | 24 import imagepairset |
| 21 | 25 |
| 22 # Keys used to link an image to a particular GM test. | 26 # Keys used to link an image to a particular GM test. |
| 23 # NOTE: Keep these in sync with static/constants.js | 27 # NOTE: Keep these in sync with static/constants.js |
| 24 VALUE__HEADER__SCHEMA_VERSION = 3 | 28 VALUE__HEADER__SCHEMA_VERSION = 4 |
| 25 KEY__EXPECTATIONS__BUGS = gm_json.JSONKEY_EXPECTEDRESULTS_BUGS | 29 KEY__EXPECTATIONS__BUGS = gm_json.JSONKEY_EXPECTEDRESULTS_BUGS |
| 26 KEY__EXPECTATIONS__IGNOREFAILURE = gm_json.JSONKEY_EXPECTEDRESULTS_IGNOREFAILURE | 30 KEY__EXPECTATIONS__IGNOREFAILURE = gm_json.JSONKEY_EXPECTEDRESULTS_IGNOREFAILURE |
| 27 KEY__EXPECTATIONS__REVIEWED = gm_json.JSONKEY_EXPECTEDRESULTS_REVIEWED | 31 KEY__EXPECTATIONS__REVIEWED = gm_json.JSONKEY_EXPECTEDRESULTS_REVIEWED |
| 28 KEY__EXTRACOLUMNS__BUILDER = 'builder' | 32 KEY__EXTRACOLUMNS__BUILDER = 'builder' |
| 29 KEY__EXTRACOLUMNS__CONFIG = 'config' | 33 KEY__EXTRACOLUMNS__CONFIG = 'config' |
| 30 KEY__EXTRACOLUMNS__RESULT_TYPE = 'resultType' | 34 KEY__EXTRACOLUMNS__RESULT_TYPE = 'resultType' |
| 31 KEY__EXTRACOLUMNS__TEST = 'test' | 35 KEY__EXTRACOLUMNS__TEST = 'test' |
| 32 KEY__HEADER__DATAHASH = 'dataHash' | 36 KEY__HEADER__DATAHASH = 'dataHash' |
| 33 KEY__HEADER__IS_EDITABLE = 'isEditable' | 37 KEY__HEADER__IS_EDITABLE = 'isEditable' |
| 34 KEY__HEADER__IS_EXPORTED = 'isExported' | 38 KEY__HEADER__IS_EXPORTED = 'isExported' |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 194 where each JSON dictionary was found). | 198 where each JSON dictionary was found). |
| 195 | 199 |
| 196 Raises: | 200 Raises: |
| 197 IOError if root does not refer to an existing directory | 201 IOError if root does not refer to an existing directory |
| 198 """ | 202 """ |
| 199 # I considered making this call _read_dicts_from_root(), but I decided | 203 # I considered making this call _read_dicts_from_root(), but I decided |
| 200 # it was better to prune out the ignored builders within the os.walk(). | 204 # it was better to prune out the ignored builders within the os.walk(). |
| 201 if not os.path.isdir(root): | 205 if not os.path.isdir(root): |
| 202 raise IOError('no directory found at path %s' % root) | 206 raise IOError('no directory found at path %s' % root) |
| 203 meta_dict = {} | 207 meta_dict = {} |
| 204 for dirpath, dirnames, filenames in os.walk(root): | 208 for dirpath, _, filenames in os.walk(root): |
| 205 for matching_filename in fnmatch.filter(filenames, pattern): | 209 for matching_filename in fnmatch.filter(filenames, pattern): |
| 206 builder = os.path.basename(dirpath) | 210 builder = os.path.basename(dirpath) |
| 207 if self._ignore_builder(builder): | 211 if self._ignore_builder(builder): |
| 208 continue | 212 continue |
| 209 full_path = os.path.join(dirpath, matching_filename) | 213 full_path = os.path.join(dirpath, matching_filename) |
| 210 meta_dict[builder] = gm_json.LoadFromFile(full_path) | 214 meta_dict[builder] = gm_json.LoadFromFile(full_path) |
| 211 return meta_dict | 215 return meta_dict |
| 212 | 216 |
| 213 def _read_dicts_from_root(self, root, pattern='*.json'): | 217 def _read_dicts_from_root(self, root, pattern='*.json'): |
| 214 """Read all JSON dictionaries within a directory tree. | 218 """Read all JSON dictionaries within a directory tree. |
| 215 | 219 |
| 216 Args: | 220 Args: |
| 217 root: path to root of directory tree | 221 root: path to root of directory tree |
| 218 pattern: which files to read within root (fnmatch-style pattern) | 222 pattern: which files to read within root (fnmatch-style pattern) |
| 219 | 223 |
| 220 Returns: | 224 Returns: |
| 221 A meta-dictionary containing all the JSON dictionaries found within | 225 A meta-dictionary containing all the JSON dictionaries found within |
| 222 the directory tree, keyed by the pathname (relative to root) of each JSON | 226 the directory tree, keyed by the pathname (relative to root) of each JSON |
| 223 dictionary. | 227 dictionary. |
| 224 | 228 |
| 225 Raises: | 229 Raises: |
| 226 IOError if root does not refer to an existing directory | 230 IOError if root does not refer to an existing directory |
| 227 """ | 231 """ |
| 228 if not os.path.isdir(root): | 232 if not os.path.isdir(root): |
| 229 raise IOError('no directory found at path %s' % root) | 233 raise IOError('no directory found at path %s' % root) |
| 230 meta_dict = {} | 234 meta_dict = {} |
| 231 for abs_dirpath, dirnames, filenames in os.walk(root): | 235 for abs_dirpath, _, filenames in os.walk(root): |
| 232 rel_dirpath = os.path.relpath(abs_dirpath, root) | 236 rel_dirpath = os.path.relpath(abs_dirpath, root) |
| 233 for matching_filename in fnmatch.filter(filenames, pattern): | 237 for matching_filename in fnmatch.filter(filenames, pattern): |
| 234 abs_path = os.path.join(abs_dirpath, matching_filename) | 238 abs_path = os.path.join(abs_dirpath, matching_filename) |
| 235 rel_path = os.path.join(rel_dirpath, matching_filename) | 239 rel_path = os.path.join(rel_dirpath, matching_filename) |
| 236 meta_dict[rel_path] = gm_json.LoadFromFile(abs_path) | 240 meta_dict[rel_path] = gm_json.LoadFromFile(abs_path) |
| 237 return meta_dict | 241 return meta_dict |
| 238 | 242 |
| 239 @staticmethod | 243 @staticmethod |
| 240 def _read_noncomment_lines(path): | 244 def _read_noncomment_lines(path): |
| 241 """Return a list of all noncomment lines within a file. | 245 """Return a list of all noncomment lines within a file. |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 286 | 290 |
| 287 Output: | 291 Output: |
| 288 { | 292 { |
| 289 KEY_B1 : VALUE_B1, | 293 KEY_B1 : VALUE_B1, |
| 290 KEY_B2 : VALUE_B2, | 294 KEY_B2 : VALUE_B2, |
| 291 } | 295 } |
| 292 | 296 |
| 293 If this would result in any repeated keys, it will raise an Exception. | 297 If this would result in any repeated keys, it will raise an Exception. |
| 294 """ | 298 """ |
| 295 output_dict = {} | 299 output_dict = {} |
| 296 for key, subdict in input_dict.iteritems(): | 300 for subdict in input_dict.values(): |
| 297 for subdict_key, subdict_value in subdict.iteritems(): | 301 for subdict_key, subdict_value in subdict.iteritems(): |
| 298 if subdict_key in output_dict: | 302 if subdict_key in output_dict: |
| 299 raise Exception('duplicate key %s in combine_subdicts' % subdict_key) | 303 raise Exception('duplicate key %s in combine_subdicts' % subdict_key) |
| 300 output_dict[subdict_key] = subdict_value | 304 output_dict[subdict_key] = subdict_value |
| 301 return output_dict | 305 return output_dict |
| 302 | 306 |
| 303 @staticmethod | 307 @staticmethod |
| 304 def get_multilevel(input_dict, *keys): | 308 def get_multilevel(input_dict, *keys): |
| 305 """ Returns input_dict[key1][key2][...], or None if any key is not found. | 309 """ Returns input_dict[key1][key2][...], or None if any key is not found. |
| 306 """ | 310 """ |
| 307 for key in keys: | 311 for key in keys: |
| 308 if input_dict == None: | 312 if input_dict == None: |
| 309 return None | 313 return None |
| 310 input_dict = input_dict.get(key, None) | 314 input_dict = input_dict.get(key, None) |
| 311 return input_dict | 315 return input_dict |
| OLD | NEW |