| 
 | 1 | +# check_version below cannot be called from anywhere  | 
 | 2 | +# because native.bazel_version's availability is restricted:  | 
 | 3 | +#   https://github.com/bazelbuild/bazel/issues/8305  | 
 | 4 | +# An alternative hacky way is as follows:  | 
 | 5 | +#   https://github.com/protocolbuffers/upb/blob/master/bazel/repository_defs.bzl  | 
 | 6 | +#  | 
 | 7 | +# There are utility functions for parsing versions numbers here:  | 
 | 8 | +#   load("@bazel_skylib//lib:versions.bzl", "versions")  | 
 | 9 | +# But we don't want to use them, as skylib is not yet loaded when code  | 
 | 10 | +# in this file executes (and there's no way to execute it later; see first  | 
 | 11 | +# paragraph above).  | 
 | 12 | + | 
 | 13 | +def _parse_version_chunk(version_chunk):  | 
 | 14 | +    """  | 
 | 15 | +    Args:  | 
 | 16 | +      version_chunk: a chunk of a semantic version, possibly with trailing  | 
 | 17 | +                     content at the end; such as "29", "2", or "3 foobar".  | 
 | 18 | +                     We handle trailing content because  | 
 | 19 | +                     native.bazel_version can: try printing actual_version  | 
 | 20 | +                     in check_version below (got for example  | 
 | 21 | +                     "2.0.0- (@non-git)").  | 
 | 22 | +    Returns:  | 
 | 23 | +      The chunk string with trailing content removed, such as "29", "2", or "3"  | 
 | 24 | +    """  | 
 | 25 | +    for i in range(len(version_chunk)):  | 
 | 26 | +        c = version_chunk[i]  | 
 | 27 | +        if not c.isdigit():  | 
 | 28 | +            return version_chunk[:i]  | 
 | 29 | +    return version_chunk  | 
 | 30 | + | 
 | 31 | +def _parse_bazel_version(bazel_version):  | 
 | 32 | +    """  | 
 | 33 | +    Args:  | 
 | 34 | +      bazel_version: a string that starts with a semantic version  | 
 | 35 | +                     like "2.0" or "0.29.1" or "0.29 foobar"  | 
 | 36 | +    Returns:  | 
 | 37 | +      The version as a int list such as [2, 0], [0, 29, 1], or [0, 29]  | 
 | 38 | +    """  | 
 | 39 | +    return [int(_parse_version_chunk(x)) for x in bazel_version.split(".")]  | 
 | 40 | + | 
 | 41 | +def check_version(actual_version):  | 
 | 42 | +    if type(actual_version) != "string" or len(actual_version) < 5:  | 
 | 43 | +        return  # Unexpected format  | 
 | 44 | + | 
 | 45 | +    # Please use length 3 tuples, because bazel versions has 3 members;  | 
 | 46 | +    # to avoid surprising behaviors (for example (2,0) >/= (2, 0, 0))  | 
 | 47 | +    min_bazel = (0, 29, 0)  # Change THIS LINE when changing bazel min version  | 
 | 48 | +    max_bazel = (2, 0, 0)  # Change THIS LINE when changing bazel max version  | 
 | 49 | + | 
 | 50 | +    actual = tuple(_parse_bazel_version(actual_version))  | 
 | 51 | + | 
 | 52 | +    if (min_bazel <= actual) and (actual <= max_bazel):  | 
 | 53 | +        return  # All good  | 
 | 54 | + | 
 | 55 | +    min_bazel_string = ".".join([str(x) for x in min_bazel])  | 
 | 56 | +    max_bazel_string = ".".join([str(x) for x in max_bazel])  | 
 | 57 | + | 
 | 58 | +    adjective = "old" if actual < min_bazel else "recent"  | 
 | 59 | + | 
 | 60 | +    print("WARNING: bazel version is too {}. Supported versions range from {} to {}, but found: {}".format(adjective, min_bazel_string, max_bazel_string, actual_version))  | 
0 commit comments