diff --git a/docs/src/Usage.md b/docs/src/Usage.md index 7b9738362d..a2d13af3a9 100644 --- a/docs/src/Usage.md +++ b/docs/src/Usage.md @@ -122,7 +122,7 @@ To show the hidden results again, delete `slither.db.json`. ### Configuration File -Some options can be set through a json configuration file. By default, `slither.config.json` is used if present (it can be changed through `--config-file file.config.json`). +Some options can be set through a json configuration file. By default, `slither.config.json` is used if present, with `slither.conf.json` accepted as an alternative (it can be changed through `--config-file file.config.json`). Options passed via the CLI have priority over options set in the configuration file. diff --git a/slither/__main__.py b/slither/__main__.py index db0c543f05..172c11395b 100644 --- a/slither/__main__.py +++ b/slither/__main__.py @@ -608,7 +608,7 @@ def parse_args( group_misc.add_argument( "--config-file", - help="Provide a config file (default: slither.config.json)", + help="Provide a config file (default: slither.config.json or slither.conf.json)", action="store", dest="config_file", default=None, diff --git a/slither/tools/slither_format/__main__.py b/slither/tools/slither_format/__main__.py index 85c0a3917f..177154673b 100644 --- a/slither/tools/slither_format/__main__.py +++ b/slither/tools/slither_format/__main__.py @@ -56,10 +56,10 @@ def parse_args() -> argparse.Namespace: parser.add_argument( "--config-file", - help="Provide a config file (default: slither.config.json)", + help="Provide a config file (default: slither.config.json or slither.conf.json)", action="store", dest="config_file", - default="slither.config.json", + default=None, ) group_detector = parser.add_argument_group("Detectors") diff --git a/slither/utils/command_line.py b/slither/utils/command_line.py index 3242e3aeb1..642889c527 100644 --- a/slither/utils/command_line.py +++ b/slither/utils/command_line.py @@ -79,13 +79,17 @@ class FailOnLevel(enum.Enum): } +DEFAULT_CONFIG_FILENAMES = ("slither.config.json", "slither.conf.json") + + def read_config_file(args: argparse.Namespace) -> None: # No config file was provided as an argument if args.config_file is None: - # Check whether the default config file is present - if os.path.exists("slither.config.json"): - # The default file exists, use it - args.config_file = "slither.config.json" + # Check whether a default config file is present + for candidate in DEFAULT_CONFIG_FILENAMES: + if os.path.exists(candidate): + args.config_file = candidate + break else: return diff --git a/tests/unit/utils/test_command_line.py b/tests/unit/utils/test_command_line.py new file mode 100644 index 0000000000..bb05e3e007 --- /dev/null +++ b/tests/unit/utils/test_command_line.py @@ -0,0 +1,54 @@ +"""Tests for slither/utils/command_line.py""" + +import argparse +import json +import os + +import pytest + +from slither.utils.command_line import DEFAULT_CONFIG_FILENAMES, read_config_file + + +@pytest.fixture +def in_tmp_cwd(tmp_path, monkeypatch): + monkeypatch.chdir(tmp_path) + return tmp_path + + +def _write_json(path, data): + path.write_text(json.dumps(data)) + + +def test_read_config_file_autodetects_config_json(in_tmp_cwd): + _write_json(in_tmp_cwd / "slither.config.json", {"exclude_low": True}) + args = argparse.Namespace(config_file=None, exclude_low=False) + read_config_file(args) + assert args.config_file == "slither.config.json" + assert args.exclude_low is True + + +def test_read_config_file_autodetects_conf_json(in_tmp_cwd): + _write_json(in_tmp_cwd / "slither.conf.json", {"exclude_low": True}) + args = argparse.Namespace(config_file=None, exclude_low=False) + read_config_file(args) + assert args.config_file == "slither.conf.json" + assert args.exclude_low is True + + +def test_read_config_file_prefers_config_over_conf(in_tmp_cwd): + _write_json(in_tmp_cwd / "slither.config.json", {"exclude_low": True}) + _write_json(in_tmp_cwd / "slither.conf.json", {"exclude_low": False}) + args = argparse.Namespace(config_file=None, exclude_low=False) + read_config_file(args) + assert args.config_file == "slither.config.json" + assert args.exclude_low is True + + +def test_read_config_file_no_default_present(in_tmp_cwd): + args = argparse.Namespace(config_file=None) + read_config_file(args) + assert args.config_file is None + + +def test_default_filenames_constant(): + assert DEFAULT_CONFIG_FILENAMES == ("slither.config.json", "slither.conf.json")