bazel-skylib
bazel-skylib copied to clipboard
Support minimum supported bazel version check from bazelisk's .bazelversion
Gerrit Code Review project is optionally supporting Bazelisk, by providing .bazelversion
file. In the same time, we are checking the minimum supported Bazel version in WORKSPACE
file by using bazel_skylib's versions.check()
function (in case the build is invoked with Bazel and not with Bazelisk command), e.g.:
http_archive(
name = "bazel_skylib",
sha256 = "2ea8a5ed2b448baf4a6855d3ce049c4c452a6470b1efd1504fdb7c1c134d220a",
strip_prefix = "bazel-skylib-0.8.0",
urls = ["https://github.com/bazelbuild/bazel-skylib/archive/0.8.0.tar.gz"],
)
load("@bazel_skylib//lib:versions.bzl", "versions")
versions.check(minimum_bazel_version = "0.29.0")
However, this is disadvantageously, to maintain Bazel versions in two different places, and upgrade them in two places, when Bazel version is bumped, like it was done in this CL: [1]:
-
.bazelversion
-
WORKSPACE
What we need is a supported built-in way to check minimum supported Bazel version check from .bazelversion
, e.g.:
bazel_version_check_from_bazelversion_file()
with the outcome, that the Build would break, if Bazel version is less than 0.29.
Bonus point, would be to not invoke anything, but just add a line in .bazelrc
file, e.g.:
build --bazel_version_check_from_bazelversion_file
Even a bigger bonus point, when this check performed automatically, without saying anything (neither in WORKSPACE
nor in .bazelrc
files). So, if there is .bazelversion
file with content 1.0.0
, and I am invoking the build with bazel
version 0.0.1, then the build should just fail.
[1] https://gerrit-review.googlesource.com/c/gerrit/+/232533
Do you really need the version check? If you use Bazelisk and Bazelisk uses the .bazelversion
, you should be fine.
Bazel doesn't know about .bazelversion
.
I think you can get the version from .bazelversion
with a custom repository rule.
WORKSPACE
:
http_archive(
name = "bazel_skylib",
sha256 = "2ea8a5ed2b448baf4a6855d3ce049c4c452a6470b1efd1504fdb7c1c134d220a",
strip_prefix = "bazel-skylib-0.8.0",
urls = ["https://github.com/bazelbuild/bazel-skylib/archive/0.8.0.tar.gz"],
)
load("//:bazelisk_version.bzl", "bazelisk_version")
bazelisk_version(name = "bazelisk_version",)
load("@bazelisk_version//:check.bzl", "check_bazelisk_version")
check_bazelisk_version()
bazelisk_version.bzl
:
_template = """
load("@bazel_skylib//lib:versions.bzl", "versions")
def check_bazelisk_version():
versions.check(minimum_bazel_version = "{version}")
""".strip()
def _impl(repository_ctx):
repository_ctx.symlink(Label('@//:.bazelversion'), '.bazelversion')
bazelversion = repository_ctx.read('.bazelversion').strip()
repository_ctx.file('BUILD', executable=False)
repository_ctx.file('check.bzl', executable=False, content=_template.format(version=bazelversion))
bazelisk_version = repository_rule(implementation=_impl)
Thanks @Yannic. Would it be an option to implement that check in bazel_skylib
, as this use case may be interesting for other projects as well.
@laurentlb Not all users and developers of Gerrit switched to using Bazelisk, and still using Bazel directly, so that yes, unfortunately we still need that check in WORKSPACE file.
@Yannic Thank you for your rule! Could you please explain what is the purpose of repository_ctx.symlink(Label('@//:.bazelversion'), '.bazelversion')
statement?
FTR: Starting from Bazel release 2.0.0 bazel shell script was extended to perform the version check. FWIW, Gerrit project removed the version check entirely.
AFAIU Bazel shell script does not work on Windows and we want to have version check on all three supported platforms.
@philwo Is there any plans to backport Shellzelisk from 2a8cc7075f741721563efd9dc050ca3458cde30b to Windows? If not, would it make sense to include Yannic's version check to check against .bazelversion
in some common place, like bazel_skylib
or bazel
itself?
@davido No plans for a wrapper script for Windows that I know of. Considering that there are various ways of installing Bazel and not all of them include the wrapper script, I would recommend to implement a version check in bazel_skylib or bazel. This sounds like a good idea to me.
The wrapper or Bazelisk would help people to automatically run a compatible Bazel version. The Starlark-based version check would then act as a second layer of defense and catch all users (even for people who directly run the Bazel binary without any wrappers).
@laurentlb Could we add Yannic's check in a skylib, WDYT?
Maybe. This can be decided on skylib repository (PR or issue).
@Yannic Can you upload your rule (or extend the existing check_version
rule) to check against the content of .bazelversion
to skylib
repository?
Maybe. This can be decided on skylib repository (PR or issue).
@laurentlb Can you move this issue to skylib
repository? It seems, that I can not do it.
I'll move it over.
Thank you for doing it, guys!
Thanks @philwo !
Still could somebody please explain the purpose of this line repository_ctx.symlink(Label('@//:.bazelversion'), '.bazelversion')
in the rule implementation by @Yannic ? Can't repository_ctx.read() on the next line be used on the file name directly?
@konste I wrote this a long time ago and didn't exactly try very hard to find a clean solution.
This line creates a symlink from @//:.bazelversion
to @bazelisk_version//:.bazelversion
.
I think I had some trouble reading the original file and this was the easiest workaround, but as I said, my memory might be off, and I'm sure there's a nicer solution than that snipped above ;).
No matter what solution, this maybe a a good feature for the users. One scenario is if we want everyone use the bazel for the LTS version, such as > 4.0.0.