OLD | NEW |
---|---|
1 # Copyright 2015 The Chromium Authors. All rights reserved. | 1 # Copyright 2015 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 all things related to manipulating google play services | 6 Utility functions for all things related to manipulating google play services |
7 related files. | 7 related files. |
8 ''' | 8 ''' |
9 | 9 |
10 import argparse | 10 import argparse |
11 import filecmp | 11 import filecmp |
12 import json | |
12 import logging | 13 import logging |
13 import os | 14 import os |
14 import re | 15 import re |
15 import sys | 16 import sys |
16 import yaml | |
17 import zipfile | 17 import zipfile |
18 | 18 |
19 sys.path.append(os.path.join(os.path.dirname(__file__), os.pardir)) | 19 sys.path.append(os.path.join(os.path.dirname(__file__), os.pardir)) |
20 from devil.utils import cmd_helper | 20 from devil.utils import cmd_helper |
21 | 21 |
22 | 22 |
23 _CONFIG_VERSION_NUMBER_KEY = 'version_number' | |
24 _YAML_VERSION_NUMBER_PATTERN = re.compile( | |
25 r'(^\s*%s\s*:\s*)(\d+)(.*$)' % _CONFIG_VERSION_NUMBER_KEY, re.MULTILINE) | |
26 _XML_VERSION_NUMBER_PATTERN = re.compile( | 23 _XML_VERSION_NUMBER_PATTERN = re.compile( |
27 r'<integer name="google_play_services_version">(\d+)<\/integer>') | 24 r'<integer name="google_play_services_version">(\d+)<\/integer>') |
28 | 25 |
29 | 26 |
30 class DefaultsRawHelpFormatter(argparse.ArgumentDefaultsHelpFormatter, | 27 class DefaultsRawHelpFormatter(argparse.ArgumentDefaultsHelpFormatter, |
31 argparse.RawDescriptionHelpFormatter): | 28 argparse.RawDescriptionHelpFormatter): |
32 ''' | 29 ''' |
33 Combines the features of RawDescriptionHelpFormatter and | 30 Combines the features of RawDescriptionHelpFormatter and |
34 ArgumentDefaultsHelpFormatter, providing defaults for the arguments and raw | 31 ArgumentDefaultsHelpFormatter, providing defaults for the arguments and raw |
35 text for the description. | 32 text for the description. |
36 ''' | 33 ''' |
37 pass | 34 pass |
38 | 35 |
39 | 36 |
37 class ConfigParser(object): | |
38 '''Reads and writes the configuration files for play services related scripts | |
39 | |
40 The configuration files are JSON files. Here is the data they are expected | |
41 to contain: | |
42 | |
43 - version_number | |
44 Number. Mirrors @integer/google_play_services_version from the library. | |
45 Example: 815000 | |
46 | |
47 ''' | |
48 _VERSION_NUMBER_KEY = 'version_number' | |
49 | |
50 def __init__(self, path): | |
51 self.path = path | |
52 self.data = {} | |
53 | |
54 with open(path, 'r') as stream: | |
55 self.data = json.load(stream) | |
56 | |
57 @property | |
58 def version_number(self): | |
59 return self.data[self._VERSION_NUMBER_KEY] | |
60 | |
61 def UpdateVersionNumber(self, new_version_number): | |
62 '''Updates the version number and saves it in the configuration file. ''' | |
63 | |
64 with open(self.path, 'r+') as stream: | |
65 # Reload the configuration in case the cached version isn't up to date | |
jbudorick
2015/11/03 02:54:41
nit: This seems unnecessary. How often will the co
dgn
2015/11/03 10:36:31
Should be extremely unlikely, yes. Removed
| |
66 self.data = json.load(stream) | |
67 self.data[self._VERSION_NUMBER_KEY] = new_version_number | |
68 stream.seek(0) | |
69 json.dump(self.data, stream) | |
70 | |
71 | |
40 def FileEquals(expected_file, actual_file): | 72 def FileEquals(expected_file, actual_file): |
41 ''' | 73 ''' |
42 Returns whether the two files are equal. Returns False if any of the files | 74 Returns whether the two files are equal. Returns False if any of the files |
43 doesn't exist. | 75 doesn't exist. |
44 ''' | 76 ''' |
45 | 77 |
46 if not os.path.isfile(actual_file) or not os.path.isfile(expected_file): | 78 if not os.path.isfile(actual_file) or not os.path.isfile(expected_file): |
47 return False | 79 return False |
48 return filecmp.cmp(expected_file, actual_file) | 80 return filecmp.cmp(expected_file, actual_file) |
49 | 81 |
(...skipping 15 matching lines...) Expand all Loading... | |
65 with open(version_xml, 'r') as version_file: | 97 with open(version_xml, 'r') as version_file: |
66 version_file_content = version_file.read() | 98 version_file_content = version_file.read() |
67 | 99 |
68 match = _XML_VERSION_NUMBER_PATTERN.search(version_file_content) | 100 match = _XML_VERSION_NUMBER_PATTERN.search(version_file_content) |
69 if not match: | 101 if not match: |
70 raise AttributeError('A value for google_play_services_version was not ' | 102 raise AttributeError('A value for google_play_services_version was not ' |
71 'found in ' + version_xml) | 103 'found in ' + version_xml) |
72 return int(match.group(1)) | 104 return int(match.group(1)) |
73 | 105 |
74 | 106 |
75 def UpdateVersionNumber(config_file_path, new_version_number): | |
76 '''Updates the version number in the update/preprocess configuration file.''' | |
77 | |
78 with open(config_file_path, 'r+') as stream: | |
79 config_content = stream.read() | |
80 # Implemented as string replacement instead of yaml parsing to preserve | |
81 # whitespace and comments. | |
82 updated = _YAML_VERSION_NUMBER_PATTERN.sub( | |
83 r'\g<1>%s\g<3>' % new_version_number, config_content) | |
84 stream.seek(0) | |
85 stream.write(updated) | |
86 | |
87 | |
88 def GetVersionNumber(config_file_path): | |
89 ''' | |
90 Returns the version number from an update/preprocess configuration file. | |
91 ''' | |
92 | |
93 return int(GetConfig(config_file_path)[_CONFIG_VERSION_NUMBER_KEY]) | |
94 | |
95 | |
96 def GetConfig(path): | |
97 ''' | |
98 Returns the configuration from an an update/preprocess configuration file as | |
99 as dictionary. | |
100 ''' | |
101 | |
102 with open(path, 'r') as stream: | |
103 config = yaml.load(stream) | |
104 return config | |
105 | |
106 | |
107 def MakeLocalCommit(repo_root, files_to_commit, message): | 107 def MakeLocalCommit(repo_root, files_to_commit, message): |
108 '''Makes a local git commit.''' | 108 '''Makes a local git commit.''' |
109 | 109 |
110 logging.debug('Staging files (%s) for commit.', files_to_commit) | 110 logging.debug('Staging files (%s) for commit.', files_to_commit) |
111 if cmd_helper.Call(['git', 'add'] + files_to_commit, cwd=repo_root) != 0: | 111 if cmd_helper.Call(['git', 'add'] + files_to_commit, cwd=repo_root) != 0: |
112 raise Exception('The local commit failed.') | 112 raise Exception('The local commit failed.') |
113 | 113 |
114 logging.debug('Committing.') | 114 logging.debug('Committing.') |
115 if cmd_helper.Call(['git', 'commit', '-m', message], cwd=repo_root) != 0: | 115 if cmd_helper.Call(['git', 'commit', '-m', message], cwd=repo_root) != 0: |
116 raise Exception('The local commit failed.') | 116 raise Exception('The local commit failed.') |
117 | 117 |
118 | 118 |
119 def ZipDir(output, base_dir): | 119 def ZipDir(output, base_dir): |
120 '''Creates a zip file from a directory.''' | 120 '''Creates a zip file from a directory.''' |
121 | 121 |
122 base = os.path.join(base_dir, os.pardir) | 122 base = os.path.join(base_dir, os.pardir) |
123 with zipfile.ZipFile(output, 'w') as out_file: | 123 with zipfile.ZipFile(output, 'w') as out_file: |
124 for root, _, files in os.walk(base_dir): | 124 for root, _, files in os.walk(base_dir): |
125 for in_file in files: | 125 for in_file in files: |
126 out_file.write(os.path.join(root, in_file), base) | 126 out_file.write(os.path.join(root, in_file), base) |
OLD | NEW |