blob: de435158411d17517a6b0bddbcb2c602fb83563d [file]
# Copyright 2026 The Pigweed Authors
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy of
# the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.
"""Common Bazel utilities for conversion scripts."""
from pathlib import Path
import subprocess
def find_workspace_root(start_path: Path) -> Path:
"""Finds the Bazel workspace root by looking for WORKSPACE or MODULE.bazel."""
curr = start_path.resolve()
while curr != curr.parent:
if (
(curr / "WORKSPACE").exists()
or (curr / "MODULE.bazel").exists()
or (curr / ".git").exists()
):
return curr
curr = curr.parent
# Fallback to CWD
return Path.cwd().resolve()
def get_bazel_package_prefix(output_dir: Path) -> str:
"""Determines the Bazel package prefix for the output directory.
Returns something like '//third_party/zephyr' or '//'.
"""
workspace_root = find_workspace_root(output_dir)
abs_output_dir = output_dir.resolve()
try:
rel_path = abs_output_dir.relative_to(workspace_root)
if str(rel_path) == ".":
return "//"
return f"//{rel_path}"
except ValueError:
print(
f"Warning: Output directory {abs_output_dir} is not under workspace root {workspace_root}."
)
return ""
def expose_files(build_file: Path, files: list[str], comment: str = ""):
"""Appends exports_files to a BUILD.bazel file."""
if not build_file.exists():
print(f"Warning: {build_file} not found, skipping.")
return
content = "\n"
if comment:
content += f"# {comment}\n"
files_str = ", ".join(f'"{f}"' for f in files)
content += f'exports_files([{files_str}], visibility = ["//visibility:public"])\n'
with open(build_file, "a", encoding="utf-8") as f:
f.write(content)
print(f"Exposed {files} in {build_file}")
def run_buildozer(instructions: list[str], target: str) -> bool:
"""Runs buildozer with the given instructions on the target."""
cmd = ["buildozer"] + instructions + [target]
try:
result = subprocess.run(
cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True
)
if result.returncode not in (0, 3):
print(f"Error running buildozer: {result.stderr.strip()}")
print(f"Command was: {' '.join(cmd)}")
return False
elif result.returncode == 0:
print(f"Buildozer: Applied changes to {target}")
elif result.returncode == 3:
print(f"Buildozer: No changes needed for {target}")
return True
except FileNotFoundError:
print(
"Error: 'buildozer' command not found. Please install buildozer to apply all fixups."
)
print(f"Failed to apply to {target}: {instructions}")
return False