Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore: copy script/patch.py from the libcc repo (#14627)
* chore: copy script/patch.py from the libcc repo * chore: fix pylint errors
- Loading branch information
1 parent
a314a15
commit 0ea687b
Showing
1 changed file
with
97 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
#!/usr/bin/env python | ||
""" | ||
Usage: patch -h | ||
Use this script to selectively apply and reverse patches. | ||
It is mostly useful to fix patches during upgrades to a new Chromium version. | ||
""" | ||
|
||
import argparse | ||
import os | ||
import subprocess | ||
import sys | ||
|
||
import lib.git as git | ||
from lib.patches import Patch, PatchesList, PatchesConfig | ||
|
||
|
||
def main(): | ||
args = parse_args() | ||
|
||
directory = args.directory | ||
force = args.force | ||
patches = args.patch | ||
project_root = args.project_root | ||
repo = args.repo | ||
reverse = args.reverse | ||
|
||
if directory: | ||
(success, failed_patches) = apply_patches_from_directory( | ||
directory, project_root, force, reverse) | ||
else: | ||
(success, failed_patches) = apply_patches(repo, patches, force, reverse) | ||
|
||
if success: | ||
print 'Done: All patches applied.' | ||
else: | ||
failed_patches_paths = [p.get_file_path() for p in failed_patches] | ||
print 'Error: {0} patch(es) failed:\n{1}'.format( | ||
len(failed_patches), '\n'.join(failed_patches_paths)) | ||
|
||
return 0 if success else 1 | ||
|
||
|
||
def apply_patches(repo_path, patches_paths, force=False, reverse=False): | ||
absolute_repo_path = os.path.abspath(repo_path) | ||
patches = [Patch(os.path.abspath(patch_path), absolute_repo_path) | ||
for patch_path in patches_paths] | ||
patches_list = PatchesList(repo_path=absolute_repo_path, patches=patches) | ||
stop_on_error = not force | ||
return patches_list.apply(reverse=reverse, stop_on_error=stop_on_error) | ||
|
||
|
||
def apply_patches_from_directory(directory, project_root, | ||
force=False, reverse=False): | ||
config = PatchesConfig.from_directory(directory, project_root=project_root) | ||
patches_list = config.get_patches_list() | ||
|
||
# Notify user if we didn't find any patch files. | ||
if patches_list is None or len(patches_list) == 0: | ||
print 'Warning: No patches found in the "{0}" folder.'.format(directory) | ||
return (True, []) | ||
|
||
# Then try to apply patches. | ||
stop_on_error = not force | ||
return patches_list.apply(reverse=reverse, stop_on_error=stop_on_error) | ||
|
||
|
||
def parse_args(): | ||
parser = argparse.ArgumentParser(description='Apply patches to a git repo') | ||
parser.add_argument('-f', '--force', default=False, action='store_true', | ||
help='Do not stop on the first failed patch.') | ||
parser.add_argument('--project-root', required=False, | ||
default=git.get_repo_root(os.path.abspath(__file__)), | ||
help='A folder to resolve repos relative paths against') | ||
parser.add_argument('-R', '--reverse', default=False, action='store_true', | ||
help='Apply patches in reverse.') | ||
parser.add_argument('-r', '--repo', help='Path to a repository root folder.') | ||
|
||
paths_group = parser.add_mutually_exclusive_group(required=True) | ||
paths_group.add_argument('-d', '--directory', | ||
help='Path to a directory with patches. \ | ||
If present, -p/--patch is ignored.') | ||
paths_group.add_argument('-p', '--patch', nargs='*', | ||
help='Path(s) to a patch file(s).') | ||
|
||
args = parser.parse_args() | ||
|
||
# Additional rules. | ||
if args.patch is not None and args.repo is None: | ||
parser.error("Repository path (-r/--repo) is required \ | ||
when you supply patches list.") | ||
|
||
return args | ||
|
||
|
||
if __name__ == '__main__': | ||
sys.exit(main()) |