| # Copyright (C) 2010 Chris Jerdonek ([email protected]) |
| # |
| # Redistribution and use in source and binary forms, with or without |
| # modification, are permitted provided that the following conditions |
| # are met: |
| # 1. Redistributions of source code must retain the above copyright |
| # notice, this list of conditions and the following disclaimer. |
| # 2. Redistributions in binary form must reproduce the above copyright |
| # notice, this list of conditions and the following disclaimer in the |
| # documentation and/or other materials provided with the distribution. |
| # |
| # THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND |
| # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| # DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR |
| # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
| # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
| # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
| # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
| # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| |
| """Supports Python version checking.""" |
| |
| import logging |
| import sys |
| |
| _log = logging.getLogger("webkitpy.python24.versioning") |
| |
| # The minimum Python version the webkitpy package supports. |
| _MINIMUM_SUPPORTED_PYTHON_VERSION = "2.5" |
| |
| |
| def compare_version(sysmodule=None, target_version=None): |
| """Compare the current Python version with a target version. |
| |
| Args: |
| sysmodule: An object with version and version_info data attributes |
| used to detect the current Python version. The attributes |
| should have the same semantics as sys.version and |
| sys.version_info. This parameter should only be used |
| for unit testing. Defaults to sys. |
| target_version: A string representing the Python version to compare |
| the current version against. The string should have |
| one of the following three forms: 2, 2.5, or 2.5.3. |
| Defaults to the minimum version that the webkitpy |
| package supports. |
| |
| Returns: |
| A triple of (comparison, current_version, target_version). |
| |
| comparison: An integer representing the result of comparing the |
| current version with the target version. A positive |
| number means the current version is greater than the |
| target, 0 means they are the same, and a negative number |
| means the current version is less than the target. |
| This method compares version information only up |
| to the precision of the given target version. For |
| example, if the target version is 2.6 and the current |
| version is 2.5.3, this method uses 2.5 for the purposes |
| of comparing with the target. |
| current_version: A string representing the current Python version, for |
| example 2.5.3. |
| target_version: A string representing the version that the current |
| version was compared against, for example 2.5. |
| |
| """ |
| if sysmodule is None: |
| sysmodule = sys |
| if target_version is None: |
| target_version = _MINIMUM_SUPPORTED_PYTHON_VERSION |
| |
| # The number of version parts to compare. |
| precision = len(target_version.split(".")) |
| |
| # We use sys.version_info rather than sys.version since its first |
| # three elements are guaranteed to be integers. |
| current_version_info_to_compare = sysmodule.version_info[:precision] |
| # Convert integers to strings. |
| current_version_info_to_compare = map(str, current_version_info_to_compare) |
| current_version_to_compare = ".".join(current_version_info_to_compare) |
| |
| # Compare version strings lexicographically. |
| if current_version_to_compare > target_version: |
| comparison = 1 |
| elif current_version_to_compare == target_version: |
| comparison = 0 |
| else: |
| comparison = -1 |
| |
| # The version number portion of the current version string, for |
| # example "2.6.4". |
| current_version = sysmodule.version.split()[0] |
| |
| return (comparison, current_version, target_version) |
| |
| |
| # FIXME: Add a logging level parameter to allow the version message |
| # to be logged at levels other than WARNING, for example CRITICAL. |
| def check_version(log=None, sysmodule=None, target_version=None): |
| """Check the current Python version against a target version. |
| |
| Logs a warning message if the current version is less than the |
| target version. |
| |
| Args: |
| log: A logging.logger instance to use when logging the version warning. |
| Defaults to the logger of this module. |
| sysmodule: See the compare_version() docstring. |
| target_version: See the compare_version() docstring. |
| |
| Returns: |
| A boolean value of whether the current version is greater than |
| or equal to the target version. |
| |
| """ |
| if log is None: |
| log = _log |
| |
| (comparison, current_version, target_version) = \ |
| compare_version(sysmodule, target_version) |
| |
| if comparison >= 0: |
| # Then the current version is at least the minimum version. |
| return True |
| |
| message = ("WebKit Python scripts do not support your current Python " |
| "version (%s). The minimum supported version is %s.\n" |
| " See the following page to upgrade your Python version:\n\n" |
| " http://trac.webkit.org/wiki/PythonGuidelines\n" |
| % (current_version, target_version)) |
| log.warn(message) |
| return False |