blob: 58ac307a1bf42e93bc2f70b996340655ea2e1574 [file]
# Copyright 2025 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.
"""Recipe module for updating MODULE.bazel.lock files."""
from __future__ import annotations
from collections.abc import Sequence
from typing import TYPE_CHECKING
from recipe_engine import recipe_api
from RECIPE_MODULES.fuchsia.git_roll_util import api as git_roll_util_api
if TYPE_CHECKING: # pragma: no cover
from RECIPE_MODULES.pigweed.checkout import api as checkout_api
from PB.recipe_modules.pigweed.bazel.options import Options as BazelOptions
from PB.recipe_modules.pigweed.module_bazel_lock_roll.module_bazel_lock import (
ModuleBazelLock,
)
from RECIPE_MODULES.fuchsia.roll_commit_message import api as rcm_api
class Roll(rcm_api.BaseRoll):
def __init__(self, name: str, *args, **kwargs):
super().__init__(*args, **kwargs)
self._name = name
def short_name(self) -> str:
return self._name
def message_header(self, force_summary_version: bool = False) -> str:
del force_summary_version # Unused.
return self.short_name()
def message_body(
self,
*,
force_summary_version: bool = False,
escape_tags: Sequence[str] | None = None,
filter_tags: Sequence[str] | None = None,
) -> str:
del force_summary_version # Unused.
del escape_tags # Unused.
del filter_tags # Unused.
return f'Regenerated {self.short_name()}'
def message_footer(self, *, send_comment: bool) -> str: # pragma: no cover
del send_comment # Unused.
return ''
def output_property(self) -> dict[str, str]:
return {'name': self._name}
class ModuleBazelLockRollApi(recipe_api.RecipeApi):
"""Recipe module for updating MODULE.bazel.lock files."""
def update(
self,
checkout: checkout_api.CheckoutContext,
module_bazel_lock: ModuleBazelLock,
) -> list[git_roll_util_api.Roll]:
"""Updates the MODULE.bazel.lock file if it exists.
If a `MODULE.bazel.lock` file is present at the root of the checkout,
this method runs `bazelisk mod deps --lockfile_mode=update` to
regenerate it based on the current `MODULE.bazel` file.
Args:
checkout: The checkout context.
module_bazel_lock: Lockfile update options.
"""
directory = checkout.root
if module_bazel_lock.subdirectory:
directory /= module_bazel_lock.subdirectory
name = 'MODULE.bazel.lock'
lock = directory / name
self.m.path.mock_add_file(lock)
if not self.m.path.isfile(lock):
return [] # pragma: no cover
with self.m.step.nest(name):
runner = self.m.bazel.new_runner(
checkout=checkout,
options=BazelOptions(),
)
with self.m.context(cwd=directory):
bazel = module_bazel_lock.bazel_executable
if not bazel:
bazel = runner.ensure_bazelisk()
bazel_name = self.m.path.basename(bazel)
self.m.step(
f'{bazel_name} mod deps --lockfile_mode=update',
[
bazel,
'mod',
'deps',
'--lockfile_mode=update',
],
)
diff = self.m.git.diff(lock, exit_code=True, ok_ret=(0, 1))
if diff.exc_result.retcode:
return [Roll(name)]
return []