| #!/usr/bin/env python |
| # Copyright 2022 The IREE Authors |
| # |
| # Licensed under the Apache License v2.0 with LLVM Exceptions. |
| # See https://llvm.org/LICENSE.txt for license information. |
| # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| |
| # Pushes module patches to an appropriate repository. |
| # |
| # Typical steps: |
| # 1. Advance the main branches on our forks to get all upstream commits |
| # (if you forget to do this, your cherry-pick will likely complain about |
| # a bad ref). |
| # 2. In your submodule: |
| # git fetch |
| # git cherry-pick <some commit> |
| # 3. Run this script from the main IREE repository (one of the following): |
| # patch_module.py --module=llvm-project |
| # patch_module.py --module=stablehlo |
| # 4. Send a PR on the main IREE repo to bump the submodule. Be sure to include |
| # the name of the patch branch for posterity. |
| |
| import argparse |
| from datetime import date |
| import os |
| import sys |
| |
| import iree_utils |
| import iree_modules |
| |
| PATCH_REMOTE_ALIAS = "patched" |
| |
| |
| def main(args): |
| module_info = iree_modules.MODULE_INFOS.get(args.module) |
| if not module_info: |
| raise SystemExit( |
| f"ERROR: Bad value for --module. Must be one of: " |
| f"{', '.join(iree_modules.MODULE_INFOS.keys())}" |
| ) |
| |
| if args.command == "patch": |
| main_patch(args, module_info) |
| else: |
| raise SystemExit( |
| f"ERROR: Unrecognized --command. Must be one of: patch, unpatch" |
| ) |
| |
| |
| def main_patch(args, module_info: iree_modules.ModuleInfo): |
| module_root = os.path.join(iree_utils.get_repo_root(), module_info.path) |
| setup_module_remotes(module_root, module_info) |
| |
| branch_name = find_unused_branch_name(module_info) |
| print(f"Allocated branch: {branch_name}") |
| current_commit, summary = iree_utils.git_current_commit(repo_dir=module_root) |
| print(f"Module is currently at: {summary}") |
| print(f"*** Pushing branch {branch_name} to {module_info.fork_repository_push} ***") |
| print(f"(Please ignore any messages below about creating a PR)\n") |
| iree_utils.git_exec( |
| ["push", PATCH_REMOTE_ALIAS, f"{current_commit}:refs/heads/{branch_name}"], |
| repo_dir=module_root, |
| ) |
| print(f"*** Branch {branch_name} pushed ***") |
| |
| print(f"******* Congratulations *******") |
| print( |
| f"You have pushed your commits to {branch_name} on {module_info.fork_repository_push}." |
| ) |
| print(f"Your main repository should now show that the submodule has been edited.") |
| print(f"Make a commit, referencing the above branch cherry-picks and ") |
| print(f"land the resulting PR.") |
| print(f"You can push more commits to this module's patch branch via:") |
| print( |
| f" (cd {module_info.path} && git push {PATCH_REMOTE_ALIAS} HEAD:{branch_name})" |
| ) |
| |
| |
| def setup_module_remotes(module_root: str, module_info: iree_modules.ModuleInfo): |
| iree_utils.git_setup_remote( |
| PATCH_REMOTE_ALIAS, url=module_info.fork_repository_push, repo_dir=module_root |
| ) |
| |
| |
| def find_unused_branch_name(module_info: iree_modules.ModuleInfo): |
| branch_base = f"{module_info.branch_prefix}{date.today().strftime('%Y%m%d')}" |
| branch_name = branch_base |
| existing_branches = iree_utils.git_ls_remote_branches( |
| module_info.fork_repository_pull, |
| filter=[f"refs/heads/{module_info.branch_prefix}*"], |
| ) |
| i = 1 |
| while branch_name in existing_branches: |
| branch_name = f"{branch_base}.{i}" |
| i += 1 |
| return branch_name |
| |
| |
| def parse_arguments(argv): |
| parser = argparse.ArgumentParser(description="IREE Submodule Patcher") |
| parser.add_argument("--module", help="Submodule to operate on", default=None) |
| parser.add_argument("--command", help="Command to execute", default="patch") |
| args = parser.parse_args(argv) |
| return args |
| |
| |
| if __name__ == "__main__": |
| main(parse_arguments(sys.argv[1:])) |