diff --git a/click_config_file.py b/click_config_file.py index 6236801..aa4287e 100755 --- a/click_config_file.py +++ b/click_config_file.py @@ -90,6 +90,19 @@ def configuration_callback(cmd_name, option_name, config_file_name, except Exception as e: raise click.BadOptionUsage(option_name, "Error reading configuration file: {}".format(e), ctx) + + valid_params = [ + p.name for p in ctx.command.params if p.name != option_name + ] + specified_params = list(config.keys()) + unknown_params = set(specified_params).difference(set(valid_params)) + + if unknown_params: + raise click.BadParameter( + f'Invalid configuration file, the following keys are not ' + f'supported: {unknown_params}', ctx, param + ) + ctx.default_map.update(config) return saved_callback(ctx, param, value) if saved_callback else value diff --git a/tests/test_configuration_option_explicit.py b/tests/test_configuration_option_explicit.py index d453d9b..dd7d27f 100644 --- a/tests/test_configuration_option_explicit.py +++ b/tests/test_configuration_option_explicit.py @@ -31,13 +31,14 @@ def cli(config): def test_custom_default_value(runner, cfgfile): @click.command() + @click.option('--who') @configuration_option(implicit=False, default=str(cfgfile), expose_value=True) - def cli(config): + def cli(who, config): assert config == str(cfgfile) click.echo(config) result = runner.invoke(cli) - assert not result.exception + assert not result.exception, result.output assert result.output == ''.join(( str(cfgfile.realpath()), '\n', @@ -60,9 +61,10 @@ def cli(who): def test_config_value_no_replacement(runner, cfgfile): """Test that config does not replace variable of other name.""" @click.command() + @click.option('--who') @click.option('--whom', default='World', envvar='CLICK_TEST_WHO') @configuration_option(implicit=False) - def cli(whom): + def cli(who, whom): assert whom == "World" click.echo("Hello {}".format(whom)) @@ -73,6 +75,7 @@ def cli(whom): assert not result.exception assert result.output == 'Hello World\n' + def test_broken_config(runner, tmpdir): @click.command() @configuration_option(implicit=False) @@ -92,6 +95,25 @@ def cli(): assert result.exit_code != 0 +def test_config_unknown_parameters(runner, cfgfile): + """Test that the command fails if the configuration file contains unknown parameters.""" + @click.command() + @configuration_option(implicit=False) + def cli(): + pass + + result = runner.invoke(cli, ( + '--config', + str(cfgfile), + )) + assert re.search( + r"Invalid configuration file, the following keys are not supported: {'who'}", + result.output + ) is not None + assert result.exception + assert result.exit_code != 0 + + def test_config_precedence_override_default(runner, cfgfile): @click.command()