def integration(): """Fixture for hassfest integration model.""" integration = Integration("") integration.manifest = { "domain": "test", "documentation": "https://example.com", "name": "test", "codeowners": ["@awesome"], } return integration
def gather_recursive_requirements(domain, seen=None): """Recursively gather requirements from a module.""" if seen is None: seen = set() seen.add(domain) integration = Integration(Path(f"homeassistant/components/{domain}")) integration.load_manifest() reqs = set(integration.manifest["requirements"]) for dep_domain in integration.manifest["dependencies"]: reqs.update(gather_recursive_requirements(dep_domain, seen)) return reqs
def gather_recursive_requirements(domain, seen=None): """Recursively gather requirements from a module.""" if seen is None: seen = set() seen.add(domain) integration = Integration(Path(f"homeassistant/components/{domain}")) integration.load_manifest() reqs = {x for x in integration.requirements if x not in CONSTRAINT_BASE} for dep_domain in integration.dependencies: reqs.update(gather_recursive_requirements(dep_domain, seen)) return reqs
def gather_recursive_requirements(domain, seen=None): """Recursively gather requirements from a module.""" if seen is None: seen = set() seen.add(domain) integration = Integration( pathlib.Path('homeassistant/components/{}'.format(domain))) integration.load_manifest() reqs = set(integration.manifest['requirements']) for dep_domain in integration.manifest['dependencies']: reqs.update(gather_recursive_requirements(dep_domain, seen)) return reqs
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", "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
def test_validate_custom_integration_manifest(integration: Integration): """Test validate custom integration manifest.""" with pytest.raises(vol.Invalid): integration.manifest["version"] = "lorem_ipsum" CUSTOM_INTEGRATION_MANIFEST_SCHEMA(integration.manifest) with pytest.raises(vol.Invalid): integration.manifest["version"] = None CUSTOM_INTEGRATION_MANIFEST_SCHEMA(integration.manifest) integration.manifest["version"] = "1" schema = CUSTOM_INTEGRATION_MANIFEST_SCHEMA(integration.manifest) assert schema["version"] == "1"
def parse_components(version: str = "master"): components = {} components_with_tests = [] with tempfile.TemporaryDirectory() as tmp: with urlopen( f"https://github.com/home-assistant/home-assistant/archive/{version}.tar.gz" ) as response: tarfile.open(fileobj=BytesIO(response.read())).extractall(tmp) # Use part of a script from the Home Assistant codebase core_path = os.path.join(tmp, f"core-{version}") for entry in os.scandir(os.path.join(core_path, "tests/components")): if entry.is_dir(): components_with_tests.append(entry.name) sys.path.append(core_path) from script.hassfest.model import Integration integrations = Integration.load_dir( pathlib.Path( os.path.join(core_path, "homeassistant/components") ) ) for domain in sorted(integrations): integration = integrations[domain] if not integration.disabled: components[domain] = integration.manifest return components, components_with_tests
def test_validate_requirements_format_wrongly_pinned(integration: Integration): """Test requirement with loose pin.""" integration.manifest["requirements"] = ["test_package>=1"] assert not validate_requirements_format(integration) assert len(integration.errors) == 1 assert 'Requirement test_package>=1 need to be pinned "<pkg name>==<version>".' in [ x.error for x in integration.errors ]
def test_validate_requirements_format_with_space(integration: Integration): """Test validate requirement with space around separator.""" integration.manifest["requirements"] = ["test_package == 1"] assert not validate_requirements_format(integration) assert len(integration.errors) == 1 assert 'Requirement "test_package == 1" contains a space' in [ x.error for x in integration.errors ]
def test_validate_requirements_format_successful(integration: Integration): """Test requirement with successful result.""" integration.manifest["requirements"] = [ "test_package==1.2.3", "test_package[async]==1.2.3", ] assert validate_requirements_format(integration) assert len(integration.errors) == 0
def test_validate_requirements_format_invalid_version(integration: Integration): """Test requirement with invalid version.""" integration.manifest["requirements"] = ["test_package==invalid"] assert not validate_requirements_format(integration) assert len(integration.errors) == 1 assert "Unable to parse package version (invalid) for test_package." in [ x.error for x in integration.errors ]
def gather_requirements_from_manifests(errors, reqs): """Gather all of the requirements from manifests.""" integrations = Integration.load_dir(Path("homeassistant/components")) for domain in sorted(integrations): integration = integrations[domain] if not integration.manifest: errors.append(f"The manifest for integration {domain} is invalid.") continue process_requirements(errors, integration.requirements, f"homeassistant.components.{domain}", reqs)
def integration(): """Fixture for hassfest integration model.""" integration = Integration( path=Path("homeassistant/components/test"), manifest={ "domain": "test", "documentation": "https://example.com", "name": "test", "codeowners": ["@awesome"], "requirements": [], }, ) yield integration
def gather_requirements_from_manifests(errors, reqs): """Gather all of the requirements from manifests.""" integrations = Integration.load_dir( pathlib.Path('homeassistant/components')) for domain in sorted(integrations): integration = integrations[domain] if not integration.manifest: errors.append( 'The manifest for integration {} is invalid.'.format(domain)) continue process_requirements(errors, integration.manifest['requirements'], 'homeassistant.components.{}'.format(domain), reqs)
def parse_components(version='master'): components = {} with tempfile.TemporaryDirectory() as tmp: with urlopen(f'https://github.com/home-assistant/home-assistant/archive/{version}.tar.gz') as response: tarfile.open(fileobj=BytesIO(response.read())).extractall(tmp) # Use part of a script from the Home Assistant codebase sys.path.append(os.path.join(tmp, f'home-assistant-{version}')) from script.hassfest.model import Integration integrations = Integration.load_dir(pathlib.Path( os.path.join(tmp, f'home-assistant-{version}', 'homeassistant/components') )) for domain in sorted(integrations): integration = integrations[domain] components[domain] = integration.manifest return components
def parse_components(version='master'): components = {} with tempfile.TemporaryDirectory() as tmp: with urlopen( f'https://github.com/home-assistant/home-assistant/archive/{version}.tar.gz' ) as response: tarfile.open(fileobj=BytesIO(response.read())).extractall(tmp) # Use part of a script from the Home Assistant codebase sys.path.append(os.path.join(tmp, f'home-assistant-{version}')) from script.hassfest.model import Integration integrations = Integration.load_dir( pathlib.Path( os.path.join(tmp, f'home-assistant-{version}', 'homeassistant/components'))) for domain in sorted(integrations): integration = integrations[domain] components[domain] = integration.manifest return components
def test_validate_requirements_format_ignore_pin_for_custom(integration: Integration): """Test requirement ignore pinning for custom.""" integration.manifest["requirements"] = ["test_package>=1"] integration.path = Path("") assert validate_requirements_format(integration) assert len(integration.errors) == 0