xref: /aosp_15_r20/external/bazel-skylib/lib/versions.bzl (revision bcb5dc7965af6ee42bf2f21341a2ec00233a8c8a)
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