OLD | NEW |
1 # Copyright 2013 The Chromium Authors. All rights reserved. | 1 # Copyright 2013 The Chromium Authors. All rights reserved. |
2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 | 4 |
5 ''' | 5 ''' |
6 Utility functions for working with the Feature abstraction. Features are grouped | 6 Utility functions for working with the Feature abstraction. Features are grouped |
7 into a dictionary by name. Each Feature is guaranteed to have the following two | 7 into a dictionary by name. Each Feature is guaranteed to have a 'name' key |
8 keys: | 8 holding the name of the feature. |
9 name - a string, the name of the feature | |
10 platform - a list containing 'app' or 'extension', both, or neither. | |
11 | 9 |
12 A Feature may have other keys from a _features.json file as well. Features with | 10 A Feature may have other keys from a _features.json file as well. Features with |
13 a whitelist are ignored as they are only useful to specific apps or extensions. | 11 a whitelist are ignored as they are only useful to specific apps or extensions. |
14 ''' | 12 ''' |
15 | 13 |
16 from copy import deepcopy | 14 from copy import deepcopy |
17 | 15 |
18 def Parse(features_json): | 16 def Parse(features_json): |
19 '''Process JSON from a _features.json file, standardizing it into a dictionary | 17 '''Process JSON from a _features.json file, standardizing it into a dictionary |
20 of Features. | 18 of Features. |
21 ''' | 19 ''' |
22 features = {} | 20 features = {} |
23 | 21 |
24 for name, value in deepcopy(features_json).iteritems(): | 22 for name, value in deepcopy(features_json).iteritems(): |
25 # Some feature names corrispond to a list; force a list down to a single | 23 # Some feature names correspond to a list; force a list down to a single |
26 # feature by removing entries that have a 'whitelist'. | 24 # feature by removing entries that have a 'whitelist'. |
27 if isinstance(value, list): | 25 if isinstance(value, list): |
28 values = [subvalue for subvalue in value if not 'whitelist' in subvalue] | 26 values = [subvalue for subvalue in value if not 'whitelist' in subvalue] |
29 if values: | 27 if values: |
30 value = values[0] | 28 value = values[0] |
31 else: | 29 else: |
32 continue | 30 continue |
33 | 31 |
34 if 'whitelist' in value: | 32 if 'whitelist' in value: |
35 continue | 33 continue |
36 | 34 |
37 features[name] = { 'platforms': [] } | 35 features[name] = {} |
38 | |
39 platforms = value.pop('extension_types') | |
40 if platforms == 'all' or 'platform_app' in platforms: | |
41 features[name]['platforms'].append('app') | |
42 if platforms == 'all' or 'extension' in platforms: | |
43 features[name]['platforms'].append('extension') | |
44 | |
45 features[name]['name'] = name | 36 features[name]['name'] = name |
46 features[name].update(value) | 37 features[name].update(value) |
47 | 38 |
48 return features | 39 return features |
49 | 40 |
50 def Filtered(features, platform=None): | 41 def GetPlatformSetForExtensionTypes(extension_types): |
51 '''Create a new Features dictionary from |features| that contains only items | 42 platforms = set() |
52 relevant to |platform|. Items retained are deepcopied. Returns new features | 43 if extension_types == 'all' or 'platform_app' in extension_types: |
53 dictionary. | 44 platforms.add('apps') |
54 ''' | 45 if extension_types == 'all' or 'extension' in extension_types: |
55 filtered_features = {} | 46 platforms.add('extensions') |
56 | 47 return platforms |
57 for name, feature in features.iteritems(): | |
58 if not platform or platform in feature['platforms']: | |
59 filtered_features[name] = deepcopy(feature) | |
60 | |
61 return filtered_features | |
62 | 48 |
63 def MergedWith(features, other): | 49 def MergedWith(features, other): |
64 '''Merge |features| with an additional dictionary to create a new features | 50 '''Merge |features| with an additional dictionary to create a new features |
65 dictionary. If a feature is common to both |features| and |other|, then it is | 51 dictionary. If a feature is common to both |features| and |other|, then it is |
66 merged using the standard dictionary update instead of being overwritten. | 52 merged using the standard dictionary update instead of being overwritten. |
67 Returns the new Features dictionary. | 53 Returns the new Features dictionary. |
68 ''' | 54 ''' |
69 for key, value in other.iteritems(): | 55 for key, value in other.iteritems(): |
70 if key in features: | 56 if key in features: |
71 features[key].update(value) | 57 features[key].update(value) |
72 else: | 58 else: |
73 features[key] = value | 59 features[key] = value |
74 | 60 |
75 # Ensure the Feature schema is enforced for all added items. | 61 # Ensure the Feature schema is enforced for all added items. |
76 if not 'name' in features[key]: | 62 if not 'name' in features[key]: |
77 features[key]['name'] = key | 63 features[key]['name'] = key |
78 if not 'platforms' in features[key]: | |
79 features[key]['platforms'] = [] | |
80 | 64 |
81 return features | 65 return features |
OLD | NEW |