Repository: kedro-org/kedro
File: kedro/framework/cli/starters.py (Python)

Code before:
def _validate_config_file_inputs(config: dict[str, str]):
    """Checks that variables provided through the config file are of the expected format. This
    validate the config provided by `kedro new --config` in a similar way to `prompts.yml`
    for starters.

    Args:
        config: The config as a dictionary

    Raises:
        SystemExit: If the provided variables are not properly formatted.
    """
    project_name_validation_config = {
        "regex_validator": r"^[\w -]{2,}$",
        "error_message": "'{input_project_name}' is an invalid value for project name. It must contain only alphanumeric symbols, spaces, underscores and hyphens and be at least 2 characters long",
    }

    input_project_name = config.get("project_name", "New Kedro Project")
    if not re.match(
        project_name_validation_config["regex_validator"], input_project_name
    ):
        click.secho(project_name_validation_config["error_message"], fg="red", err=True)
        sys.exit(1)

    input_tools = config.get("tools", "none")
    tools_validation_config = {
        "regex_validator": r"^(all|none|(( )*(\d*|\d( )?-( )?\d)(( )*,( )*(\d*|\d( )?-( )?\d))*( )*))$",
        "error_message": f"'{input_tools}' is an invalid value for project tools. Please select valid options for tools using comma-separated values, ranges, or 'all/none'.",
    }

    if not re.match(tools_validation_config["regex_validator"], input_tools.lower()):
        message = tools_validation_config["error_message"]
        click.secho(message, fg="red", err=True)
        sys.exit(1)

    selected_tools = _parse_tools_input(input_tools)
    _validate_selection(selected_tools)
    _validate_regex("yes_no", config.get("example_pipeline", "no"))


def _validate_selection(tools: list[str]):
    # start validating from the end, when user select 1-20, it will generate a message
    # '20' is not a valid selection instead of '8'
    for tool in tools[::-1]:
        if tool not in NUMBER_TO_TOOLS_NAME:
            message = f"'{tool}' is not a valid selection.\nPlease select from the available tools: 1, 2, 3, 4, 5, 6, 7."  # nosec
            click.secho(message, fg="red", err=True)
            sys.exit(1)


def _parse_tools_input(tools_str: str):
    """Parse the tools input string.

Review comment (suggestion):
You wrote a good explanation of the regex in the PR - can you actually include it here? Using `re.VERBOSE`:

https://docs.python.org/3/library/re.html#re.VERBOSE



Code after:
        )


def _validate_config_file_inputs(config: dict[str, str]):
    """Checks that variables provided through the config file are of the expected format. This
    validate the config provided by `kedro new --config` in a similar way to `prompts.yml`
    for starters.

    Args:
        config: The config as a dictionary

    Raises:
        SystemExit: If the provided variables are not properly formatted.
    """
    project_name_validation_config = {
        "regex_validator": r"^[\w -]{2,}$",
        "error_message": "'{input_project_name}' is an invalid value for project name. It must contain only alphanumeric symbols, spaces, underscores and hyphens and be at least 2 characters long",
    }

    input_project_name = config.get("project_name", "New Kedro Project")
    if not re.match(
        project_name_validation_config["regex_validator"], input_project_name
    ):
        click.secho(project_name_validation_config["error_message"], fg="red", err=True)
        sys.exit(1)

    input_tools = config.get("tools", "none")
    tools_validation_config = {
        "regex_validator": r"""^(
            all|none|                        # A: "all" or "none" or
            (\ *\d+                          # B: any number of spaces followed by one or more digits
            (\ *-\ *\d+)?                    # C: zero or one instances of: a hyphen followed by one or more digits, spaces allowed
            (\ *,\ *\d+(\ *-\ *\d+)?)*       # D: any number of instances of: a comma followed by B and C, spaces allowed
            \ *)?)                           # E: zero or one instances of (B,C,D) as empty strings are also permissible
            $""",
        "error_message": f"'{input_tools}' is an invalid value for project tools. Please select valid options for tools using comma-separated values, ranges, or 'all/none'.",
    }

    if not re.match(
        tools_validation_config["regex_validator"], input_tools.lower(), flags=re.X
    ):
        message = tools_validation_config["error_message"]
        click.secho(message, fg="red", err=True)
        sys.exit(1)

    selected_tools = _parse_tools_input(input_tools)
    _validate_selection(selected_tools)
    _validate_regex("yes_no", config.get("example_pipeline", "no"))


def _validate_selection(tools: list[str]):