Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

slither: implement shell completions with shtab #2317

Open
wants to merge 5 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"eth-abi>=4.0.0",
"eth-typing>=3.0.0",
"eth-utils>=2.1.0",
"shtab>=1.7.1",
],
extras_require={
"lint": [
Expand Down
20 changes: 12 additions & 8 deletions slither/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from crytic_compile.platform.standard import generate_standard_export
from crytic_compile.platform.etherscan import SUPPORTED_NETWORK
from crytic_compile import compile_all, is_supported
import shtab

from slither.detectors import all_detectors
from slither.detectors.abstract_detector import AbstractDetector, DetectorClassification
Expand Down Expand Up @@ -293,7 +294,7 @@ def parse_filter_paths(args: argparse.Namespace, filter_path: bool) -> List[str]
def parse_args(
detector_classes: List[Type[AbstractDetector]], printer_classes: List[Type[AbstractPrinter]]
) -> argparse.Namespace:
usage = "slither target [flag]\n"
usage = "slither target [options]\n"
usage += "\ntarget can be:\n"
usage += "\t- file.sol // a Solidity file\n"
usage += "\t- project_directory // a project directory. See https://github.com/crytic/crytic-compile/#crytic-compile for the supported platforms\n"
Expand All @@ -305,7 +306,9 @@ def parse_args(
usage=usage,
)

parser.add_argument("filename", help=argparse.SUPPRESS)
shtab.add_argument_to(parser)

parser.add_argument("filename", metavar="target", help="File or project target, see above")

cryticparser.init(parser)

Expand Down Expand Up @@ -497,28 +500,28 @@ def parse_args(
help='Export the results as a JSON file ("--json -" to export to stdout)',
action="store",
default=defaults_flag_in_config["json"],
)
).complete = shtab.FILE

group_misc.add_argument(
"--sarif",
help='Export the results as a SARIF JSON file ("--sarif -" to export to stdout)',
action="store",
default=defaults_flag_in_config["sarif"],
)
).complete = shtab.FILE

group_misc.add_argument(
"--sarif-input",
help="Sarif input (beta)",
action="store",
default=defaults_flag_in_config["sarif_input"],
)
).complete = shtab.FILE

group_misc.add_argument(
"--sarif-triage",
help="Sarif triage (beta)",
action="store",
default=defaults_flag_in_config["sarif_triage"],
)
).complete = shtab.FILE

group_misc.add_argument(
"--json-types",
Expand All @@ -534,13 +537,14 @@ def parse_args(
help="Export the results as a zipped JSON file",
action="store",
default=defaults_flag_in_config["zip"],
)
).complete = shtab.FILE

group_misc.add_argument(
"--zip-type",
help=f'Zip compression type. One of {",".join(ZIP_TYPES_ACCEPTED.keys())}. Default lzma',
action="store",
default=defaults_flag_in_config["zip_type"],
choices=list(ZIP_TYPES_ACCEPTED.keys()),
)

group_misc.add_argument(
Expand Down Expand Up @@ -572,7 +576,7 @@ def parse_args(
action="store",
dest="config_file",
default=None,
)
).complete = shtab.FILE

group_misc.add_argument(
"--change-line-prefix",
Expand Down
9 changes: 6 additions & 3 deletions slither/tools/doctor/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import sys

from crytic_compile import cryticparser
import shtab

from slither.tools.doctor.utils import report_section
from slither.tools.doctor.checks import ALL_CHECKS
Expand All @@ -18,6 +19,8 @@ def parse_args() -> argparse.Namespace:
usage="slither-doctor project",
)

shtab.add_argument_to(parser)

parser.add_argument("project", help="The codebase to be tested.")

# Add default arguments from crytic-compile
Expand All @@ -27,12 +30,12 @@ def parse_args() -> argparse.Namespace:


def main() -> None:
# log on stdout to keep output in order
logging.basicConfig(stream=sys.stdout, level=logging.DEBUG, force=True)

args = parse_args()
kwargs = vars(args)

# log on stdout to keep output in order
logging.basicConfig(stream=sys.stdout, level=logging.DEBUG, force=True)

for check in ALL_CHECKS:
with report_section(check.title):
check.function(**kwargs)
Expand Down
3 changes: 3 additions & 0 deletions slither/tools/documentation/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import uuid
from typing import Optional, Dict, List
from crytic_compile import cryticparser
import shtab
from slither import Slither
from slither.core.compilation_unit import SlitherCompilationUnit
from slither.core.declarations import Function
Expand All @@ -26,6 +27,8 @@ def parse_args() -> argparse.Namespace:
usage="slither-documentation filename",
)

shtab.add_argument_to(parser)

parser.add_argument("project", help="The target directory/Solidity file.")

parser.add_argument(
Expand Down
8 changes: 6 additions & 2 deletions slither/tools/erc_conformance/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from typing import Any, Dict, List, Callable

from crytic_compile import cryticparser
import shtab

from slither import Slither
from slither.core.declarations import Contract
Expand Down Expand Up @@ -42,6 +43,8 @@ def parse_args() -> argparse.Namespace:
usage="slither-check-erc project contractName",
)

shtab.add_argument_to(parser)

parser.add_argument("project", help="The codebase to be tested.")

parser.add_argument(
Expand All @@ -53,15 +56,16 @@ def parse_args() -> argparse.Namespace:
"--erc",
help=f"ERC to be tested, available {','.join(ERCS.keys())} (default ERC20)",
action="store",
default="erc20",
default="ERC20",
choices=list(ERCS.keys()),
)

parser.add_argument(
"--json",
help='Export the results as a JSON file ("--json -" to export to stdout)',
action="store",
default=False,
)
).complete = shtab.FILE

# Add default arguments from crytic-compile
cryticparser.init(parser)
Expand Down
10 changes: 7 additions & 3 deletions slither/tools/flattening/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

from crytic_compile import cryticparser
from crytic_compile.utils.zip import ZIP_TYPES_ACCEPTED
import shtab

from slither import Slither
from slither.tools.flattening.flattening import (
Expand All @@ -28,6 +29,8 @@ def parse_args() -> argparse.Namespace:
usage="slither-flat filename",
)

shtab.add_argument_to(parser)

parser.add_argument("filename", help="The filename of the contract or project to analyze.")

parser.add_argument("--contract", help="Flatten one contract.", default=None)
Expand All @@ -44,27 +47,28 @@ def parse_args() -> argparse.Namespace:
"--dir",
help=f"Export directory (default: {DEFAULT_EXPORT_PATH}).",
default=None,
)
).complete = shtab.DIRECTORY

group_export.add_argument(
"--json",
help='Export the results as a JSON file ("--json -" to export to stdout)',
action="store",
default=None,
)
).complete = shtab.FILE

parser.add_argument(
"--zip",
help="Export all the files to a zip file",
action="store",
default=None,
)
).complete = shtab.FILE

parser.add_argument(
"--zip-type",
help=f"Zip compression type. One of {','.join(ZIP_TYPES_ACCEPTED.keys())}. Default lzma",
action="store",
default=None,
choices=list(ZIP_TYPES_ACCEPTED.keys()),
)

group_patching = parser.add_argument_group("Patching options")
Expand Down
3 changes: 3 additions & 0 deletions slither/tools/interface/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from pathlib import Path

from crytic_compile import cryticparser
import shtab

from slither import Slither
from slither.utils.code_generation import generate_interface
Expand All @@ -22,6 +23,8 @@ def parse_args() -> argparse.Namespace:
usage=("slither-interface <ContractName> <source file or deployment address>"),
)

shtab.add_argument_to(parser)

parser.add_argument(
"contract_source",
help="The name of the contract (case sensitive) followed by the deployed contract address if verified on etherscan or project directory/filename for local contracts.",
Expand Down
5 changes: 4 additions & 1 deletion slither/tools/kspec_coverage/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import logging
import argparse
from crytic_compile import cryticparser
import shtab
from slither.tools.kspec_coverage.kspec_coverage import kspec_coverage

logging.basicConfig()
Expand All @@ -26,6 +27,8 @@ def parse_args() -> argparse.Namespace:
usage="slither-kspec-coverage contract.sol kspec.md",
)

shtab.add_argument_to(parser)

parser.add_argument(
"contract", help="The filename of the contract or truffle directory to analyze."
)
Expand All @@ -45,7 +48,7 @@ def parse_args() -> argparse.Namespace:
help='Export the results as a JSON file ("--json -" to export to stdout)',
action="store",
default=False,
)
).complete = shtab.FILE

cryticparser.init(parser)

Expand Down
5 changes: 4 additions & 1 deletion slither/tools/mutator/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from pathlib import Path
from typing import Type, List, Any, Optional, Union
from crytic_compile import cryticparser
import shtab
from slither import Slither
from slither.tools.mutator.utils.testing_generated_mutant import run_test_cmd
from slither.tools.mutator.mutators import all_mutators
Expand Down Expand Up @@ -41,6 +42,8 @@ def parse_args() -> argparse.Namespace:
usage="slither-mutate <codebase> --test-cmd <test command> <options>",
)

shtab.add_argument_to(parser)

parser.add_argument("codebase", help="Codebase to analyze (.sol file, project directory, ...)")

parser.add_argument(
Expand All @@ -66,7 +69,7 @@ def parse_args() -> argparse.Namespace:
# output directory argument
parser.add_argument(
"--output-dir", help="Name of output directory (by default 'mutation_campaign')"
)
).complete = shtab.DIRECTORY

# to print just all the mutants
parser.add_argument(
Expand Down
3 changes: 3 additions & 0 deletions slither/tools/possible_paths/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from argparse import ArgumentParser, Namespace

from crytic_compile import cryticparser
import shtab
from slither import Slither
from slither.core.declarations import FunctionContract
from slither.utils.colors import red
Expand All @@ -27,6 +28,8 @@ def parse_args() -> Namespace:
usage="possible_paths.py filename [contract.function targets]",
)

shtab.add_argument_to(parser)

parser.add_argument(
"filename", help="The filename of the contract or truffle directory to analyze."
)
Expand Down
3 changes: 3 additions & 0 deletions slither/tools/properties/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from typing import Any

from crytic_compile import cryticparser
import shtab

from slither import Slither
from slither.tools.properties.properties.erc20 import generate_erc20, ERC20_PROPERTIES
Expand Down Expand Up @@ -73,6 +74,8 @@ def parse_args() -> argparse.Namespace:
formatter_class=argparse.RawDescriptionHelpFormatter,
)

shtab.add_argument_to(parser)

parser.add_argument(
"filename", help="The filename of the contract or project directory to analyze."
)
Expand Down
5 changes: 4 additions & 1 deletion slither/tools/read_storage/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import argparse

from crytic_compile import cryticparser
import shtab

from slither import Slither
from slither.exceptions import SlitherError
Expand All @@ -29,6 +30,8 @@ def parse_args() -> argparse.Namespace:
),
)

shtab.add_argument_to(parser)

parser.add_argument(
"contract_source",
help="The deployed contract address if verified on etherscan. Prepend project directory for unverified contracts.",
Expand Down Expand Up @@ -77,7 +80,7 @@ def parse_args() -> argparse.Namespace:
"--json",
action="store",
help="Save the result in a JSON file.",
)
).complete = shtab.FILE

parser.add_argument(
"--value",
Expand Down
11 changes: 8 additions & 3 deletions slither/tools/similarity/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import sys

from crytic_compile import cryticparser
import shtab

from slither.tools.similarity.info import info
from slither.tools.similarity.test import test
Expand All @@ -22,11 +23,15 @@ def parse_args() -> argparse.Namespace:
description="Code similarity detection tool. For usage, see https://github.com/crytic/slither/wiki/Code-Similarity-detector"
)

parser.add_argument("mode", help="|".join(modes))
shtab.add_argument_to(parser)

parser.add_argument("mode", help="|".join(modes), choices=modes)

parser.add_argument("model", help="model.bin")

parser.add_argument("--filename", action="store", dest="filename", help="contract.sol")
parser.add_argument(
"--filename", action="store", dest="filename", help="contract.sol"
).complete = shtab.FILE

parser.add_argument("--fname", action="store", dest="fname", help="Target function")

Expand All @@ -51,7 +56,7 @@ def parse_args() -> argparse.Namespace:

parser.add_argument(
"--input", action="store", dest="input", help="File or directory used as input"
)
).complete = shtab.FILE

parser.add_argument(
"--version",
Expand Down
Loading