mirror of
https://github.com/volatilityfoundation/volatility3.git
synced 2026-08-17 20:35:40 +02:00
Add in shtab autocompletion
This commit is contained in:
@@ -22,6 +22,13 @@ import traceback
|
||||
from typing import Any, Dict, List, Tuple, Type, Union
|
||||
from urllib import parse, request
|
||||
|
||||
try:
|
||||
import shtab
|
||||
|
||||
HAS_SHTAB = True
|
||||
except ImportError:
|
||||
HAS_SHTAB = False
|
||||
|
||||
from volatility3.cli import text_filter
|
||||
import volatility3.plugins
|
||||
import volatility3.symbols
|
||||
@@ -106,6 +113,9 @@ class CommandLine:
|
||||
]
|
||||
)
|
||||
|
||||
# Argument for doing autocompletion
|
||||
print_completion_arg = "--print-completion"
|
||||
|
||||
# Load up system defaults
|
||||
delayed_logs, default_config = self.load_system_defaults("vol.json")
|
||||
|
||||
@@ -246,10 +256,12 @@ class CommandLine:
|
||||
# We have to filter out help, otherwise parse_known_args will trigger the help message before having
|
||||
# processed the plugin choice or had the plugin subparser added.
|
||||
known_args = [arg for arg in sys.argv if arg != "--help" and arg != "-h"]
|
||||
partial_args, _ = parser.parse_known_args(known_args)
|
||||
|
||||
partial_args, unknown_args = parser.parse_known_args(known_args)
|
||||
banner_output = sys.stdout
|
||||
if renderers[partial_args.renderer].structured_output:
|
||||
if (
|
||||
renderers[partial_args.renderer].structured_output
|
||||
or print_completion_arg in unknown_args
|
||||
):
|
||||
banner_output = sys.stderr
|
||||
banner_output.write(f"Volatility 3 Framework {constants.PACKAGE_VERSION}\n")
|
||||
|
||||
@@ -351,6 +363,10 @@ class CommandLine:
|
||||
# Hand the plugin requirements over to the CLI (us) and let it construct the config tree
|
||||
|
||||
# Run the argparser
|
||||
if HAS_SHTAB:
|
||||
# The autocompletion line must be after the partial_arg handling, so that it doesn't trip it
|
||||
# before all the plugins have been added
|
||||
shtab.add_argument_to(parser, [print_completion_arg])
|
||||
args = parser.parse_args()
|
||||
if args.plugin is None:
|
||||
parser.error("Please select a plugin to run")
|
||||
|
||||
@@ -21,8 +21,6 @@ class HelpfulSubparserAction(argparse._SubParsersAction):
|
||||
|
||||
def __init__(self, *args, **kwargs) -> None:
|
||||
super().__init__(*args, **kwargs)
|
||||
# We don't want the action self-check to kick in, so we remove the choices list, the check happens in __call__
|
||||
self.choices = None
|
||||
|
||||
def __call__(
|
||||
self,
|
||||
@@ -100,3 +98,7 @@ class HelpfulArgParser(argparse.ArgumentParser):
|
||||
|
||||
# return the number of arguments matched
|
||||
return len(match.group(1))
|
||||
|
||||
def _check_value(self, action, value):
|
||||
if not isinstance(action, HelpfulSubparserAction):
|
||||
return super()._check_value(action, value)
|
||||
|
||||
Reference in New Issue
Block a user