diff --git a/swh/scanner/cli.py b/swh/scanner/cli.py --- a/swh/scanner/cli.py +++ b/swh/scanner/cli.py @@ -15,10 +15,8 @@ from swh.core.cli import swh as swh_cli_group # All generic config code should reside in swh.core.config -DEFAULT_CONFIG_PATH = os.environ.get( - "SWH_CONFIG_FILE", os.path.join(click.get_app_dir("swh"), "global.yml") -) - +CONFIG_ENVVAR = "SWH_CONFIG_FILE" +DEFAULT_CONFIG_PATH = os.path.join(click.get_app_dir("swh"), "global.yml") DEFAULT_CONFIG: Dict[str, Any] = { "web-api": { @@ -52,15 +50,26 @@ @click.pass_context def scanner(ctx, config_file: Optional[str]): """Software Heritage Scanner tools.""" - if config_file is None and config.config_exists(DEFAULT_CONFIG_PATH): - config_file = DEFAULT_CONFIG_PATH - - if config_file is None: - conf = DEFAULT_CONFIG - else: + env_path = os.environ.get("SWH_CONFIG_FILE") + def_path = DEFAULT_CONFIG_PATH + + # for now assuming files do not change while running + if config_file and not config.config_exists(config_file): + raise FileNotFoundError(config_file) + elif env_path and not config.config_exists(env_path): + raise FileNotFoundError(env_path) + elif config_file or env_path or config.config_exists(def_path): + config_file = config_file or env_path or def_path + # config_file = ( + # config_file if config_file + # else env_path if env_path + # else def_path if config.config_exists(def_path) + # else None + # ) + + conf = DEFAULT_CONFIG + if config_file is not None: # read_raw_config do not fail on ENOENT - if not config.config_exists(config_file): - raise FileNotFoundError(config_file) conf = config.read_raw_config(config.config_basepath(config_file)) conf = config.merge_configs(DEFAULT_CONFIG, conf) diff --git a/swh/scanner/tests/test_cli.py b/swh/scanner/tests/test_cli.py new file mode 100644 --- /dev/null +++ b/swh/scanner/tests/test_cli.py @@ -0,0 +1,83 @@ +# Copyright (C) 2020 The Software Heritage developers +# See the AUTHORS file at the top-level directory of this distribution +# License: GNU General Public License version 3, or any later version +# See top-level LICENSE file for more information + +from os.path import expanduser + +from click.testing import CliRunner +import pytest + +from swh.scanner.cli import scanner + + +@pytest.fixture +def cli_runner() -> CliRunner: + return CliRunner() + + +@pytest.fixture +def rootpath_good() -> str: + return "/usr/lib/python3/dist-packages/urllib3" + + +@pytest.fixture +def rootpath_bad() -> str: + return "~" + + +@pytest.fixture +def confpath_good() -> str: + return expanduser("~/.config/swh/global.yml") + + +@pytest.fixture +def confpath_bad() -> str: + return "~" + + +def test_smoke(cli_runner): + cli_runner.invoke(scanner, ["-h"]) + + +# TODO For nominal code paths, check that the right config file is loaded with a mock +def test_root_path_good(cli_runner, rootpath_good): + # test no option no envvar no default + # how to make sure the default file does not exist? + res = cli_runner.invoke(scanner, ["scan", rootpath_good]) + assert res.exit_code == 0 + + +def test_root_path_bad(cli_runner, rootpath_bad): + res = cli_runner.invoke(scanner, ["scan", rootpath_bad]) + print(res.__dict__) + assert res.exit_code == 2 + + +def test_config_path_option_bad(cli_runner, confpath_bad, rootpath_good): + res = cli_runner.invoke(scanner, ["-C", confpath_bad, "scan", rootpath_good]) + print(res.__dict__) + assert res.exception.__class__ == FileNotFoundError + + +def test_config_path_envvar_good(cli_runner, confpath_good, rootpath_good, monkeypatch): + monkeypatch.setenv("SWH_CONFIG_FILE", confpath_good) + res = cli_runner.invoke(scanner, ["scan", rootpath_good]) + assert res.exit_code == 0 + + +def test_config_path_envvar_bad(cli_runner, confpath_bad, rootpath_good, monkeypatch): + monkeypatch.setenv("SWH_CONFIG_FILE", confpath_bad) + res = cli_runner.invoke(scanner, ["scan", rootpath_good]) + print(res.__dict__) + assert res.exception.__class__ == FileNotFoundError + + +def test_config_path_option_envvar( + cli_runner, confpath_good, rootpath_good, monkeypatch +): + monkeypatch.setenv("SWH_CONFIG_FILE", confpath_good) + res = cli_runner.invoke(scanner, ["-C", confpath_good, "scan", rootpath_good]) + print(res.__dict__) + assert res.exit_code == 0 + # TODO Check that option has precedence over envvar