Skip to content

Commit 7c35724

Browse files
do dynamic command dispatching
1 parent 120f421 commit 7c35724

File tree

2 files changed

+19
-80
lines changed

2 files changed

+19
-80
lines changed

src/borg/archiver/__init__.py

Lines changed: 15 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -64,66 +64,6 @@
6464
PURE_PYTHON_MSGPACK_WARNING = "Using a pure-python msgpack! This will result in lower performance."
6565

6666

67-
# Command dispatch table: maps subcommand names to method names on the Archiver class.
68-
# For nested subcommands (key, debug, benchmark), the value is a dict mapping
69-
# the nested subcommand name to the method name.
70-
COMMAND_DISPATCH = {
71-
"analyze": "do_analyze",
72-
"benchmark": {"crud": "do_benchmark_crud", "cpu": "do_benchmark_cpu"},
73-
"break-lock": "do_break_lock",
74-
"check": "do_check",
75-
"compact": "do_compact",
76-
"completion": "do_completion",
77-
"create": "do_create",
78-
"debug": {
79-
"info": "do_debug_info",
80-
"dump-archive-items": "do_debug_dump_archive_items",
81-
"dump-archive": "do_debug_dump_archive",
82-
"dump-manifest": "do_debug_dump_manifest",
83-
"dump-repo-objs": "do_debug_dump_repo_objs",
84-
"search-repo-objs": "do_debug_search_repo_objs",
85-
"id-hash": "do_debug_id_hash",
86-
"parse-obj": "do_debug_parse_obj",
87-
"format-obj": "do_debug_format_obj",
88-
"get-obj": "do_debug_get_obj",
89-
"put-obj": "do_debug_put_obj",
90-
"delete-obj": "do_debug_delete_obj",
91-
"convert-profile": "do_debug_convert_profile",
92-
},
93-
"delete": "do_delete",
94-
"diff": "do_diff",
95-
"export-tar": "do_export_tar",
96-
"extract": "do_extract",
97-
"help": "do_help",
98-
"import-tar": "do_import_tar",
99-
"info": "do_info",
100-
"key": {
101-
"change-passphrase": "do_change_passphrase",
102-
"change-location": "do_change_location",
103-
"export": "do_key_export",
104-
"import": "do_key_import",
105-
},
106-
"list": "do_list",
107-
"mount": "do_mount",
108-
"prune": "do_prune",
109-
"repo-compress": "do_repo_compress",
110-
"repo-create": "do_repo_create",
111-
"repo-delete": "do_repo_delete",
112-
"repo-info": "do_repo_info",
113-
"repo-list": "do_repo_list",
114-
"repo-space": "do_repo_space",
115-
"recreate": "do_recreate",
116-
"rename": "do_rename",
117-
"serve": "do_serve",
118-
"tag": "do_tag",
119-
"transfer": "do_transfer",
120-
"umount": "do_umount",
121-
"undelete": "do_undelete",
122-
"version": "do_version",
123-
"with-lock": "do_with_lock",
124-
}
125-
126-
12767
from .analyze_cmd import AnalyzeMixIn
12868
from .benchmark_cmd import BenchmarkMixIn
12969
from .check_cmd import CheckMixIn
@@ -462,24 +402,23 @@ def get_func(self, args):
462402
if subcmd is None:
463403
return functools.partial(self.do_maincommand_help, self.parser)
464404

465-
dispatch = COMMAND_DISPATCH.get(subcmd)
466-
if dispatch is None:
467-
return functools.partial(self.do_maincommand_help, self.parser)
405+
subcmd_ns = getattr(args, subcmd, None)
406+
nested_subcmd = getattr(subcmd_ns, "subcommand", None) if subcmd_ns else None
468407

469-
if isinstance(dispatch, dict):
470-
# Nested subcommand (key, debug, benchmark)
471-
subcmd_ns = getattr(args, subcmd, None)
472-
nested_subcmd = getattr(subcmd_ns, "subcommand", None) if subcmd_ns else None
473-
if nested_subcmd is None:
474-
# No nested subcommand given, show subcommand help
475-
# We need the parser for the mid-level command
476-
return functools.partial(self.do_subcommand_help, self.parser)
477-
method_name = dispatch.get(nested_subcmd)
478-
if method_name is None:
479-
return functools.partial(self.do_subcommand_help, self.parser)
480-
func = getattr(self, method_name)
408+
if nested_subcmd is None:
409+
method_name = f"do_{subcmd}".replace("-", "_")
481410
else:
482-
func = getattr(self, dispatch)
411+
method_name = f"do_{subcmd}_{nested_subcmd}".replace("-", "_")
412+
413+
func = getattr(self, method_name, None)
414+
415+
if func is None:
416+
# Fallback for container commands or unknown commands
417+
if nested_subcmd is None and subcmd_ns is not None:
418+
# Might be a container command without a subcommand selected (e.g. just "borg key")
419+
subparser = getattr(self, "_commands", {}).get(subcmd)
420+
return functools.partial(self.do_subcommand_help, subparser or self.parser)
421+
return functools.partial(self.do_maincommand_help, self.parser)
483422

484423
# Special handling for "help" command which needs extra args
485424
if subcmd == "help":

src/borg/archiver/key_cmds.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020
class KeysMixIn:
2121
@with_repository(compatibility=(Manifest.Operation.CHECK,))
22-
def do_change_passphrase(self, args, repository, manifest):
22+
def do_key_change_passphrase(self, args, repository, manifest):
2323
"""Changes the repository key file passphrase."""
2424
key = manifest.key
2525
if not hasattr(key, "change_passphrase"):
@@ -31,7 +31,7 @@ def do_change_passphrase(self, args, repository, manifest):
3131
logger.info("Key location: %s", key.find_key())
3232

3333
@with_repository(exclusive=True, manifest=True, cache=True, compatibility=(Manifest.Operation.CHECK,))
34-
def do_change_location(self, args, repository, manifest, cache):
34+
def do_key_change_location(self, args, repository, manifest, cache):
3535
"""Changes the repository key location."""
3636
key = manifest.key
3737
if not hasattr(key, "change_passphrase"):
@@ -239,7 +239,7 @@ def build_parser_keys_l2(self, key_parser, common_parser):
239239
subparser = ArgumentParser(
240240
parents=[common_parser],
241241
add_help=False,
242-
description=self.do_change_passphrase.__doc__,
242+
description=self.do_key_change_passphrase.__doc__,
243243
epilog=change_passphrase_epilog,
244244
formatter_class=argparse.RawDescriptionHelpFormatter,
245245
)
@@ -261,7 +261,7 @@ def build_parser_keys_l2(self, key_parser, common_parser):
261261
subparser = ArgumentParser(
262262
parents=[common_parser],
263263
add_help=False,
264-
description=self.do_change_location.__doc__,
264+
description=self.do_key_change_location.__doc__,
265265
epilog=change_location_epilog,
266266
formatter_class=argparse.RawDescriptionHelpFormatter,
267267
)

0 commit comments

Comments
 (0)