diff options
author | Yifan Hong <elsk@google.com> | 2024-03-05 12:43:57 -0800 |
---|---|---|
committer | Yifan Hong <elsk@google.com> | 2024-03-14 18:28:22 +0000 |
commit | 01bb9ba9ccb96b0e4b4a307b65afec96b43b8bf6 (patch) | |
tree | fc69af51cdfb62ffe4401647c08365b398219895 | |
parent | 731e74a8ac1142bac1c99f446bd6617e702a775b (diff) | |
download | build-01bb9ba9ccb96b0e4b4a307b65afec96b43b8bf6.tar.gz |
kleaf: Don't write to $HOME to determine workspace root.
If --output_root or --output_user_root is set,
do not write to $HOME by not running bazel info workspace.
Instead, detect the existance of WORKSPACE.bazel, WORKSPACE,
MODULE.bazel, or REPO.bazel.
Bug: 328233115
Change-Id: I6000315d50f184f8da7032b929844fab1e2091da
-rwxr-xr-x | kleaf/bazel.py | 39 |
1 files changed, 33 insertions, 6 deletions
diff --git a/kleaf/bazel.py b/kleaf/bazel.py index 2d12b7c..d4ccc73 100755 --- a/kleaf/bazel.py +++ b/kleaf/bazel.py @@ -37,6 +37,7 @@ _QUERY_TARGETS_ARG = 'kind("kernel_build rule", //... except attr("tags", \ _QUERY_ABI_TARGETS_ARG = 'kind("(update_source_file|abi_update) rule", //... except attr("tags", \ "manual", //...) except //.source_date_epoch_dir/... except //out/...)' +_REPO_BOUNDARY_FILES = ("MODULE.bazel", "REPO.bazel", "WORKSPACE.bazel", "WORKSPACE") def _require_absolute_path(p: str | pathlib.Path) -> pathlib.Path: p = pathlib.Path(p) @@ -80,12 +81,7 @@ class BazelWrapper(KleafHelpPrinter): self.bazel_path = self.kleaf_repo_dir / _BAZEL_REL_PATH - # Root of the top level workspace (named "@"), where WORKSPACE - # is located. This is not necessarily - # equal to kleaf_repo_dir, especially when Kleaf tooling is in a subworkspace. - self.workspace_dir = pathlib.Path(subprocess.check_output( - [self.bazel_path, "info", "workspace"], - text=True).strip()) + self.workspace_dir = self._get_workspace_dir() command_idx = None for idx, arg in enumerate(bazel_args): @@ -112,6 +108,37 @@ class BazelWrapper(KleafHelpPrinter): self._parse_command_args() self._rebuild_kleaf_help_args() + @classmethod + def _get_workspace_dir(cls): + """Returns Root of the top level workspace (named "@") + + where WORKSPACE is located. This is not necessarily equal to + kleaf_repo_dir, especially when Kleaf tooling is in a submodule. + """ + + # See Bazel's implementation at: + # https://github.com/bazelbuild/bazel/blob/master/src/main/cpp/workspace_layout.cc + + possible_workspace = pathlib.Path.cwd() + while possible_workspace.parent != possible_workspace: # is not root directory + if cls._is_workspace(possible_workspace): + return possible_workspace + possible_workspace = possible_workspace.parent + + sys.stderr.write(textwrap.dedent("""\ + ERROR: Unable to determine root of repository. See + https://bazel.build/external/overview#repository + """)) + sys.exit(1) + + @staticmethod + def _is_workspace(possible_workspace: pathlib.Path): + for boundary_file in _REPO_BOUNDARY_FILES: + if (possible_workspace / boundary_file).is_file(): + return True + return False + + def add_startup_option_to_parser(self, parser): group = parser.add_argument_group( title="Startup options - Wrapper flags", |