Chromium Code Reviews| 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 |