diff --git a/kedro/framework/cli/starters.py b/kedro/framework/cli/starters.py index 6ea3803fbb..9a5291f22c 100644 --- a/kedro/framework/cli/starters.py +++ b/kedro/framework/cli/starters.py @@ -568,5 +568,4 @@ def _validate_config_file(config: dict[str, str], prompts: dict[str, Any]): selected_add_ons = config["add_ons"] if not re.match(add_on_reg_ex, selected_add_ons): message = f"'{selected_add_ons}' is an invalid value for project add-ons. Please select valid options for add-ons using comma-separated values, ranges, or 'all/none'." - click.secho(message, fg="red", err=True) - raise ValueError(message) + raise ValueError(message).with_traceback(None) diff --git a/kedro/templates/project/hooks/utils.py b/kedro/templates/project/hooks/utils.py index 488d1bd216..15295759c5 100644 --- a/kedro/templates/project/hooks/utils.py +++ b/kedro/templates/project/hooks/utils.py @@ -1,6 +1,5 @@ from pathlib import Path import shutil -import click current_dir = Path.cwd() @@ -47,6 +46,17 @@ ] """ +def _validate_range(start, end): + if int(start) > int(end): + message = f"'{start}-{end}' is an invalid range for project add-ons." + raise ValueError(message).with_traceback(None) + +def _validate_selection(add_ons): + for add_on in add_ons: + if int(add_on) < 1 or int(add_on) > 5: + message = f"'{add_on}' is not a valid selection." + raise ValueError(message).with_traceback(None) + def parse_add_ons_input(add_ons_str): """Parse the add-ons input string. @@ -69,14 +79,12 @@ def parse_add_ons_input(add_ons_str): for choice in add_ons_choices: if "-" in choice: start, end = choice.split("-") - if int(start) > int(end): - message = f"'{add_ons_str}' is an invalid range for Project Add-Ons." - click.secho(message, fg="red", err=True) - raise ValueError(message) + _validate_range(start, end) selected.extend(str(i) for i in range(int(start), int(end) + 1)) else: selected.append(choice.strip()) + _validate_selection(selected) return selected diff --git a/tests/framework/cli/test_starters.py b/tests/framework/cli/test_starters.py index 13e21fb3ab..2ae1ad52cb 100644 --- a/tests/framework/cli/test_starters.py +++ b/tests/framework/cli/test_starters.py @@ -264,10 +264,19 @@ def test_parse_add_ons_valid(input, expected): ["5-2", "3-1"], ) def test_parse_add_ons_invalid_range(input): + with pytest.raises(ValueError) as excinfo: + parse_add_ons_input(input) + assert str(excinfo.value) == f"'{input}' is an invalid range for project add-ons." + +@pytest.mark.parametrize( + "input,first_invalid", + [("0,3,5", "0"), ("1,3,6", "6"), ("0-4", "0"), ("3-6", "6")], +) +def test_parse_add_ons_invalid_selection(input, first_invalid): with pytest.raises(ValueError) as excinfo: parse_add_ons_input(input) - assert str(excinfo.value) == f"'{input}' is an invalid range for Project Add-Ons." + assert str(excinfo.value) == f"'{first_invalid}' is not a valid selection." @pytest.mark.usefixtures("chdir_to_tmp") @@ -860,8 +869,8 @@ def test_invalid_add_ons(self, fake_kedro_cli): ) assert result.exit_code != 0 - assert "is an invalid value for project add-ons." in result.output + assert "is an invalid value for project add-ons." in str(result.exc_info) assert ( - "Please select valid options for add-ons using comma-separated values, ranges, or 'all/none'.\n" - in result.output + "Please select valid options for add-ons using comma-separated values, ranges, or 'all/none'." + in str(result.exc_info) )