blob: 6c77bcd4322ecd2578f4d8282e6f432ea46b6324 [file] [log] [blame]
# Copyright 2023 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.
"""Bazel-related functions."""
import dataclasses
from typing import Any
from PB.recipe_modules.pigweed.bazel.options import Options
from RECIPE_MODULES.pigweed.checkout import api as checkout_api
from recipe_engine import config_types, recipe_api
# This is copied from bazel.json in Pigweed, but there's no need to keep it
# up-to-date.
_JSON_TEST_DATA: dict[str, Any] = {
"included_files": [],
"packages": [
{
"path": "fuchsia/third_party/bazel/${platform}",
"platforms": ["linux-amd64", "mac-amd64", "windows-amd64"],
"tags": ["version:2@6.3.0.6"],
"version_file": ".versions/bazel.cipd_version",
},
{
"path": "flutter/java/openjdk/${platform}",
"platforms": [
"linux-amd64",
"mac-amd64",
"mac-arm64",
"windows-amd64",
],
"tags": ["version:17"],
},
],
}
@dataclasses.dataclass
class BazelRunner:
api: recipe_api.RecipeApi
checkout_root: config_types.Path
options: Options
_bazel: config_types.Path | None = None
def _ensure_cipd(self) -> config_types.Path:
# read_json in a few lines requires absolute, normalized paths.
json_path: config_types.Path = self.api.path.abspath(
self.checkout_root / self.options.cipd_json_path
)
ensure_file = self.api.cipd.EnsureFile()
for package in self.api.file.read_json(
f'read {self.api.path.basename(json_path)}',
json_path,
test_data=_JSON_TEST_DATA,
)["packages"]:
ensure_file.add_package(package['path'], package['tags'][0])
root = self.api.path.mkdtemp()
self.api.cipd.ensure(root, ensure_file, name='ensure bazel')
return root / 'bazel'
def _ensure_bazelisk(self) -> config_types.Path:
ensure_file = self.api.cipd.EnsureFile()
ensure_file.add_package(
'fuchsia/third_party/bazelisk/${platform}',
self.options.bazelisk_version or 'latest',
)
root = self.api.path.mkdtemp()
self.api.cipd.ensure(root, ensure_file, name='ensure bazelisk')
return root / 'bazelisk'
def ensure(self) -> config_types.Path:
if self._bazel:
return self._bazel
if self.options.cipd_json_path:
self._bazel = self._ensure_cipd()
else:
self._bazel = self._ensure_bazelisk()
self.api.step('bazel version', [self._bazel, 'version'])
return self._bazel
def run(self, **kwargs) -> None:
name: str = ' '.join(['bazel'] + list(self.options.args))
with self.api.context(cwd=self.checkout_root):
if self.options.args:
self.api.step(
name, [self.ensure(), *self.options.args], **kwargs
)
for invocation in self.options.invocations:
assert invocation.args
name: str = ' '.join(['bazel'] + list(invocation.args))
self.api.step(name, [self.ensure(), *invocation.args], **kwargs)
class BazelApi(recipe_api.RecipeApi):
"""Bazel utilities."""
BazelRunner = BazelRunner
def new_runner(
self,
checkout: checkout_api.CheckoutContext,
options: Options,
) -> BazelRunner:
return BazelRunner(self.m, checkout.root, options)