| # Copyright 2021 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. |
| """Utility functions common to multiple recipes that don't fit elsewhere.""" |
| |
| import json |
| import re |
| |
| import attr |
| from google.protobuf import json_format |
| from recipe_engine import recipe_api |
| |
| |
| @attr.s |
| class ChangeWithComments: |
| change = attr.ib() |
| details = attr.ib() |
| commit_message = attr.ib() |
| comments = attr.ib() |
| |
| |
| class UtilApi(recipe_api.RecipeApi): |
| def get_change_with_comments(self): |
| input_ = self.m.buildbucket.build.input |
| change = input_.gerrit_changes[0] |
| change_id = str(change.change) |
| details = self.m.gerrit.change_details( |
| 'change details', |
| change_id=change_id, |
| host=input_.gerrit_changes[0].host, |
| query_params=['ALL_COMMITS', 'ALL_REVISIONS', 'ALL_FILES'], |
| test_data=self.m.json.test_api.output( |
| { |
| 'owner': {'email': 'coder@example.com',}, |
| 'current_revision': 'a' * 40, |
| 'revisions': { |
| 'a' |
| * 40: { |
| 'files': [], |
| 'commit': {'message': '',}, |
| 'description': 'description', |
| } |
| }, |
| 'revert_of': 0, |
| } |
| ), |
| ).json.output |
| |
| current_revision = details['revisions'][details['current_revision']] |
| commit_message = current_revision['commit']['message'] |
| |
| comments = [] |
| |
| for revision in details['revisions'].values(): |
| if revision.get('description'): |
| comments.append(revision['description']) |
| |
| comments_result = self.m.gerrit.list_change_comments( |
| "list change comments", |
| change_id, |
| test_data=self.m.json.test_api.output( |
| {'/PATCHSET_LEVEL': [{'message': ''}],} |
| ), |
| ).json.output |
| |
| for _, comment_data in comments_result.items(): |
| comments.extend(x['message'] for x in comment_data) |
| |
| return ChangeWithComments(change, details, commit_message, comments) |
| |
| def find_matching_comment(self, rx, comments): |
| """Find a comment in comments that matches regex object rx.""" |
| result = None |
| with self.m.step.nest('checking comments'): |
| for i, comment in enumerate(comments): |
| with self.m.step.nest(f'comment ({i})') as pres: |
| pres.step_summary_text = comment |
| match = re.search(rx, comment) |
| if match: |
| pres.step_summary_text = f'MATCH: {comment}' |
| result = match |
| break |
| |
| if result: |
| with self.m.step.nest('found'): |
| pass |
| |
| return result |
| |
| def build_metadata(self): |
| return { |
| 'bb_id': self.m.buildbucket.build.id, |
| 'swarming_id': self.m.swarming.task_id, |
| 'builder': self.m.buildbucket_util.full_builder_name(), |
| 'url': self.m.buildbucket_util.build_url, |
| 'triggers': [ |
| json.loads(json_format.MessageToJson(x)) |
| for x in self.m.scheduler.triggers |
| ], |
| } |