diff --git a/script/hassfest/requirements.py b/script/hassfest/requirements.py index 26cb834e4e2..2da82762240 100644 --- a/script/hassfest/requirements.py +++ b/script/hassfest/requirements.py @@ -26,6 +26,7 @@ PACKAGE_REGEX = re.compile( r"^(?:--.+\s)?([-_\.\w\d\[\]]+)(==|>=|<=|~=|!=|<|>|===)*(.*)$" ) PIP_REGEX = re.compile(r"^(--.+\s)?([-_\.\w\d]+.*(?:==|>=|<=|~=|!=|<|>|===)?.*$)") +PIP_VERSION_RANGE_SEPARATOR = re.compile(r"^(==|>=|<=|~=|!=|<|>|===)?(.*)$") SUPPORTED_PYTHON_TUPLES = [ REQUIRED_PYTHON_VER[:2], tuple(map(operator.add, REQUIRED_PYTHON_VER, (0, 1, 0)))[:2], @@ -95,16 +96,22 @@ def validate_requirements_format(integration: Integration) -> bool: ) continue - if ( - version - and AwesomeVersion(version).strategy == AwesomeVersionStrategy.UNKNOWN - ): - integration.add_error( - "requirements", - f"Unable to parse package version ({version}) for {pkg}.", - ) + if not version: continue + for part in version.split(","): + version_part = PIP_VERSION_RANGE_SEPARATOR.match(part) + if ( + version_part + and AwesomeVersion(version_part.group(2)).strategy + == AwesomeVersionStrategy.UNKNOWN + ): + integration.add_error( + "requirements", + f"Unable to parse package version ({version}) for {pkg}.", + ) + continue + return len(integration.errors) == start_errors diff --git a/tests/hassfest/test_requirements.py b/tests/hassfest/test_requirements.py index 079e77f909b..91496b7fa6f 100644 --- a/tests/hassfest/test_requirements.py +++ b/tests/hassfest/test_requirements.py @@ -45,7 +45,14 @@ def test_validate_requirements_format_wrongly_pinned(integration: Integration): def test_validate_requirements_format_ignore_pin_for_custom(integration: Integration): """Test requirement ignore pinning for custom.""" - integration.manifest["requirements"] = ["test_package>=1", "test_package"] + integration.manifest["requirements"] = [ + "test_package>=1", + "test_package", + "test_package>=1.2.3,<3.2.1", + "test_package~=0.5.0", + "test_package>=1.4.2,<1.4.99,>=1.7,<1.8.99", + "test_package>=1.4.2,<1.9,!=1.5", + ] integration.path = Path("") assert validate_requirements_format(integration) assert len(integration.errors) == 0