blob: 041392efb66f4e82e1ba582111212d542c640984 [file] [edit]
# 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.
"""Enable roll logic to be in-tree."""
from __future__ import annotations
from collections.abc import Mapping, Sequence
from typing import Any
from recipe_engine import recipe_api
from PB.recipe_modules.pigweed.run_script_roll.run_script_entry import (
RunScriptEntry,
)
from RECIPE_MODULES.fuchsia.roll_commit_message import (
api as roll_commit_message_api,
)
from RECIPE_MODULES.pigweed.checkout import api as checkout_api
class RunScriptRoll(roll_commit_message_api.BaseRoll):
"""Represents a roll created by running an in-tree script."""
def __init__(
self,
name: str,
header: str,
body: str,
properties: Mapping[str, Any],
*args,
**kwargs,
):
"""Initializes a RunScriptRoll instance.
Args:
name: Short name for the roll.
header: Short description of the roll.
body: Details of what changed in the roll.
*args: Additional arguments for the base class.
**kwargs: Additional keyword arguments for the base class.
"""
super().__init__(*args, **kwargs)
self.name = name
self.header = header
self.body = body
self.properties = properties
def short_name(self) -> str:
"""Returns a short name for the roll, typically the destination path."""
return self.name
def message_header(self, force_summary_version: bool = False) -> str:
"""Generates the header for the commit message.
Args:
force_summary_version: If True, a more concise header is generated.
Returns:
The commit message header string.
"""
if force_summary_version:
return self.name
return f'{self.name}: {self.header}'
def message_body(
self,
*,
force_summary_version: bool = False,
escape_tags: Sequence[str] = (),
filter_tags: Sequence[str] = (),
) -> str:
"""Generates the body of the commit message.
Args:
force_summary_version: If True, a more concise body is generated.
escape_tags: A sequence of tags to escape in the message.
filter_tags: A sequence of tags to filter from the message.
Returns:
The commit message body string.
"""
del force_summary_version, escape_tags, filter_tags # Unused.
return self.body
def message_footer(self, *, send_comment: bool) -> str:
"""Generates the footer for the commit message.
Args:
send_comment: If True, indicates a comment should be sent.
Returns:
An empty string, as run script rolls typically don't have footers.
"""
del send_comment # Unused.
return ''
def output_property(self) -> dict[str, str]:
"""Generates a dictionary of properties representing the roll.
Returns:
A dictionary containing details of the roll.
"""
return self.properties
class RunScriptRollApi(recipe_api.RecipeApi):
"""Allows for in-tree roll logic."""
RunScriptRoll = RunScriptRoll
def run(
self,
checkout: checkout_api.CheckoutContext,
run_script_entry: RunScriptEntry,
) -> list[RunScriptRoll]:
"""Runs an in-tree script that modifies the checkout.
Args:
checkout: The checkout context, providing repository information.
run_script_entry: A protobuf message defining the script to run.
Returns:
A list containing a `RunScriptRoll` object if the tree was updated,
or an empty list if no updates were made.
"""
with self.m.step.nest(run_script_entry.script):
script = checkout.root / run_script_entry.script
result = self.m.step(
'run',
[script],
stdout=self.m.json.output(),
step_test_data=lambda: self.m.json.test_api.output_stream(
{
'name': 'foo',
'header': 'changed some files',
'body': 'abc: changed\ndef: changed\nghi: changed\n',
'properties': {'key': 'value'},
}
),
).stdout
if not result:
return []
return [
RunScriptRoll(
name=result['name'],
header=result['header'],
body=result['body'],
properties=result['properties'],
),
]