# This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. import argparse import os import re import shutil import sys from pathlib import Path from fetch_github_repo import fetch_repo from run_operations import ( RepoType, check_repo_status, detect_repo_type, get_last_line, run_git, run_shell, ) repo_type = detect_repo_type() # This script restores the mozilla patch stack and no-op commit tracking # files. In the case of repo corruption or a mistake made during # various rebase conflict resolution operations, the patch-stack can be # restored rather than requiring the user to restart the fast-forward # process from the beginning. def restore_patch_stack( github_path, github_branch, patch_directory, state_directory, tar_name, ): # make sure the repo is clean before beginning stdout_lines = check_repo_status(repo_type) if len(stdout_lines) != 0: print("There are modified or untracked files under third_party/libwebrtc") print("Please cleanup the repo under third_party/libwebrtc before running") print(os.path.basename(__file__)) sys.exit(1) # first, refetch the repo (hopefully utilizing the tarfile for speed) so # the patches apply cleanly print("fetch repo") fetch_repo(github_path, True, os.path.join(state_directory, tar_name)) # remove any stale no-op-cherry-pick-msg files in state_directory print("clear no-op-cherry-pick-msg files") run_shell(f"rm {state_directory}/*.no-op-cherry-pick-msg || true") # lookup latest vendored commit from third_party/libwebrtc/README.mozilla.last-vendor print( "lookup latest vendored commit from third_party/libwebrtc/README.mozilla.last-vendor" ) file = os.path.abspath("third_party/libwebrtc/README.mozilla.last-vendor") last_vendored_commit = get_last_line(file) # checkout the previous vendored commit with proper branch name print( f"checkout the previous vendored commit ({last_vendored_commit}) with proper branch name" ) cmd = f"git checkout -b {github_branch} {last_vendored_commit}" run_git(cmd, github_path) # restore the patches to moz-libwebrtc repo, use run_shell instead of # run_hg to allow filepath wildcard print("Restoring patch stack") test_directory = Path(patch_directory) pre_stack_file_cnt = len( list(Path(patch_directory).glob("p[0-9][0-9][0-9][0-9].patch")) ) print(f"Restoring {pre_stack_file_cnt} pre-stack patch files") if pre_stack_file_cnt > 0: run_shell(f"cd {github_path} && git am {patch_directory}/p*.patch") norm_stack_files = list(test_directory.glob("s*.patch")) norm_stack_file_cnt = len(norm_stack_files) print(f"Restoring {norm_stack_file_cnt} normal patch files") run_shell(f"cd {github_path} && git am {patch_directory}/s*.patch") # it is also helpful to restore the no-op-cherry-pick-msg files to # the state directory so that if we're restoring a patch-stack we # also restore the possibly consumed no-op tracking files. no_op_files = [ path for path in os.listdir(patch_directory) if re.findall(".*no-op-cherry-pick-msg$", path) ] for file in no_op_files: shutil.copy(os.path.join(patch_directory, file), state_directory) print("Please run the following command to verify the state of the patch-stack:") print(" bash dom/media/webrtc/third_party_build/verify_vendoring.sh") if __name__ == "__main__": # first, check which repo we're in, git or hg if repo_type is None or not isinstance(repo_type, RepoType): print("Unable to detect repo (git or hg)") sys.exit(1) default_patch_dir = "third_party/libwebrtc/moz-patch-stack" default_state_dir = ".moz-fast-forward" default_tar_name = "moz-libwebrtc.tar.gz" parser = argparse.ArgumentParser( description="Restore moz-libwebrtc github patch stack" ) parser.add_argument( "--repo-path", required=True, help="path to libwebrtc repo", ) parser.add_argument( "--branch", default="mozpatches", help="moz-libwebrtc branch (defaults to mozpatches)", ) parser.add_argument( "--patch-path", default=default_patch_dir, help=f"path to save patches (defaults to {default_patch_dir})", ) parser.add_argument( "--tar-name", default=default_tar_name, help=f"name of tar file (defaults to {default_tar_name})", ) parser.add_argument( "--state-path", default=default_state_dir, help=f"path to state directory (defaults to {default_state_dir})", ) args = parser.parse_args() restore_patch_stack( args.repo_path, args.branch, os.path.abspath(args.patch_path), args.state_path, args.tar_name, )