blob: 0d417e256ea5f5ac7f755a77f0a5c54194c02fa2 [file] [log] [blame] [edit]
# Copyright 2024 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 commit pins stored in plain text files.
This module provides the `TxtRollApi` for scenarios where a dependency's
commit hash is stored directly as the sole content of a text file.
This is a simpler form of version pinning compared to variable assignments
or structured manifest files.
The API handles:
- Reading the current commit hash from the specified text file.
- Resolving the latest commit hash from a remote Git repository and branch.
- Comparing the current and new hashes.
- Overwriting the text file with the new hash if it represents a forward roll.
- Generating `Roll` objects for standardized commit messages.
"""
from __future__ import annotations
from recipe_engine import recipe_api
from PB.recipe_modules.pigweed.txt_roll.txt_entry import TxtEntry
from RECIPE_MODULES.fuchsia.git_roll_util import api as git_roll_util_api
from RECIPE_MODULES.pigweed.checkout import api as checkout_api
class TxtRollApi(recipe_api.RecipeApi):
"""API for updating commit pins stored in plain text files.
This module handles scenarios where a dependency's commit hash is stored
directly in a text file (e.g., a file containing just the commit hash).
It can update this hash to the latest commit from a specified remote
repository and branch.
"""
def update(
self,
checkout: checkout_api.CheckoutContext,
txt_entry: TxtEntry,
) -> list[git_roll_util_api.Roll]:
"""Updates a commit hash in a text file to the latest from a remote.
This function reads a text file expected to contain a commit hash.
It resolves the latest revision from the specified remote and branch.
If the new revision is different and represents a forward roll,
it overwrites the text file with the new revision and generates a
`Roll` object for commit message formatting.
Args:
checkout: The checkout context.
txt_entry: A protobuf message defining the text file to update,
including its path, the remote URL to track, the branch,
and an optional name for the roll.
Returns:
A list containing a `Roll` object if the file was updated,
or an empty list if no update was needed (e.g., already
up-to-date or a backwards roll).
"""
with self.m.step.nest(txt_entry.path):
branch = txt_entry.branch or 'main'
new_revision = self.m.git_roll_util.resolve_new_revision(
txt_entry.remote,
branch,
checkout.remotes_equivalent,
)
full_txt_path = checkout.root / txt_entry.path
old_revision = self.m.file.read_text(
'read old revision',
full_txt_path,
test_data='1' * 40,
).strip()
with self.m.step.nest('txt_path') as pres:
pres.step_summary_text = repr(txt_entry.path)
try:
roll = self.m.git_roll_util.get_roll(
repo_url=txt_entry.remote,
repo_short_name=txt_entry.name or txt_entry.path,
old_rev=old_revision,
new_rev=new_revision,
)
except self.m.git_roll_util.BackwardsRollError:
props = self.m.step.empty('output property').presentation
props.properties[txt_entry.path] = {
'remote': txt_entry.remote,
'revision': new_revision,
}
return []
self.m.file.write_text(
'write new revision', full_txt_path, f'{new_revision}\n'
)
return [roll]