1# Copyright 2018 The Bazel Authors. All rights reserved. 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14 15"""Skylib module containing functions for checking Bazel versions.""" 16 17def _get_bazel_version(): 18 """Returns the current Bazel version""" 19 20 return native.bazel_version 21 22def _extract_version_number(bazel_version): 23 """Extracts the semantic version number from a version string 24 25 Args: 26 bazel_version: the version string that begins with the semantic version 27 e.g. "1.2.3rc1 abc1234" where "abc1234" is a commit hash. 28 29 Returns: 30 The semantic version string, like "1.2.3". 31 """ 32 for i in range(len(bazel_version)): 33 c = bazel_version[i] 34 if not (c.isdigit() or c == "."): 35 return bazel_version[:i] 36 return bazel_version 37 38# Parse the bazel version string from `native.bazel_version`. 39# e.g. 40# "0.10.0rc1 abc123d" => (0, 10, 0) 41# "0.3.0" => (0, 3, 0) 42def _parse_bazel_version(bazel_version): 43 """Parses a version string into a 3-tuple of ints 44 45 int tuples can be compared directly using binary operators (<, >). 46 47 For a development build of Bazel, this returns an unspecified version tuple 48 that compares higher than any released version. 49 50 Args: 51 bazel_version: the Bazel version string 52 53 Returns: 54 An int 3-tuple of a (major, minor, patch) version. 55 """ 56 57 version = _extract_version_number(bazel_version) 58 if not version: 59 return (999999, 999999, 999999) 60 return tuple([int(n) for n in version.split(".")]) 61 62def _is_at_most(threshold, version): 63 """Check that a version is lower or equals to a threshold. 64 65 Args: 66 threshold: the maximum version string 67 version: the version string to be compared to the threshold 68 69 Returns: 70 True if version <= threshold. 71 """ 72 return _parse_bazel_version(version) <= _parse_bazel_version(threshold) 73 74def _is_at_least(threshold, version): 75 """Check that a version is higher or equals to a threshold. 76 77 Args: 78 threshold: the minimum version string 79 version: the version string to be compared to the threshold 80 81 Returns: 82 True if version >= threshold. 83 """ 84 85 return _parse_bazel_version(version) >= _parse_bazel_version(threshold) 86 87def _check_bazel_version(minimum_bazel_version, maximum_bazel_version = None, bazel_version = None): 88 """Check that the version of Bazel is valid within the specified range. 89 90 Args: 91 minimum_bazel_version: minimum version of Bazel expected 92 maximum_bazel_version: maximum version of Bazel expected 93 bazel_version: the version of Bazel to check. Used for testing, defaults to native.bazel_version 94 """ 95 if not bazel_version: 96 if "bazel_version" not in dir(native): 97 fail("Current Bazel version is lower than 0.2.1; expected at least {}".format( 98 minimum_bazel_version, 99 )) 100 elif not native.bazel_version: 101 # Using a non-release version, assume it is good. 102 return 103 else: 104 bazel_version = native.bazel_version 105 106 if not _is_at_least( 107 threshold = minimum_bazel_version, 108 version = bazel_version, 109 ): 110 fail("Current Bazel version is {}; expected at least {}".format( 111 bazel_version, 112 minimum_bazel_version, 113 )) 114 115 if maximum_bazel_version: 116 if not _is_at_most( 117 threshold = maximum_bazel_version, 118 version = bazel_version, 119 ): 120 fail("Current Bazel version is {}; expected at most {}".format( 121 bazel_version, 122 maximum_bazel_version, 123 )) 124 125 pass 126 127versions = struct( 128 get = _get_bazel_version, 129 parse = _parse_bazel_version, 130 check = _check_bazel_version, 131 is_at_most = _is_at_most, 132 is_at_least = _is_at_least, 133) 134