slither: implement shell completions with `shtab`

These can be generated by running e.g. `slither --print-completion zsh`
and installed as usual.

Closes #2055
dev-autocompletion
Emilio López 10 months ago
parent 9fa8e8ea1f
commit b2b1c5a88b
  1. 1
      setup.py
  2. 16
      slither/__main__.py
  3. 3
      slither/tools/doctor/__main__.py
  4. 3
      slither/tools/documentation/__main__.py
  5. 8
      slither/tools/erc_conformance/__main__.py
  6. 10
      slither/tools/flattening/__main__.py
  7. 3
      slither/tools/interface/__main__.py
  8. 5
      slither/tools/kspec_coverage/__main__.py
  9. 5
      slither/tools/mutator/__main__.py
  10. 3
      slither/tools/possible_paths/__main__.py
  11. 3
      slither/tools/properties/__main__.py
  12. 5
      slither/tools/read_storage/__main__.py
  13. 11
      slither/tools/similarity/__main__.py
  14. 5
      slither/tools/slither_format/__main__.py
  15. 7
      slither/tools/upgradeability/__main__.py

@ -21,6 +21,7 @@ setup(
"eth-abi>=4.0.0", "eth-abi>=4.0.0",
"eth-typing>=3.0.0", "eth-typing>=3.0.0",
"eth-utils>=2.1.0", "eth-utils>=2.1.0",
"shtab>=1.6.5",
], ],
extras_require={ extras_require={
"lint": [ "lint": [

@ -18,6 +18,7 @@ from crytic_compile import cryticparser, CryticCompile
from crytic_compile.platform.standard import generate_standard_export from crytic_compile.platform.standard import generate_standard_export
from crytic_compile.platform.etherscan import SUPPORTED_NETWORK from crytic_compile.platform.etherscan import SUPPORTED_NETWORK
from crytic_compile import compile_all, is_supported from crytic_compile import compile_all, is_supported
import shtab
from slither.detectors import all_detectors from slither.detectors import all_detectors
from slither.detectors.abstract_detector import AbstractDetector, DetectorClassification from slither.detectors.abstract_detector import AbstractDetector, DetectorClassification
@ -290,6 +291,8 @@ def parse_args(
usage=usage, usage=usage,
) )
shtab.add_argument_to(parser)
parser.add_argument("filename", help=argparse.SUPPRESS) parser.add_argument("filename", help=argparse.SUPPRESS)
cryticparser.init(parser) cryticparser.init(parser)
@ -465,28 +468,28 @@ def parse_args(
help='Export the results as a JSON file ("--json -" to export to stdout)', help='Export the results as a JSON file ("--json -" to export to stdout)',
action="store", action="store",
default=defaults_flag_in_config["json"], default=defaults_flag_in_config["json"],
) ).complete = shtab.FILE
group_misc.add_argument( group_misc.add_argument(
"--sarif", "--sarif",
help='Export the results as a SARIF JSON file ("--sarif -" to export to stdout)', help='Export the results as a SARIF JSON file ("--sarif -" to export to stdout)',
action="store", action="store",
default=defaults_flag_in_config["sarif"], default=defaults_flag_in_config["sarif"],
) ).complete = shtab.FILE
group_misc.add_argument( group_misc.add_argument(
"--sarif-input", "--sarif-input",
help="Sarif input (beta)", help="Sarif input (beta)",
action="store", action="store",
default=defaults_flag_in_config["sarif_input"], default=defaults_flag_in_config["sarif_input"],
) ).complete = shtab.FILE
group_misc.add_argument( group_misc.add_argument(
"--sarif-triage", "--sarif-triage",
help="Sarif triage (beta)", help="Sarif triage (beta)",
action="store", action="store",
default=defaults_flag_in_config["sarif_triage"], default=defaults_flag_in_config["sarif_triage"],
) ).complete = shtab.FILE
group_misc.add_argument( group_misc.add_argument(
"--json-types", "--json-types",
@ -502,13 +505,14 @@ def parse_args(
help="Export the results as a zipped JSON file", help="Export the results as a zipped JSON file",
action="store", action="store",
default=defaults_flag_in_config["zip"], default=defaults_flag_in_config["zip"],
) ).complete = shtab.FILE
group_misc.add_argument( group_misc.add_argument(
"--zip-type", "--zip-type",
help=f'Zip compression type. One of {",".join(ZIP_TYPES_ACCEPTED.keys())}. Default lzma', help=f'Zip compression type. One of {",".join(ZIP_TYPES_ACCEPTED.keys())}. Default lzma',
action="store", action="store",
default=defaults_flag_in_config["zip_type"], default=defaults_flag_in_config["zip_type"],
choices=list(ZIP_TYPES_ACCEPTED.keys()),
) )
group_misc.add_argument( group_misc.add_argument(
@ -540,7 +544,7 @@ def parse_args(
action="store", action="store",
dest="config_file", dest="config_file",
default=None, default=None,
) ).complete = shtab.FILE
group_misc.add_argument( group_misc.add_argument(
"--change-line-prefix", "--change-line-prefix",

@ -3,6 +3,7 @@ import logging
import sys import sys
from crytic_compile import cryticparser from crytic_compile import cryticparser
import shtab
from slither.tools.doctor.utils import report_section from slither.tools.doctor.utils import report_section
from slither.tools.doctor.checks import ALL_CHECKS from slither.tools.doctor.checks import ALL_CHECKS
@ -18,6 +19,8 @@ def parse_args() -> argparse.Namespace:
usage="slither-doctor project", usage="slither-doctor project",
) )
shtab.add_argument_to(parser)
parser.add_argument("project", help="The codebase to be tested.") parser.add_argument("project", help="The codebase to be tested.")
# Add default arguments from crytic-compile # Add default arguments from crytic-compile

@ -3,6 +3,7 @@ import logging
import uuid import uuid
from typing import Optional, Dict, List from typing import Optional, Dict, List
from crytic_compile import cryticparser from crytic_compile import cryticparser
import shtab
from slither import Slither from slither import Slither
from slither.core.compilation_unit import SlitherCompilationUnit from slither.core.compilation_unit import SlitherCompilationUnit
from slither.core.declarations import Function from slither.core.declarations import Function
@ -26,6 +27,8 @@ def parse_args() -> argparse.Namespace:
usage="slither-documentation filename", usage="slither-documentation filename",
) )
shtab.add_argument_to(parser)
parser.add_argument("project", help="The target directory/Solidity file.") parser.add_argument("project", help="The target directory/Solidity file.")
parser.add_argument( parser.add_argument(

@ -4,6 +4,7 @@ from collections import defaultdict
from typing import Any, Dict, List, Callable from typing import Any, Dict, List, Callable
from crytic_compile import cryticparser from crytic_compile import cryticparser
import shtab
from slither import Slither from slither import Slither
from slither.core.declarations import Contract from slither.core.declarations import Contract
@ -42,6 +43,8 @@ def parse_args() -> argparse.Namespace:
usage="slither-check-erc project contractName", usage="slither-check-erc project contractName",
) )
shtab.add_argument_to(parser)
parser.add_argument("project", help="The codebase to be tested.") parser.add_argument("project", help="The codebase to be tested.")
parser.add_argument( parser.add_argument(
@ -53,7 +56,8 @@ def parse_args() -> argparse.Namespace:
"--erc", "--erc",
help=f"ERC to be tested, available {','.join(ERCS.keys())} (default ERC20)", help=f"ERC to be tested, available {','.join(ERCS.keys())} (default ERC20)",
action="store", action="store",
default="erc20", default="ERC20",
choices=list(ERCS.keys()),
) )
parser.add_argument( parser.add_argument(
@ -61,7 +65,7 @@ def parse_args() -> argparse.Namespace:
help='Export the results as a JSON file ("--json -" to export to stdout)', help='Export the results as a JSON file ("--json -" to export to stdout)',
action="store", action="store",
default=False, default=False,
) ).complete = shtab.FILE
# Add default arguments from crytic-compile # Add default arguments from crytic-compile
cryticparser.init(parser) cryticparser.init(parser)

@ -4,6 +4,7 @@ import sys
from crytic_compile import cryticparser from crytic_compile import cryticparser
from crytic_compile.utils.zip import ZIP_TYPES_ACCEPTED from crytic_compile.utils.zip import ZIP_TYPES_ACCEPTED
import shtab
from slither import Slither from slither import Slither
from slither.tools.flattening.flattening import ( from slither.tools.flattening.flattening import (
@ -28,6 +29,8 @@ def parse_args() -> argparse.Namespace:
usage="slither-flat filename", 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("filename", help="The filename of the contract or project to analyze.")
parser.add_argument("--contract", help="Flatten one contract.", default=None) parser.add_argument("--contract", help="Flatten one contract.", default=None)
@ -44,27 +47,28 @@ def parse_args() -> argparse.Namespace:
"--dir", "--dir",
help=f"Export directory (default: {DEFAULT_EXPORT_PATH}).", help=f"Export directory (default: {DEFAULT_EXPORT_PATH}).",
default=None, default=None,
) ).complete = shtab.DIRECTORY
group_export.add_argument( group_export.add_argument(
"--json", "--json",
help='Export the results as a JSON file ("--json -" to export to stdout)', help='Export the results as a JSON file ("--json -" to export to stdout)',
action="store", action="store",
default=None, default=None,
) ).complete = shtab.FILE
parser.add_argument( parser.add_argument(
"--zip", "--zip",
help="Export all the files to a zip file", help="Export all the files to a zip file",
action="store", action="store",
default=None, default=None,
) ).complete = shtab.FILE
parser.add_argument( parser.add_argument(
"--zip-type", "--zip-type",
help=f"Zip compression type. One of {','.join(ZIP_TYPES_ACCEPTED.keys())}. Default lzma", help=f"Zip compression type. One of {','.join(ZIP_TYPES_ACCEPTED.keys())}. Default lzma",
action="store", action="store",
default=None, default=None,
choices=list(ZIP_TYPES_ACCEPTED.keys()),
) )
group_patching = parser.add_argument_group("Patching options") group_patching = parser.add_argument_group("Patching options")

@ -3,6 +3,7 @@ import logging
from pathlib import Path from pathlib import Path
from crytic_compile import cryticparser from crytic_compile import cryticparser
import shtab
from slither import Slither from slither import Slither
from slither.utils.code_generation import generate_interface from slither.utils.code_generation import generate_interface
@ -22,6 +23,8 @@ def parse_args() -> argparse.Namespace:
usage=("slither-interface <ContractName> <source file or deployment address>"), usage=("slither-interface <ContractName> <source file or deployment address>"),
) )
shtab.add_argument_to(parser)
parser.add_argument( parser.add_argument(
"contract_source", "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.", 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.",

@ -2,6 +2,7 @@ import sys
import logging import logging
import argparse import argparse
from crytic_compile import cryticparser from crytic_compile import cryticparser
import shtab
from slither.tools.kspec_coverage.kspec_coverage import kspec_coverage from slither.tools.kspec_coverage.kspec_coverage import kspec_coverage
logging.basicConfig() logging.basicConfig()
@ -26,6 +27,8 @@ def parse_args() -> argparse.Namespace:
usage="slither-kspec-coverage contract.sol kspec.md", usage="slither-kspec-coverage contract.sol kspec.md",
) )
shtab.add_argument_to(parser)
parser.add_argument( parser.add_argument(
"contract", help="The filename of the contract or truffle directory to analyze." "contract", help="The filename of the contract or truffle directory to analyze."
) )
@ -45,7 +48,7 @@ def parse_args() -> argparse.Namespace:
help='Export the results as a JSON file ("--json -" to export to stdout)', help='Export the results as a JSON file ("--json -" to export to stdout)',
action="store", action="store",
default=False, default=False,
) ).complete = shtab.FILE
cryticparser.init(parser) cryticparser.init(parser)

@ -6,6 +6,7 @@ import os
import shutil import shutil
from typing import Type, List, Any, Optional from typing import Type, List, Any, Optional
from crytic_compile import cryticparser from crytic_compile import cryticparser
import shtab
from slither import Slither from slither import Slither
from slither.tools.mutator.mutators import all_mutators from slither.tools.mutator.mutators import all_mutators
from slither.utils.colors import yellow, magenta from slither.utils.colors import yellow, magenta
@ -38,6 +39,8 @@ def parse_args() -> argparse.Namespace:
usage="slither-mutate <codebase> --test-cmd <test command> <options>", 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("codebase", help="Codebase to analyze (.sol file, project directory, ...)")
parser.add_argument( parser.add_argument(
@ -63,7 +66,7 @@ def parse_args() -> argparse.Namespace:
# output directory argument # output directory argument
parser.add_argument( parser.add_argument(
"--output-dir", help="Name of output directory (by default 'mutation_campaign')" "--output-dir", help="Name of output directory (by default 'mutation_campaign')"
) ).complete = shtab.DIRECTORY
# to print just all the mutants # to print just all the mutants
parser.add_argument( parser.add_argument(

@ -4,6 +4,7 @@ import logging
from argparse import ArgumentParser, Namespace from argparse import ArgumentParser, Namespace
from crytic_compile import cryticparser from crytic_compile import cryticparser
import shtab
from slither import Slither from slither import Slither
from slither.core.declarations import FunctionContract from slither.core.declarations import FunctionContract
from slither.utils.colors import red from slither.utils.colors import red
@ -27,6 +28,8 @@ def parse_args() -> Namespace:
usage="possible_paths.py filename [contract.function targets]", usage="possible_paths.py filename [contract.function targets]",
) )
shtab.add_argument_to(parser)
parser.add_argument( parser.add_argument(
"filename", help="The filename of the contract or truffle directory to analyze." "filename", help="The filename of the contract or truffle directory to analyze."
) )

@ -4,6 +4,7 @@ import sys
from typing import Any from typing import Any
from crytic_compile import cryticparser from crytic_compile import cryticparser
import shtab
from slither import Slither from slither import Slither
from slither.tools.properties.properties.erc20 import generate_erc20, ERC20_PROPERTIES from slither.tools.properties.properties.erc20 import generate_erc20, ERC20_PROPERTIES
@ -73,6 +74,8 @@ def parse_args() -> argparse.Namespace:
formatter_class=argparse.RawDescriptionHelpFormatter, formatter_class=argparse.RawDescriptionHelpFormatter,
) )
shtab.add_argument_to(parser)
parser.add_argument( parser.add_argument(
"filename", help="The filename of the contract or project directory to analyze." "filename", help="The filename of the contract or project directory to analyze."
) )

@ -5,6 +5,7 @@ import json
import argparse import argparse
from crytic_compile import cryticparser from crytic_compile import cryticparser
import shtab
from slither import Slither from slither import Slither
from slither.exceptions import SlitherError from slither.exceptions import SlitherError
@ -29,6 +30,8 @@ def parse_args() -> argparse.Namespace:
), ),
) )
shtab.add_argument_to(parser)
parser.add_argument( parser.add_argument(
"contract_source", "contract_source",
help="The deployed contract address if verified on etherscan. Prepend project directory for unverified contracts.", help="The deployed contract address if verified on etherscan. Prepend project directory for unverified contracts.",
@ -77,7 +80,7 @@ def parse_args() -> argparse.Namespace:
"--json", "--json",
action="store", action="store",
help="Save the result in a JSON file.", help="Save the result in a JSON file.",
) ).complete = shtab.FILE
parser.add_argument( parser.add_argument(
"--value", "--value",

@ -5,6 +5,7 @@ import logging
import sys import sys
from crytic_compile import cryticparser from crytic_compile import cryticparser
import shtab
from slither.tools.similarity.info import info from slither.tools.similarity.info import info
from slither.tools.similarity.test import test from slither.tools.similarity.test import test
@ -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" 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("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") parser.add_argument("--fname", action="store", dest="fname", help="Target function")
@ -51,7 +56,7 @@ def parse_args() -> argparse.Namespace:
parser.add_argument( parser.add_argument(
"--input", action="store", dest="input", help="File or directory used as input" "--input", action="store", dest="input", help="File or directory used as input"
) ).complete = shtab.FILE
parser.add_argument( parser.add_argument(
"--version", "--version",

@ -2,6 +2,7 @@ import sys
import argparse import argparse
import logging import logging
from crytic_compile import cryticparser from crytic_compile import cryticparser
import shtab
from slither import Slither from slither import Slither
from slither.utils.command_line import read_config_file from slither.utils.command_line import read_config_file
from slither.tools.slither_format.slither_format import slither_format from slither.tools.slither_format.slither_format import slither_format
@ -30,6 +31,8 @@ def parse_args() -> argparse.Namespace:
""" """
parser = argparse.ArgumentParser(description="slither_format", usage="slither_format filename") parser = argparse.ArgumentParser(description="slither_format", usage="slither_format filename")
shtab.add_argument_to(parser)
parser.add_argument( parser.add_argument(
"filename", help="The filename of the contract or truffle directory to analyze." "filename", help="The filename of the contract or truffle directory to analyze."
) )
@ -60,7 +63,7 @@ def parse_args() -> argparse.Namespace:
action="store", action="store",
dest="config_file", dest="config_file",
default="slither.config.json", default="slither.config.json",
) ).complete = shtab.FILE
group_detector = parser.add_argument_group("Detectors") group_detector = parser.add_argument_group("Detectors")
group_detector.add_argument( group_detector.add_argument(

@ -6,6 +6,7 @@ import sys
from typing import List, Any, Type, Dict, Tuple, Union, Sequence, Optional from typing import List, Any, Type, Dict, Tuple, Union, Sequence, Optional
from crytic_compile import cryticparser from crytic_compile import cryticparser
import shtab
from slither import Slither from slither import Slither
@ -36,6 +37,8 @@ def parse_args(check_classes: List[Type[AbstractCheck]]) -> argparse.Namespace:
usage="slither-check-upgradeability contract.sol ContractName", usage="slither-check-upgradeability contract.sol ContractName",
) )
shtab.add_argument_to(parser)
group_checks = parser.add_argument_group("Checks") group_checks = parser.add_argument_group("Checks")
parser.add_argument("contract.sol", help="Codebase to analyze") parser.add_argument("contract.sol", help="Codebase to analyze")
@ -47,14 +50,14 @@ def parse_args(check_classes: List[Type[AbstractCheck]]) -> argparse.Namespace:
parser.add_argument("--new-contract-name", help="New contract name (if changed)") parser.add_argument("--new-contract-name", help="New contract name (if changed)")
parser.add_argument( parser.add_argument(
"--new-contract-filename", help="New implementation filename (if different)" "--new-contract-filename", help="New implementation filename (if different)"
) ).complete = shtab.FILE
parser.add_argument( parser.add_argument(
"--json", "--json",
help='Export the results as a JSON file ("--json -" to export to stdout)', help='Export the results as a JSON file ("--json -" to export to stdout)',
action="store", action="store",
default=False, default=False,
) ).complete = shtab.FILE
group_checks.add_argument( group_checks.add_argument(
"--detect", "--detect",

Loading…
Cancel
Save