filter-repo: restructure argument parsing for re-use

Signed-off-by: Elijah Newren <newren@gmail.com>
This commit is contained in:
Elijah Newren 2018-12-24 22:59:38 -08:00
parent 9bb4188e83
commit 2f3a445875

View File

@ -25,9 +25,9 @@ import textwrap
from datetime import tzinfo, timedelta, datetime
__all__ = ["Blob", "Reset", "FileChanges", "Commit", "Tag", "Progress",
"Checkpoint", "FastExportFilter", "FixedTimeZone",
"Checkpoint", "FastExportFilter", "FixedTimeZone", "ProgressWriter",
"fast_export_output", "fast_import_input", "get_commit_count",
"get_total_objects", "record_id_rename"]
"get_total_objects", "record_id_rename", "FilteringOptions"]
def _timedelta_to_seconds(delta):
@ -1670,7 +1670,8 @@ _CURRENT_STREAM_NUMBER = 0
######################################################################
class AppendFilter(argparse.Action):
class FilteringOptions(object):
class AppendFilter(argparse.Action):
def __call__(self, parser, namespace, values, option_string=None):
suffix = option_string[len('--path-'):] or 'match'
if suffix == 'rename':
@ -1686,9 +1687,10 @@ class AppendFilter(argparse.Action):
items.append((mod_type, match_type, values))
setattr(namespace, self.dest, items)
class HelperFilter(argparse.Action):
class HelperFilter(argparse.Action):
def __call__(self, parser, namespace, values, option_string=None):
af = AppendFilter(dest='path_changes', option_strings=None)
af = FilteringOptions.AppendFilter(dest='path_changes',
option_strings=None)
dirname = values if values[-1] == '/' else values+'/'
if option_string == '--subdirectory-filter':
af(parser, namespace, dirname, '--path-match')
@ -1699,7 +1701,8 @@ class HelperFilter(argparse.Action):
raise SystemExit("Error: HelperFilter given invalid option_string: {}"
.format(option_string))
def get_args():
@staticmethod
def create_arg_parser():
# Include usage in the summary, so we can put the description first
summary = '''Rewrite (or analyze) repository history
@ -1753,17 +1756,17 @@ def get_args():
select files matching none of those options.''')
path.add_argument('--path-match', '--path', metavar='DIR_OR_FILE',
action=AppendFilter, dest='path_changes',
action=FilteringOptions.AppendFilter, dest='path_changes',
help='''Exact paths (files or directories) to include in
filtered history. Multiple --path options can be
specified to get a union of paths.''')
path.add_argument('--path-glob', metavar='GLOB',
action=AppendFilter, dest='path_changes',
action=FilteringOptions.AppendFilter, dest='path_changes',
help='''Glob of paths to include in filtered history.
Multiple --path-glob options can be specified to
get a union of paths.''')
path.add_argument('--path-regex', metavar='REGEX',
action=AppendFilter, dest='path_changes',
action=FilteringOptions.AppendFilter, dest='path_changes',
help='''Regex of paths to include in filtered history.
Multiple --path-regex options can be specified to
get a union of paths''')
@ -1771,7 +1774,8 @@ def get_args():
rename = parser.add_argument_group(title='Renaming based on paths')
rename.add_argument('--path-rename', '--path-rename-prefix',
metavar='OLD_NAME:NEW_NAME',
action=AppendFilter, dest='path_changes',
action=FilteringOptions.AppendFilter,
dest='path_changes',
help='''Prefix to rename; if filename starts with
OLD_NAME, replace that with NEW_NAME. Multiple
--path-rename options can be specified.''')
@ -1785,13 +1789,14 @@ def get_args():
helpers = parser.add_argument_group(title='Shortcuts')
helpers.add_argument('--subdirectory-filter', metavar='DIRECTORY',
action=HelperFilter,
action=FilteringOptions.HelperFilter,
help='''Only look at history that touches the given
subdirectory and treat that directory as the
project root. Equivalent to using
"--path DIRECTORY/ --path-rename DIRECTORY/:"''')
"--path DIRECTORY/ --path-rename DIRECTORY/:"
''')
helpers.add_argument('--to-subdirectory-filter', metavar='DIRECTORY',
action=HelperFilter,
action=FilteringOptions.HelperFilter,
help='''Treat the project root as instead being under
DIRECTORY. Equivalent to using
"--path-rename :DIRECTORY/"''')
@ -1821,14 +1826,10 @@ def get_args():
stdin.''')
misc.add_argument('--quiet', action='store_true',
help='''Pass --quiet to other git commands called''')
return parser
if len(sys.argv) == 1:
parser.print_usage()
raise SystemExit("No arguments specified.")
args = parser.parse_args()
if args.help:
parser.print_help()
raise SystemExit()
@staticmethod
def sanity_check_args(args):
if not args.refs:
args.refs = ['--all']
if args.analyze and args.path_changes:
@ -1849,6 +1850,22 @@ def get_args():
has_filter = True
if not has_filter:
args.inclusive = False
@staticmethod
def default_options():
return FilteringOptions.parse_args([], error_on_empty = False)
@staticmethod
def parse_args(input_args, error_on_empty = True):
parser = FilteringOptions.create_arg_parser()
if not input_args and error_on_empty:
parser.print_usage()
raise SystemExit("No arguments specified.")
args = parser.parse_args(input_args)
if args.help:
parser.print_help()
raise SystemExit()
FilteringOptions.sanity_check_args(args)
return args
def is_repository_bare():
@ -2474,7 +2491,7 @@ class DualFileWriter:
self.file2.close()
def run_fast_filter():
args = get_args()
args = FilteringOptions.parse_args(sys.argv[1:])
if args.debug:
print("[DEBUG] Parsed arguments:\n{}".format(args))