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