| # Copyright 2017 The Fuchsia Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| from recipe_engine import recipe_api |
| |
| |
| class GerritApi(recipe_api.RecipeApi): |
| """Module for querying a Gerrit host through the Gerrit API.""" |
| |
| def __init__(self, gerrit_host, *args, **kwargs): |
| super(GerritApi, self).__init__(*args, **kwargs) |
| self._gerrit_host = gerrit_host |
| self._gerrit_path = None |
| |
| def __call__(self, name, subcmd, input_json, gerrit_host=None, |
| test_data=None): |
| assert self._gerrit_path |
| if not gerrit_host: |
| assert self._gerrit_host |
| gerrit_host = self._gerrit_host |
| cmd = [ |
| self._gerrit_path, |
| subcmd, |
| '-host', gerrit_host, |
| '-input', self.m.json.input(input_json), |
| '-output', self.m.json.output(), |
| ] |
| |
| # If there's test data, create a factory for it. |
| step_test_data = None |
| if test_data is not None: |
| step_test_data = lambda: test_data |
| |
| # Run the gerrit client command. |
| return self.m.step( |
| name, |
| cmd, |
| step_test_data=step_test_data, |
| ).json.output |
| |
| def ensure_gerrit(self, version=None): |
| with self.m.step.nest('ensure_gerrit'): |
| with self.m.context(infra_steps=True): |
| cipd_dir = self.m.path['start_dir'].join('cipd', 'gerrit') |
| pkgs = self.m.cipd.EnsureFile() |
| pkgs.add_package('infra/tools/luci/gerrit/${platform}', version or 'latest') |
| self.m.cipd.ensure(cipd_dir, pkgs) |
| self._gerrit_path = cipd_dir.join('gerrit') |
| return self._gerrit_path |
| |
| @property |
| def host(self): |
| return self._gerrit_host |
| |
| @host.setter |
| def host(self, host): |
| self._gerrit_host = host |
| |
| def abandon(self, name, change_id, message=None, test_data=None): |
| """Abandons a change. |
| |
| Returns the details of the change, after attempting to abandon. |
| |
| Args: |
| name (str): The name of the step. |
| change_id (str): A change ID that uniquely defines a change on the host. |
| message (str): A message explaining the reason for abandoning the change. |
| test_data (recipe_test_api.StepTestData): Test JSON output data for this step. |
| """ |
| input_json = {'change_id': change_id} |
| if message: |
| input_json['input'] = {'message': message} |
| return self( |
| name=name, |
| subcmd='change-abandon', |
| input_json=input_json, |
| test_data=test_data, |
| ) |
| |
| def create_change(self, name, project, subject, branch, topic=None, |
| test_data=None): |
| """Creates a new change for a given project on the gerrit host. |
| |
| Returns the details of the newly-created change. |
| |
| Args: |
| name (str): The name of the step. |
| project (str): The name of the project on the host to create a change for. |
| subject (str): The subject of the new change. |
| branch (str): The branch onto which the change will be made. |
| topic (str): A gerrit topic that can be used to atomically land the change with |
| other changes in the same topic. |
| test_data (recipe_test_api.StepTestData): Test JSON output data for this step. |
| """ |
| input_json = {'input': { |
| 'project': project, |
| 'subject': subject, |
| 'branch': branch, |
| }} |
| if topic: |
| input_json['input']['topic'] = topic |
| return self( |
| name=name, |
| subcmd='change-create', |
| input_json=input_json, |
| test_data=test_data, |
| ) |
| |
| def set_review(self, name, change_id, labels=None, reviewers=None, |
| ccs=None, revision='current', test_data=None): |
| """Sets a change at a revision for review. Can optionally set labels, |
| reviewers, and CCs. |
| |
| Returns updated labels, reviewers, and whether the change is ready for |
| review as a JSON dict. |
| |
| Args: |
| name (str): The name of the step. |
| change_id (str): A change ID that uniquely defines a change on the host. |
| labels (dict): A map of labels (with names as strings, e.g. 'Code-Review') to the |
| integral values you wish to set them to. |
| reviewers (list): A list of strings containing reviewer IDs (e.g. email addresses). |
| ccs (list): A list of strings containing reviewer IDs (e.g. email addresses). |
| revision (str): A revision ID that identifies a revision for the change |
| (default is 'current'). |
| test_data (recipe_test_api.StepTestData): Test JSON output data for this step. |
| """ |
| input_json = { |
| 'change_id': change_id, |
| 'revision_id': revision, |
| 'input': {} |
| } |
| if labels: |
| input_json['input']['labels'] = labels |
| if reviewers or ccs: |
| input_json['input']['reviewers'] = [] |
| if reviewers: |
| input_json['input']['reviewers'] += [{'reviewer': i} for i in reviewers] |
| if ccs: |
| input_json['input']['reviewers'] += [{'reviewer': i, 'state': 'CC'} for i in ccs] |
| return self( |
| name=name, |
| subcmd='set-review', |
| input_json=input_json, |
| test_data=test_data, |
| ) |
| |
| def change_details(self, name, change_id, gerrit_host=None, query_params=[], |
| test_data=None): |
| """Returns a JSON dict of details regarding a specific change. |
| |
| Args: |
| name (str): The name of the step. |
| change_id (str): A change ID that uniquely defines a change on the host. |
| gerrit_host (str): The Gerrit host to make the query against. Overrides |
| the recipe module's global host property. |
| query_params (list): A list of Gerrit REST query parameters (strings). |
| Documented at |
| https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#query-options |
| test_data (recipe_test_api.StepTestData): Test JSON output data for this |
| step. |
| """ |
| input_json={'change_id': change_id} |
| if query_params: |
| input_json['params'] = {'o': query_params} |
| return self( |
| name=name, |
| subcmd='change-detail', |
| input_json=input_json, |
| gerrit_host=gerrit_host, |
| test_data=test_data, |
| ) |
| |
| def restore_change(self, name, change_id, message=None, test_data=None): |
| """Restores a change. |
| |
| Returns the details of the change, after attempting to restore. |
| |
| Args: |
| name (str): The name of the step. |
| change_id (str): A change ID that uniquely defines a change on the host. |
| message (str): An optional message explaining the reason for restoring the change. |
| test_data (recipe_test_api.StepTestData): Test JSON output data for this step. |
| """ |
| input_json = {'change_id': change_id} |
| if message: |
| input_json['input'] = {'message': message} |
| return self( |
| name=name, |
| subcmd='restore', |
| input_json=input_json, |
| test_data=test_data, |
| ) |