xref: /aosp_15_r20/external/bazelbuild-rules_go/go/private/skylib/lib/versions.bzl (revision 9bb1b549b6a84214c53be0924760be030e66b93a)
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    Args:
48      bazel_version: the Bazel version string
49
50    Returns:
51      An int 3-tuple of a (major, minor, patch) version.
52    """
53
54    version = _extract_version_number(bazel_version)
55    return tuple([int(n) for n in version.split(".")])
56
57def _is_at_most(threshold, version):
58    """Check that a version is lower or equals to a threshold.
59
60    Args:
61      threshold: the maximum version string
62      version: the version string to be compared to the threshold
63
64    Returns:
65      True if version <= threshold.
66    """
67    return _parse_bazel_version(version) <= _parse_bazel_version(threshold)
68
69def _is_at_least(threshold, version):
70    """Check that a version is higher or equals to a threshold.
71
72    Args:
73      threshold: the minimum version string
74      version: the version string to be compared to the threshold
75
76    Returns:
77      True if version >= threshold.
78    """
79
80    return _parse_bazel_version(version) >= _parse_bazel_version(threshold)
81
82def _check_bazel_version(minimum_bazel_version, maximum_bazel_version = None, bazel_version = None):
83    """Check that the version of Bazel is valid within the specified range.
84
85    Args:
86      minimum_bazel_version: minimum version of Bazel expected
87      maximum_bazel_version: maximum version of Bazel expected
88      bazel_version: the version of Bazel to check. Used for testing, defaults to native.bazel_version
89    """
90    if not bazel_version:
91        if "bazel_version" not in dir(native):
92            fail("\nCurrent Bazel version is lower than 0.2.1, expected at least %s\n" % minimum_bazel_version)
93        elif not native.bazel_version:
94            print("\nCurrent Bazel is not a release version, cannot check for compatibility.")
95            print("Make sure that you are running at least Bazel %s.\n" % minimum_bazel_version)
96            return
97        else:
98            bazel_version = native.bazel_version
99
100    if not _is_at_least(
101        threshold = minimum_bazel_version,
102        version = bazel_version,
103    ):
104        fail("\nCurrent Bazel version is {}, expected at least {}\n".format(
105            bazel_version,
106            minimum_bazel_version,
107        ))
108
109    if maximum_bazel_version:
110        if not _is_at_most(
111            threshold = maximum_bazel_version,
112            version = bazel_version,
113        ):
114            fail("\nCurrent Bazel version is {}, expected at most {}\n".format(
115                bazel_version,
116                maximum_bazel_version,
117            ))
118
119    pass
120
121versions = struct(
122    get = _get_bazel_version,
123    parse = _parse_bazel_version,
124    check = _check_bazel_version,
125    is_at_most = _is_at_most,
126    is_at_least = _is_at_least,
127)
128