| # 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] |