| # 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. |
| """Update the tokenizer database. |
| |
| Note: this is not what most developers think of when they see "tokenizer". For |
| details see https://pigweed.dev/pw_tokenizer/. |
| |
| On its face builders using this recipe could create infinite loops but they |
| won't because the changes created by this recipe won't cause changes in the |
| generated database. |
| """ |
| |
| import re |
| |
| import attr |
| from PB.recipes.pigweed.tokendb_updater import InputProperties |
| |
| DEPS = [ |
| 'fuchsia/auto_roller', |
| 'fuchsia/git', |
| 'fuchsia/status_check', |
| 'pigweed/build', |
| 'pigweed/checkout', |
| 'pigweed/environment', |
| 'pigweed/roll_util', |
| 'recipe_engine/context', |
| 'recipe_engine/file', |
| 'recipe_engine/path', |
| 'recipe_engine/properties', |
| 'recipe_engine/step', |
| ] |
| |
| PROPERTIES = InputProperties |
| |
| PYTHON_VERSION_COMPATIBILITY = "PY3" |
| |
| |
| def RunSteps(api, props): # pylint: disable=invalid-name |
| api.checkout() |
| |
| tokendb_branch = props.tokendb_branch or "main" |
| generated_tokendb_path = api.checkout.root.join( |
| *re.split(r'/+', props.generated_tokendb_path) |
| ) |
| |
| if props.tokendb_host and props.tokendb_project: |
| directory = ( |
| api.path.abs_to_path( |
| api.path.split(api.path.abspath(generated_tokendb_path))[0] |
| ) |
| or api.checkout.root |
| ) |
| with api.step.nest('update token db repo'), api.context(cwd=directory): |
| api.git.fetch('origin', tokendb_branch) |
| api.git('checkout FETCH_HEAD', 'checkout', 'FETCH_HEAD') |
| |
| if bool(props.tokendb_host) != bool(props.tokendb_project): |
| raise ValueError( # pragma: no cover |
| 'tokendb_host ({}) and tokendb_project ({}) must both be set ' |
| 'or both be empty'.format(props.tokendb_host, props.tokendb_project) |
| ) |
| |
| tokendb_host = api.checkout.gerrit_host().replace('-review.', '.') |
| if props.tokendb_host: |
| tokendb_host = '{}.googlesource.com'.format(props.tokendb_host) |
| tokendb_project = props.tokendb_project or api.checkout.gerrit_project() |
| |
| # If the token database is in the top-level repo we just use that. If not |
| # we need to checkout the repo even though it's already in our checkout. |
| # It's much simpler to do a new checkout instead of parsing .gitmodules. |
| tokendb_repo = api.checkout.root |
| tokendb_branch = api.checkout.branch |
| |
| if props.tokendb_host and props.tokendb_project: |
| tokendb_repo = api.path['start_dir'].join('tokendb') |
| tokendb_remote = 'https://{}/{}'.format( |
| tokendb_host.rstrip('/'), tokendb_project.strip('/') |
| ) |
| tokendb_branch = props.tokendb_branch or "main" |
| api.checkout( |
| tokendb_remote, |
| root=tokendb_repo, |
| branch=tokendb_branch, |
| use_trigger=False, |
| ) |
| |
| api.environment.init(api.checkout.root) |
| |
| with api.environment(): |
| api.build(api.checkout.root) |
| |
| tokendb_path = tokendb_repo.join(*re.split(r'/+', props.tokendb_path)) |
| |
| if generated_tokendb_path != tokendb_path: |
| api.file.copy('copy', generated_tokendb_path, tokendb_path) |
| |
| message = 'Update token db for commit {}'.format( |
| api.checkout.revision[0:15] |
| ) |
| |
| change = api.auto_roller.attempt_roll( |
| gerrit_host=tokendb_host, |
| gerrit_project=tokendb_project, |
| upstream_ref=tokendb_branch, |
| repo_dir=tokendb_repo, |
| commit_message=message, |
| dry_run=props.dry_run, |
| labels_to_set=api.roll_util.labels_to_set, |
| labels_to_wait_on=api.roll_util.labels_to_wait_on, |
| bot_commit=props.bot_commit, |
| ) |
| |
| return api.auto_roller.raw_result(change) |
| |
| |
| def GenTests(api): # pylint: disable=invalid-name |
| def properties(**kwargs): |
| new_kwargs = { |
| 'steps': ['default'], |
| 'generated_tokendb_path': 'folder/generated.csv', |
| 'tokendb_path': 'tokendb.csv', |
| 'dry_run': False, |
| } |
| new_kwargs.update(api.checkout.git_properties()) |
| new_kwargs.update(kwargs) |
| return api.properties(**new_kwargs) |
| |
| yield ( |
| api.status_check.test('simple') |
| + properties() |
| + api.auto_roller.success() |
| ) |
| |
| yield ( |
| api.status_check.test('dry-run') |
| + properties(dry_run=True) |
| + api.auto_roller.dry_run_success() |
| ) |
| |
| yield ( |
| api.status_check.test('separate-repo') |
| + properties(tokendb_host='pigweed', tokendb_project='tokendb') |
| + api.auto_roller.success() |
| ) |