OLD | NEW |
1 # -*- coding: utf-8 -*- | 1 # -*- coding: utf-8 -*- |
2 """Helper to check for availability and version of dependencies.""" | 2 """Helper to check for availability and version of dependencies.""" |
3 | 3 |
4 from __future__ import print_function | 4 from __future__ import print_function |
5 from __future__ import unicode_literals | 5 from __future__ import unicode_literals |
6 | 6 |
7 import re | 7 import re |
8 | 8 |
9 try: | 9 try: |
10 import ConfigParser as configparser | 10 import ConfigParser as configparser |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
81 def Read(self, file_object): | 81 def Read(self, file_object): |
82 """Reads dependency definitions. | 82 """Reads dependency definitions. |
83 | 83 |
84 Args: | 84 Args: |
85 file_object (file): file-like object to read from. | 85 file_object (file): file-like object to read from. |
86 | 86 |
87 Yields: | 87 Yields: |
88 DependencyDefinition: dependency definition. | 88 DependencyDefinition: dependency definition. |
89 """ | 89 """ |
90 config_parser = configparser.RawConfigParser() | 90 config_parser = configparser.RawConfigParser() |
| 91 # pylint: disable=deprecated-method |
| 92 # TODO: replace readfp by read_file, check if Python 2 compatible |
91 config_parser.readfp(file_object) | 93 config_parser.readfp(file_object) |
92 | 94 |
93 for section_name in config_parser.sections(): | 95 for section_name in config_parser.sections(): |
94 dependency_definition = DependencyDefinition(section_name) | 96 dependency_definition = DependencyDefinition(section_name) |
95 for value_name in self._VALUE_NAMES: | 97 for value_name in self._VALUE_NAMES: |
96 value = self._GetConfigValue(config_parser, section_name, value_name) | 98 value = self._GetConfigValue(config_parser, section_name, value_name) |
97 setattr(dependency_definition, value_name, value) | 99 setattr(dependency_definition, value_name, value) |
98 | 100 |
99 yield dependency_definition | 101 yield dependency_definition |
100 | 102 |
101 | 103 |
102 class DependencyHelper(object): | 104 class DependencyHelper(object): |
103 """Dependency helper.""" | 105 """Dependency helper.""" |
104 | 106 |
| 107 _VERSION_NUMBERS_REGEX = re.compile(r'[0-9.]+') |
105 _VERSION_SPLIT_REGEX = re.compile(r'\.|\-') | 108 _VERSION_SPLIT_REGEX = re.compile(r'\.|\-') |
106 | 109 |
107 def __init__(self): | 110 def __init__(self, configuration_file='dependencies.ini'): |
108 """Initializes a dependency helper.""" | 111 """Initializes a dependency helper. |
| 112 |
| 113 Args: |
| 114 configuration_file (Optional[str]): path to the dependencies |
| 115 configuration file. |
| 116 """ |
109 super(DependencyHelper, self).__init__() | 117 super(DependencyHelper, self).__init__() |
110 self._dependencies = {} | 118 self._dependencies = {} |
111 self._test_dependencies = {} | 119 self._test_dependencies = {} |
112 | 120 |
113 dependency_reader = DependencyDefinitionReader() | 121 dependency_reader = DependencyDefinitionReader() |
114 | 122 |
115 with open('dependencies.ini', 'r') as file_object: | 123 with open(configuration_file, 'r') as file_object: |
116 for dependency in dependency_reader.Read(file_object): | 124 for dependency in dependency_reader.Read(file_object): |
117 self._dependencies[dependency.name] = dependency | 125 self._dependencies[dependency.name] = dependency |
118 | 126 |
119 dependency = DependencyDefinition('mock') | 127 dependency = DependencyDefinition('mock') |
120 dependency.minimum_version = '0.7.1' | 128 dependency.minimum_version = '0.7.1' |
121 dependency.version_property = '__version__' | 129 dependency.version_property = '__version__' |
122 self._test_dependencies['mock'] = dependency | 130 self._test_dependencies['mock'] = dependency |
123 | 131 |
124 def _CheckPythonModule(self, dependency): | 132 def _CheckPythonModule(self, dependency): |
125 """Checks the availability of a Python module. | 133 """Checks the availability of a Python module. |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
178 status_message = ( | 186 status_message = ( |
179 'unable to determine version information for: {0:s}').format( | 187 'unable to determine version information for: {0:s}').format( |
180 module_name) | 188 module_name) |
181 return False, status_message | 189 return False, status_message |
182 | 190 |
183 # Make sure the module version is a string. | 191 # Make sure the module version is a string. |
184 module_version = '{0!s}'.format(module_version) | 192 module_version = '{0!s}'.format(module_version) |
185 | 193 |
186 # Split the version string and convert every digit into an integer. | 194 # Split the version string and convert every digit into an integer. |
187 # A string compare of both version strings will yield an incorrect result. | 195 # A string compare of both version strings will yield an incorrect result. |
188 module_version_map = list( | 196 |
189 map(int, self._VERSION_SPLIT_REGEX.split(module_version))) | 197 # Strip any semantic suffixes such as a1, b1, pre, post, rc, dev. |
190 minimum_version_map = list( | 198 module_version = self._VERSION_NUMBERS_REGEX.findall(module_version)[0] |
191 map(int, self._VERSION_SPLIT_REGEX.split(minimum_version))) | 199 |
| 200 if module_version[-1] == '.': |
| 201 module_version = module_version[:-1] |
| 202 |
| 203 try: |
| 204 module_version_map = list( |
| 205 map(int, self._VERSION_SPLIT_REGEX.split(module_version))) |
| 206 except ValueError: |
| 207 status_message = 'unable to parse module version: {0:s} {1:s}'.format( |
| 208 module_name, module_version) |
| 209 return False, status_message |
| 210 |
| 211 try: |
| 212 minimum_version_map = list( |
| 213 map(int, self._VERSION_SPLIT_REGEX.split(minimum_version))) |
| 214 except ValueError: |
| 215 status_message = 'unable to parse minimum version: {0:s} {1:s}'.format( |
| 216 module_name, minimum_version) |
| 217 return False, status_message |
192 | 218 |
193 if module_version_map < minimum_version_map: | 219 if module_version_map < minimum_version_map: |
194 status_message = ( | 220 status_message = ( |
195 '{0:s} version: {1!s} is too old, {2!s} or later required').format( | 221 '{0:s} version: {1!s} is too old, {2!s} or later required').format( |
196 module_name, module_version, minimum_version) | 222 module_name, module_version, minimum_version) |
197 return False, status_message | 223 return False, status_message |
198 | 224 |
199 if maximum_version: | 225 if maximum_version: |
200 maximum_version_map = list( | 226 try: |
201 map(int, self._VERSION_SPLIT_REGEX.split(maximum_version))) | 227 maximum_version_map = list( |
| 228 map(int, self._VERSION_SPLIT_REGEX.split(maximum_version))) |
| 229 except ValueError: |
| 230 status_message = 'unable to parse maximum version: {0:s} {1:s}'.format( |
| 231 module_name, maximum_version) |
| 232 return False, status_message |
| 233 |
202 if module_version_map > maximum_version_map: | 234 if module_version_map > maximum_version_map: |
203 status_message = ( | 235 status_message = ( |
204 '{0:s} version: {1!s} is too recent, {2!s} or earlier ' | 236 '{0:s} version: {1!s} is too recent, {2!s} or earlier ' |
205 'required').format(module_name, module_version, maximum_version) | 237 'required').format(module_name, module_version, maximum_version) |
206 return False, status_message | 238 return False, status_message |
207 | 239 |
208 status_message = '{0:s} version: {1!s}'.format(module_name, module_version) | 240 status_message = '{0:s} version: {1!s}'.format(module_name, module_version) |
209 return True, status_message | 241 return True, status_message |
210 | 242 |
211 def _CheckSQLite3(self): | 243 def _CheckSQLite3(self): |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
333 check_result = False | 365 check_result = False |
334 | 366 |
335 self._PrintCheckDependencyStatus( | 367 self._PrintCheckDependencyStatus( |
336 dependency, result, status_message, verbose_output=verbose_output) | 368 dependency, result, status_message, verbose_output=verbose_output) |
337 | 369 |
338 if check_result and not verbose_output: | 370 if check_result and not verbose_output: |
339 print('[OK]') | 371 print('[OK]') |
340 | 372 |
341 print('') | 373 print('') |
342 return check_result | 374 return check_result |
OLD | NEW |