restore_patch_stack.py (5048B)
1 # This Source Code Form is subject to the terms of the Mozilla Public 2 # License, v. 2.0. If a copy of the MPL was not distributed with this 3 # file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 import argparse 5 import os 6 import re 7 import shutil 8 import sys 9 from pathlib import Path 10 11 from fetch_github_repo import fetch_repo 12 from run_operations import ( 13 RepoType, 14 check_repo_status, 15 detect_repo_type, 16 get_last_line, 17 run_git, 18 run_shell, 19 ) 20 21 repo_type = detect_repo_type() 22 23 # This script restores the mozilla patch stack and no-op commit tracking 24 # files. In the case of repo corruption or a mistake made during 25 # various rebase conflict resolution operations, the patch-stack can be 26 # restored rather than requiring the user to restart the fast-forward 27 # process from the beginning. 28 29 30 def restore_patch_stack( 31 github_path, 32 github_branch, 33 patch_directory, 34 state_directory, 35 tar_name, 36 ): 37 # make sure the repo is clean before beginning 38 stdout_lines = check_repo_status(repo_type) 39 if len(stdout_lines) != 0: 40 print("There are modified or untracked files under third_party/libwebrtc") 41 print("Please cleanup the repo under third_party/libwebrtc before running") 42 print(os.path.basename(__file__)) 43 sys.exit(1) 44 45 # first, refetch the repo (hopefully utilizing the tarfile for speed) so 46 # the patches apply cleanly 47 print("fetch repo") 48 fetch_repo(github_path, True, os.path.join(state_directory, tar_name)) 49 50 # remove any stale no-op-cherry-pick-msg files in state_directory 51 print("clear no-op-cherry-pick-msg files") 52 run_shell(f"rm {state_directory}/*.no-op-cherry-pick-msg || true") 53 54 # lookup latest vendored commit from third_party/libwebrtc/README.mozilla.last-vendor 55 print( 56 "lookup latest vendored commit from third_party/libwebrtc/README.mozilla.last-vendor" 57 ) 58 file = os.path.abspath("third_party/libwebrtc/README.mozilla.last-vendor") 59 last_vendored_commit = get_last_line(file) 60 61 # checkout the previous vendored commit with proper branch name 62 print( 63 f"checkout the previous vendored commit ({last_vendored_commit}) with proper branch name" 64 ) 65 cmd = f"git checkout -b {github_branch} {last_vendored_commit}" 66 run_git(cmd, github_path) 67 68 # restore the patches to moz-libwebrtc repo, use run_shell instead of 69 # run_hg to allow filepath wildcard 70 print("Restoring patch stack") 71 test_directory = Path(patch_directory) 72 pre_stack_file_cnt = len( 73 list(Path(patch_directory).glob("p[0-9][0-9][0-9][0-9].patch")) 74 ) 75 print(f"Restoring {pre_stack_file_cnt} pre-stack patch files") 76 if pre_stack_file_cnt > 0: 77 run_shell(f"cd {github_path} && git am {patch_directory}/p*.patch") 78 79 norm_stack_files = list(test_directory.glob("s*.patch")) 80 norm_stack_file_cnt = len(norm_stack_files) 81 print(f"Restoring {norm_stack_file_cnt} normal patch files") 82 run_shell(f"cd {github_path} && git am {patch_directory}/s*.patch") 83 84 # it is also helpful to restore the no-op-cherry-pick-msg files to 85 # the state directory so that if we're restoring a patch-stack we 86 # also restore the possibly consumed no-op tracking files. 87 no_op_files = [ 88 path 89 for path in os.listdir(patch_directory) 90 if re.findall(".*no-op-cherry-pick-msg$", path) 91 ] 92 for file in no_op_files: 93 shutil.copy(os.path.join(patch_directory, file), state_directory) 94 95 print("Please run the following command to verify the state of the patch-stack:") 96 print(" bash dom/media/webrtc/third_party_build/verify_vendoring.sh") 97 98 99 if __name__ == "__main__": 100 # first, check which repo we're in, git or hg 101 if repo_type is None or not isinstance(repo_type, RepoType): 102 print("Unable to detect repo (git or hg)") 103 sys.exit(1) 104 105 default_patch_dir = "third_party/libwebrtc/moz-patch-stack" 106 default_state_dir = ".moz-fast-forward" 107 default_tar_name = "moz-libwebrtc.tar.gz" 108 109 parser = argparse.ArgumentParser( 110 description="Restore moz-libwebrtc github patch stack" 111 ) 112 parser.add_argument( 113 "--repo-path", 114 required=True, 115 help="path to libwebrtc repo", 116 ) 117 parser.add_argument( 118 "--branch", 119 default="mozpatches", 120 help="moz-libwebrtc branch (defaults to mozpatches)", 121 ) 122 parser.add_argument( 123 "--patch-path", 124 default=default_patch_dir, 125 help=f"path to save patches (defaults to {default_patch_dir})", 126 ) 127 parser.add_argument( 128 "--tar-name", 129 default=default_tar_name, 130 help=f"name of tar file (defaults to {default_tar_name})", 131 ) 132 parser.add_argument( 133 "--state-path", 134 default=default_state_dir, 135 help=f"path to state directory (defaults to {default_state_dir})", 136 ) 137 args = parser.parse_args() 138 139 restore_patch_stack( 140 args.repo_path, 141 args.branch, 142 os.path.abspath(args.patch_path), 143 args.state_path, 144 args.tar_name, 145 )