| # 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 |
| from PB.recipe_modules.pigweed.checkout.options import ( |
| Options as CheckoutOptions, |
| ) |
| |
| DEPS = [ |
| 'fuchsia/auto_roller', |
| 'fuchsia/git', |
| 'pigweed/build', |
| 'pigweed/checkout', |
| 'pigweed/environment', |
| 'recipe_engine/context', |
| 'recipe_engine/file', |
| 'recipe_engine/path', |
| 'recipe_engine/properties', |
| 'recipe_engine/step', |
| ] |
| |
| PROPERTIES = InputProperties |
| |
| |
| def RunSteps(api, props): # pylint: disable=invalid-name |
| checkout = api.checkout(props.checkout_options) |
| |
| tokendb_branch = props.tokendb_branch or "main" |
| generated_tokendb_path = 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 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 = checkout.gerrit_host().replace('-review.', '.') |
| if props.tokendb_host: |
| tokendb_host = f'{props.tokendb_host}.googlesource.com' |
| tokendb_project = props.tokendb_project or checkout.gerrit_project() |
| tokendb_remote = ( |
| f"https://{tokendb_host.rstrip('/')}/{tokendb_project.strip('/')}" |
| ) |
| |
| # 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 = checkout.root |
| tokendb_branch = checkout.options.branch |
| |
| if props.tokendb_host and props.tokendb_project: |
| tokendb_repo = api.path['start_dir'].join('tokendb') |
| tokendb_branch = props.tokendb_branch or "main" |
| api.checkout( |
| CheckoutOptions( |
| remote=tokendb_remote, branch=tokendb_branch, use_trigger=False |
| ), |
| root=tokendb_repo, |
| ) |
| |
| env = api.environment.init(checkout, props.environment_options) |
| |
| with env(): |
| api.build(checkout.root, props.build_options) |
| |
| 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 = f'Update token db for commit {checkout.revision()[0:15]}' |
| |
| change = api.auto_roller.attempt_roll( |
| props.auto_roller_options, |
| repo_dir=tokendb_repo, |
| commit_message=message, |
| ) |
| |
| return api.auto_roller.raw_result(change) |
| |
| |
| def GenTests(api): # pylint: disable=invalid-name |
| def properties(dry_run=False, **kwargs): |
| new_kwargs = { |
| 'steps': ['default'], |
| 'generated_tokendb_path': 'folder/generated.csv', |
| 'tokendb_path': 'tokendb.csv', |
| } |
| new_kwargs.update(api.checkout.git_properties()) |
| new_kwargs.setdefault( |
| 'auto_roller_options', |
| {'dry_run': dry_run, 'remote': api.checkout.pigweed_repo,}, |
| ) |
| new_kwargs.update(kwargs) |
| return api.properties(**new_kwargs) |
| |
| yield api.test('simple') + properties() + api.auto_roller.success() |
| |
| yield ( |
| api.test('dry-run') |
| + properties(dry_run=True) |
| + api.auto_roller.dry_run_success() |
| ) |
| |
| yield ( |
| api.test('separate-repo') |
| + properties(tokendb_host='pigweed', tokendb_project='tokendb') |
| + api.auto_roller.success() |
| ) |