blob: 5776c6aec8c30bf61f5794871acb66e057aa52f2 [file] [log] [blame]
# Copyright 2023 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""
Repository rules that perform preflight checks.
"""
def _prominent_fail(message):
"""Similar to fail, but prints a message prominently."""
fail("\n\n" + "*" * 80 + "\n" + message + "\n" + "*" * 80 + "\n\n")
def _misconfiguration_fail(reason):
"""Reports a preflight check failure due to the user's misconfiguration."""
_prominent_fail(
reason +
"\n\nPlease read the following guide to set up your environment " +
"properly:\n" +
"https://chromium.googlesource.com/chromiumos/bazel/+/HEAD/README.md",
)
def _do_basic_preflight_checks(repo_ctx):
# Skip all preflight checks for nested bazel.
if repo_ctx.os.environ.get("IS_NESTED_BAZEL") == "1":
return
# Ensure we're invoked via the wrapper script.
if repo_ctx.os.environ.get("CHROMITE_BAZEL_WRAPPER") != "1":
_misconfiguration_fail("Bazel was run without the proper wrapper.")
# Ensure the execroot is not overlayfs.
result = repo_ctx.execute(["stat", "--format=%T", "--file-system", "."], timeout = 10)
if result.return_code != 0:
_prominent_fail(
"statvfs execroot failed: " + result.stderr + result.stdout,
)
if result.stdout.strip() == "overlayfs":
_misconfiguration_fail("The execroot must not be overlayfs.")
def _basic_preflight_checks_impl(repo_ctx):
"""Performs basic preflight checks."""
_do_basic_preflight_checks(repo_ctx)
# Create an empty repository.
repo_ctx.file("BUILD.bazel", "")
repo_ctx.file("ok.bzl", "ok = True")
basic_preflight_checks = repository_rule(
implementation = _basic_preflight_checks_impl,
attrs = {},
environ = [
"CHROMITE_BAZEL_WRAPPER",
"IS_NESTED_BAZEL",
],
local = True,
doc = """
Performs basic preflight checks to provide friendly diagnostics to users.
This rule should be called at the very beginning of WORKSPACE.bazel.
""",
)
def _do_portage_preflight_checks(repo_ctx):
# Ensure we're inside the CrOS chroot.
if repo_ctx.os.environ.get("ALCHEMY_EXPERIMENTAL_OUTSIDE_CHROOT") != "1":
if not repo_ctx.path("/etc/cros_chroot_version").exists:
_misconfiguration_fail("Bazel was run outside CrOS chroot.")
# Ensure third_party/llvm-project is checked out.
llvm_path = repo_ctx.workspace_root.get_child("third_party/llvm-project")
if not llvm_path.exists:
_misconfiguration_fail(
"third_party/llvm-project is not checked out.\n" +
"Did you run `repo init` with `-g default,bazel`?",
)
def _portage_preflight_checks_impl(repo_ctx):
"""Performs preflight checks before generating @portage."""
_do_portage_preflight_checks(repo_ctx)
# Create an empty repository.
repo_ctx.file("BUILD.bazel", "")
repo_ctx.file("ok.bzl", "ok = True")
portage_preflight_checks = repository_rule(
implementation = _portage_preflight_checks_impl,
attrs = {},
environ = [
"ALCHEMY_EXPERIMENTAL_OUTSIDE_CHROOT",
],
local = True,
doc = """
Performs preflight checks before generating @portage to provide friendly
diagnostics to users.
This rule should be called in the module extension generating @portage.
""",
)
def _symlinks_unavailable_impl(_repo_ctx):
_misconfiguration_fail("Bazel was run without the proper wrapper.")
symlinks_unavailable = repository_rule(
implementation = _symlinks_unavailable_impl,
local = True,
doc = """
Reports a failure because symlinks are missing.
This rule should be called in WORKSPACE (the fallback for WORKSPACE.bazel
that is loaded when symlinks are not properly set up).
""",
)