From 28281523ec6501bdbf126a32ad95ead90374b768 Mon Sep 17 00:00:00 2001 From: Jan-Philipp Benecke Date: Tue, 16 Jan 2024 09:47:53 +0100 Subject: [PATCH] Add pylint plugin to check for sorted platforms list (#108115) --- homeassistant/components/abode/__init__.py | 6 +- .../components/advantage_air/__init__.py | 2 +- .../components/alarmdecoder/__init__.py | 2 +- .../components/amberelectric/const.py | 2 +- homeassistant/components/atag/__init__.py | 2 +- homeassistant/components/august/const.py | 2 +- homeassistant/components/bloomsky/__init__.py | 2 +- .../components/coolmaster/__init__.py | 2 +- .../components/danfoss_air/__init__.py | 2 +- homeassistant/components/dynalite/const.py | 2 +- homeassistant/components/econet/__init__.py | 2 +- homeassistant/components/enocean/const.py | 2 +- homeassistant/components/fibaro/__init__.py | 4 +- .../components/fireservicerota/__init__.py | 2 +- homeassistant/components/freebox/const.py | 4 +- homeassistant/components/fritz/const.py | 2 +- homeassistant/components/gdacs/const.py | 2 +- .../components/geonetnz_quakes/const.py | 2 +- .../components/huawei_lte/__init__.py | 2 +- homeassistant/components/hyperion/__init__.py | 2 +- homeassistant/components/ipma/__init__.py | 2 +- homeassistant/components/juicenet/__init__.py | 2 +- homeassistant/components/kaiterra/const.py | 2 +- .../components/lutron_caseta/__init__.py | 2 +- .../components/mobile_app/__init__.py | 2 +- .../components/modern_forms/__init__.py | 2 +- .../components/moehlenhoff_alpha2/__init__.py | 2 +- homeassistant/components/mqtt/const.py | 4 +- homeassistant/components/neato/__init__.py | 8 +-- homeassistant/components/nest/__init__.py | 2 +- .../components/nissan_leaf/__init__.py | 2 +- .../components/philips_js/__init__.py | 4 +- homeassistant/components/plaato/const.py | 2 +- .../components/progettihwsw/__init__.py | 2 +- homeassistant/components/rachio/__init__.py | 2 +- homeassistant/components/rainbird/__init__.py | 6 +- homeassistant/components/rfxtrx/__init__.py | 6 +- homeassistant/components/ring/const.py | 4 +- homeassistant/components/roborock/const.py | 2 +- homeassistant/components/roomba/const.py | 2 +- homeassistant/components/smartthings/const.py | 8 +-- homeassistant/components/spider/const.py | 2 +- homeassistant/components/tailwind/__init__.py | 2 +- .../components/vodafone_station/__init__.py | 2 +- homeassistant/components/wallbox/__init__.py | 2 +- .../plugins/hass_enforce_sorted_platforms.py | 39 ++++++++++ pyproject.toml | 1 + tests/pylint/conftest.py | 21 ++++++ tests/pylint/test_enforce_sorted_platforms.py | 71 +++++++++++++++++++ 49 files changed, 194 insertions(+), 62 deletions(-) create mode 100644 pylint/plugins/hass_enforce_sorted_platforms.py create mode 100644 tests/pylint/test_enforce_sorted_platforms.py diff --git a/homeassistant/components/abode/__init__.py b/homeassistant/components/abode/__init__.py index 4e4b6a9561d..55ce9e054c3 100644 --- a/homeassistant/components/abode/__init__.py +++ b/homeassistant/components/abode/__init__.py @@ -63,12 +63,12 @@ AUTOMATION_SCHEMA = vol.Schema({ATTR_ENTITY_ID: cv.entity_ids}) PLATFORMS = [ Platform.ALARM_CONTROL_PANEL, Platform.BINARY_SENSOR, - Platform.LOCK, - Platform.SWITCH, - Platform.COVER, Platform.CAMERA, + Platform.COVER, Platform.LIGHT, + Platform.LOCK, Platform.SENSOR, + Platform.SWITCH, ] diff --git a/homeassistant/components/advantage_air/__init__.py b/homeassistant/components/advantage_air/__init__.py index 1383ea7c054..0ef2c0eada5 100644 --- a/homeassistant/components/advantage_air/__init__.py +++ b/homeassistant/components/advantage_air/__init__.py @@ -19,11 +19,11 @@ PLATFORMS = [ Platform.BINARY_SENSOR, Platform.CLIMATE, Platform.COVER, + Platform.LIGHT, Platform.SELECT, Platform.SENSOR, Platform.SWITCH, Platform.UPDATE, - Platform.LIGHT, ] _LOGGER = logging.getLogger(__name__) diff --git a/homeassistant/components/alarmdecoder/__init__.py b/homeassistant/components/alarmdecoder/__init__.py index 807d12383bc..19d1d729a5e 100644 --- a/homeassistant/components/alarmdecoder/__init__.py +++ b/homeassistant/components/alarmdecoder/__init__.py @@ -39,8 +39,8 @@ _LOGGER = logging.getLogger(__name__) PLATFORMS = [ Platform.ALARM_CONTROL_PANEL, - Platform.SENSOR, Platform.BINARY_SENSOR, + Platform.SENSOR, ] diff --git a/homeassistant/components/amberelectric/const.py b/homeassistant/components/amberelectric/const.py index 5f92e5a9117..8416b7ca33c 100644 --- a/homeassistant/components/amberelectric/const.py +++ b/homeassistant/components/amberelectric/const.py @@ -11,4 +11,4 @@ CONF_SITE_NMI = "site_nmi" ATTRIBUTION = "Data provided by Amber Electric" LOGGER = logging.getLogger(__package__) -PLATFORMS = [Platform.SENSOR, Platform.BINARY_SENSOR] +PLATFORMS = [Platform.BINARY_SENSOR, Platform.SENSOR] diff --git a/homeassistant/components/atag/__init__.py b/homeassistant/components/atag/__init__.py index 2d04ca798e0..b0cc83ab88e 100644 --- a/homeassistant/components/atag/__init__.py +++ b/homeassistant/components/atag/__init__.py @@ -19,7 +19,7 @@ from homeassistant.helpers.update_coordinator import ( _LOGGER = logging.getLogger(__name__) DOMAIN = "atag" -PLATFORMS = [Platform.CLIMATE, Platform.WATER_HEATER, Platform.SENSOR] +PLATFORMS = [Platform.CLIMATE, Platform.SENSOR, Platform.WATER_HEATER] async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: diff --git a/homeassistant/components/august/const.py b/homeassistant/components/august/const.py index b97890d09b6..0cbd21f397e 100644 --- a/homeassistant/components/august/const.py +++ b/homeassistant/components/august/const.py @@ -50,9 +50,9 @@ LOGIN_METHODS = ["phone", "email"] DEFAULT_LOGIN_METHOD = "email" PLATFORMS = [ + Platform.BINARY_SENSOR, Platform.BUTTON, Platform.CAMERA, - Platform.BINARY_SENSOR, Platform.LOCK, Platform.SENSOR, ] diff --git a/homeassistant/components/bloomsky/__init__.py b/homeassistant/components/bloomsky/__init__.py index 5b069cacdb3..59e224b0b6b 100644 --- a/homeassistant/components/bloomsky/__init__.py +++ b/homeassistant/components/bloomsky/__init__.py @@ -16,7 +16,7 @@ from homeassistant.util.unit_system import METRIC_SYSTEM _LOGGER = logging.getLogger(__name__) -PLATFORMS = [Platform.CAMERA, Platform.BINARY_SENSOR, Platform.SENSOR] +PLATFORMS = [Platform.BINARY_SENSOR, Platform.CAMERA, Platform.SENSOR] DOMAIN = "bloomsky" diff --git a/homeassistant/components/coolmaster/__init__.py b/homeassistant/components/coolmaster/__init__.py index eaca8949b14..d01310a6266 100644 --- a/homeassistant/components/coolmaster/__init__.py +++ b/homeassistant/components/coolmaster/__init__.py @@ -9,7 +9,7 @@ from homeassistant.exceptions import ConfigEntryNotReady from .const import CONF_SWING_SUPPORT, DATA_COORDINATOR, DATA_INFO, DOMAIN from .coordinator import CoolmasterDataUpdateCoordinator -PLATFORMS = [Platform.CLIMATE, Platform.BINARY_SENSOR, Platform.BUTTON, Platform.SENSOR] +PLATFORMS = [Platform.BINARY_SENSOR, Platform.BUTTON, Platform.CLIMATE, Platform.SENSOR] async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: diff --git a/homeassistant/components/danfoss_air/__init__.py b/homeassistant/components/danfoss_air/__init__.py index 599edbb7703..5069a62bcdf 100644 --- a/homeassistant/components/danfoss_air/__init__.py +++ b/homeassistant/components/danfoss_air/__init__.py @@ -15,7 +15,7 @@ from homeassistant.util import Throttle _LOGGER = logging.getLogger(__name__) -PLATFORMS = [Platform.SENSOR, Platform.BINARY_SENSOR, Platform.SWITCH] +PLATFORMS = [Platform.BINARY_SENSOR, Platform.SENSOR, Platform.SWITCH] DOMAIN = "danfoss_air" MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=60) diff --git a/homeassistant/components/dynalite/const.py b/homeassistant/components/dynalite/const.py index 83cc639d1da..f46719febb1 100644 --- a/homeassistant/components/dynalite/const.py +++ b/homeassistant/components/dynalite/const.py @@ -6,7 +6,7 @@ from homeassistant.const import CONF_ROOM, Platform LOGGER = logging.getLogger(__package__) DOMAIN = "dynalite" -PLATFORMS = [Platform.LIGHT, Platform.SWITCH, Platform.COVER] +PLATFORMS = [Platform.COVER, Platform.LIGHT, Platform.SWITCH] CONF_ACTIVE = "active" diff --git a/homeassistant/components/econet/__init__.py b/homeassistant/components/econet/__init__.py index 67cbd7496e3..5728c87938b 100644 --- a/homeassistant/components/econet/__init__.py +++ b/homeassistant/components/econet/__init__.py @@ -27,8 +27,8 @@ from .const import API_CLIENT, DOMAIN, EQUIPMENT _LOGGER = logging.getLogger(__name__) PLATFORMS = [ - Platform.CLIMATE, Platform.BINARY_SENSOR, + Platform.CLIMATE, Platform.SENSOR, Platform.WATER_HEATER, ] diff --git a/homeassistant/components/enocean/const.py b/homeassistant/components/enocean/const.py index 08e9b5ba11d..f9c522393d7 100644 --- a/homeassistant/components/enocean/const.py +++ b/homeassistant/components/enocean/const.py @@ -15,8 +15,8 @@ SIGNAL_SEND_MESSAGE = "enocean.send_message" LOGGER = logging.getLogger(__package__) PLATFORMS = [ - Platform.LIGHT, Platform.BINARY_SENSOR, + Platform.LIGHT, Platform.SENSOR, Platform.SWITCH, ] diff --git a/homeassistant/components/fibaro/__init__.py b/homeassistant/components/fibaro/__init__.py index 8b41c4f404f..159ba62bd24 100644 --- a/homeassistant/components/fibaro/__init__.py +++ b/homeassistant/components/fibaro/__init__.py @@ -42,12 +42,12 @@ PLATFORMS = [ Platform.BINARY_SENSOR, Platform.CLIMATE, Platform.COVER, + Platform.EVENT, Platform.LIGHT, + Platform.LOCK, Platform.SCENE, Platform.SENSOR, - Platform.LOCK, Platform.SWITCH, - Platform.EVENT, ] FIBARO_TYPEMAP = { diff --git a/homeassistant/components/fireservicerota/__init__.py b/homeassistant/components/fireservicerota/__init__.py index a9a4323fe12..cb7a18dfcac 100644 --- a/homeassistant/components/fireservicerota/__init__.py +++ b/homeassistant/components/fireservicerota/__init__.py @@ -25,7 +25,7 @@ MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=60) _LOGGER = logging.getLogger(__name__) -PLATFORMS = [Platform.SENSOR, Platform.BINARY_SENSOR, Platform.SWITCH] +PLATFORMS = [Platform.BINARY_SENSOR, Platform.SENSOR, Platform.SWITCH] async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: diff --git a/homeassistant/components/freebox/const.py b/homeassistant/components/freebox/const.py index f74f6f49ebf..ef5cabda1b6 100644 --- a/homeassistant/components/freebox/const.py +++ b/homeassistant/components/freebox/const.py @@ -19,12 +19,12 @@ API_VERSION = "v6" PLATFORMS = [ Platform.ALARM_CONTROL_PANEL, + Platform.BINARY_SENSOR, Platform.BUTTON, + Platform.CAMERA, Platform.DEVICE_TRACKER, Platform.SENSOR, - Platform.BINARY_SENSOR, Platform.SWITCH, - Platform.CAMERA, ] DEFAULT_DEVICE_NAME = "Unknown device" diff --git a/homeassistant/components/fritz/const.py b/homeassistant/components/fritz/const.py index 16015ec5837..fb60eaef5f8 100644 --- a/homeassistant/components/fritz/const.py +++ b/homeassistant/components/fritz/const.py @@ -28,8 +28,8 @@ class MeshRoles(StrEnum): DOMAIN = "fritz" PLATFORMS = [ - Platform.BUTTON, Platform.BINARY_SENSOR, + Platform.BUTTON, Platform.DEVICE_TRACKER, Platform.IMAGE, Platform.SENSOR, diff --git a/homeassistant/components/gdacs/const.py b/homeassistant/components/gdacs/const.py index 551c8be5810..6be7e7b32fc 100644 --- a/homeassistant/components/gdacs/const.py +++ b/homeassistant/components/gdacs/const.py @@ -7,7 +7,7 @@ from homeassistant.const import Platform DOMAIN = "gdacs" -PLATFORMS = [Platform.SENSOR, Platform.GEO_LOCATION] +PLATFORMS = [Platform.GEO_LOCATION, Platform.SENSOR] FEED = "feed" diff --git a/homeassistant/components/geonetnz_quakes/const.py b/homeassistant/components/geonetnz_quakes/const.py index f3303d551ce..6ec2199f9e4 100644 --- a/homeassistant/components/geonetnz_quakes/const.py +++ b/homeassistant/components/geonetnz_quakes/const.py @@ -5,7 +5,7 @@ from homeassistant.const import Platform DOMAIN = "geonetnz_quakes" -PLATFORMS = [Platform.SENSOR, Platform.GEO_LOCATION] +PLATFORMS = [Platform.GEO_LOCATION, Platform.SENSOR] CONF_MINIMUM_MAGNITUDE = "minimum_magnitude" CONF_MMI = "mmi" diff --git a/homeassistant/components/huawei_lte/__init__.py b/homeassistant/components/huawei_lte/__init__.py index ba276625730..29c59d3ff9c 100644 --- a/homeassistant/components/huawei_lte/__init__.py +++ b/homeassistant/components/huawei_lte/__init__.py @@ -127,9 +127,9 @@ PLATFORMS = [ Platform.BINARY_SENSOR, Platform.BUTTON, Platform.DEVICE_TRACKER, + Platform.SELECT, Platform.SENSOR, Platform.SWITCH, - Platform.SELECT, ] diff --git a/homeassistant/components/hyperion/__init__.py b/homeassistant/components/hyperion/__init__.py index ea038b3b408..42d9770656b 100644 --- a/homeassistant/components/hyperion/__init__.py +++ b/homeassistant/components/hyperion/__init__.py @@ -32,7 +32,7 @@ from .const import ( SIGNAL_INSTANCE_REMOVE, ) -PLATFORMS = [Platform.LIGHT, Platform.SWITCH, Platform.CAMERA] +PLATFORMS = [Platform.CAMERA, Platform.LIGHT, Platform.SWITCH] _LOGGER = logging.getLogger(__name__) diff --git a/homeassistant/components/ipma/__init__.py b/homeassistant/components/ipma/__init__.py index 5ff89fa8ed5..4cb8f921ba4 100644 --- a/homeassistant/components/ipma/__init__.py +++ b/homeassistant/components/ipma/__init__.py @@ -17,7 +17,7 @@ from .const import DATA_API, DATA_LOCATION, DOMAIN DEFAULT_NAME = "ipma" -PLATFORMS = [Platform.WEATHER, Platform.SENSOR] +PLATFORMS = [Platform.SENSOR, Platform.WEATHER] _LOGGER = logging.getLogger(__name__) diff --git a/homeassistant/components/juicenet/__init__.py b/homeassistant/components/juicenet/__init__.py index c1744b30b1a..bcefe763e15 100644 --- a/homeassistant/components/juicenet/__init__.py +++ b/homeassistant/components/juicenet/__init__.py @@ -20,7 +20,7 @@ from .device import JuiceNetApi _LOGGER = logging.getLogger(__name__) -PLATFORMS = [Platform.SENSOR, Platform.SWITCH, Platform.NUMBER] +PLATFORMS = [Platform.NUMBER, Platform.SENSOR, Platform.SWITCH] CONFIG_SCHEMA = vol.Schema( vol.All( diff --git a/homeassistant/components/kaiterra/const.py b/homeassistant/components/kaiterra/const.py index c77b3c34564..a73a698f80a 100644 --- a/homeassistant/components/kaiterra/const.py +++ b/homeassistant/components/kaiterra/const.py @@ -72,4 +72,4 @@ DEFAULT_AQI_STANDARD = "us" DEFAULT_PREFERRED_UNIT: list[str] = [] DEFAULT_SCAN_INTERVAL = timedelta(seconds=30) -PLATFORMS = [Platform.SENSOR, Platform.AIR_QUALITY] +PLATFORMS = [Platform.AIR_QUALITY, Platform.SENSOR] diff --git a/homeassistant/components/lutron_caseta/__init__.py b/homeassistant/components/lutron_caseta/__init__.py index 0788af76aca..33cf6f21d6f 100644 --- a/homeassistant/components/lutron_caseta/__init__.py +++ b/homeassistant/components/lutron_caseta/__init__.py @@ -91,12 +91,12 @@ CONFIG_SCHEMA = vol.Schema( PLATFORMS = [ Platform.BINARY_SENSOR, + Platform.BUTTON, Platform.COVER, Platform.FAN, Platform.LIGHT, Platform.SCENE, Platform.SWITCH, - Platform.BUTTON, ] diff --git a/homeassistant/components/mobile_app/__init__.py b/homeassistant/components/mobile_app/__init__.py index 124ef750baa..831d2d5cdfb 100644 --- a/homeassistant/components/mobile_app/__init__.py +++ b/homeassistant/components/mobile_app/__init__.py @@ -39,7 +39,7 @@ from .http_api import RegistrationsView from .util import async_create_cloud_hook from .webhook import handle_webhook -PLATFORMS = [Platform.SENSOR, Platform.BINARY_SENSOR, Platform.DEVICE_TRACKER] +PLATFORMS = [Platform.BINARY_SENSOR, Platform.DEVICE_TRACKER, Platform.SENSOR] CONFIG_SCHEMA = cv.empty_config_schema(DOMAIN) diff --git a/homeassistant/components/modern_forms/__init__.py b/homeassistant/components/modern_forms/__init__.py index 78d2fafa078..3401d961bc8 100644 --- a/homeassistant/components/modern_forms/__init__.py +++ b/homeassistant/components/modern_forms/__init__.py @@ -34,8 +34,8 @@ _P = ParamSpec("_P") SCAN_INTERVAL = timedelta(seconds=5) PLATFORMS = [ Platform.BINARY_SENSOR, - Platform.LIGHT, Platform.FAN, + Platform.LIGHT, Platform.SENSOR, Platform.SWITCH, ] diff --git a/homeassistant/components/moehlenhoff_alpha2/__init__.py b/homeassistant/components/moehlenhoff_alpha2/__init__.py index 05f6b23fdd0..fa5db2d0e81 100644 --- a/homeassistant/components/moehlenhoff_alpha2/__init__.py +++ b/homeassistant/components/moehlenhoff_alpha2/__init__.py @@ -17,7 +17,7 @@ from .const import DOMAIN _LOGGER = logging.getLogger(__name__) -PLATFORMS = [Platform.BUTTON, Platform.CLIMATE, Platform.SENSOR, Platform.BINARY_SENSOR] +PLATFORMS = [Platform.BINARY_SENSOR, Platform.BUTTON, Platform.CLIMATE, Platform.SENSOR] UPDATE_INTERVAL = timedelta(seconds=60) diff --git a/homeassistant/components/mqtt/const.py b/homeassistant/components/mqtt/const.py index 50ea3860d9e..304877695c3 100644 --- a/homeassistant/components/mqtt/const.py +++ b/homeassistant/components/mqtt/const.py @@ -142,9 +142,9 @@ PLATFORMS = [ Platform.BUTTON, Platform.CAMERA, Platform.CLIMATE, + Platform.COVER, Platform.DEVICE_TRACKER, Platform.EVENT, - Platform.COVER, Platform.FAN, Platform.HUMIDIFIER, Platform.IMAGE, @@ -152,8 +152,8 @@ PLATFORMS = [ Platform.LIGHT, Platform.LOCK, Platform.NUMBER, - Platform.SELECT, Platform.SCENE, + Platform.SELECT, Platform.SENSOR, Platform.SIREN, Platform.SWITCH, diff --git a/homeassistant/components/neato/__init__.py b/homeassistant/components/neato/__init__.py index 52bc841f3b5..196961652f0 100644 --- a/homeassistant/components/neato/__init__.py +++ b/homeassistant/components/neato/__init__.py @@ -41,11 +41,11 @@ CONFIG_SCHEMA = vol.Schema( ) PLATFORMS = [ - Platform.CAMERA, - Platform.VACUUM, - Platform.SWITCH, - Platform.SENSOR, Platform.BUTTON, + Platform.CAMERA, + Platform.SENSOR, + Platform.SWITCH, + Platform.VACUUM, ] diff --git a/homeassistant/components/nest/__init__.py b/homeassistant/components/nest/__init__.py index e85073061c2..8d1d58f9117 100644 --- a/homeassistant/components/nest/__init__.py +++ b/homeassistant/components/nest/__init__.py @@ -95,7 +95,7 @@ CONFIG_SCHEMA = vol.Schema( ) # Platforms for SDM API -PLATFORMS = [Platform.SENSOR, Platform.CAMERA, Platform.CLIMATE] +PLATFORMS = [Platform.CAMERA, Platform.CLIMATE, Platform.SENSOR] # Fetch media events with a disk backed cache, with a limit for each camera # device. The largest media items are mp4 clips at ~120kb each, and we target diff --git a/homeassistant/components/nissan_leaf/__init__.py b/homeassistant/components/nissan_leaf/__init__.py index a32ba2e6329..a0cb3c4f8cc 100644 --- a/homeassistant/components/nissan_leaf/__init__.py +++ b/homeassistant/components/nissan_leaf/__init__.py @@ -87,7 +87,7 @@ CONFIG_SCHEMA = vol.Schema( extra=vol.ALLOW_EXTRA, ) -PLATFORMS = [Platform.SENSOR, Platform.SWITCH, Platform.BINARY_SENSOR, Platform.BUTTON] +PLATFORMS = [Platform.BINARY_SENSOR, Platform.BUTTON, Platform.SENSOR, Platform.SWITCH] SIGNAL_UPDATE_LEAF = "nissan_leaf_update" diff --git a/homeassistant/components/philips_js/__init__.py b/homeassistant/components/philips_js/__init__.py index b81fec90a59..3fce7f1fafd 100644 --- a/homeassistant/components/philips_js/__init__.py +++ b/homeassistant/components/philips_js/__init__.py @@ -32,11 +32,11 @@ from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, Upda from .const import CONF_ALLOW_NOTIFY, CONF_SYSTEM, DOMAIN PLATFORMS = [ - Platform.MEDIA_PLAYER, + Platform.BINARY_SENSOR, Platform.LIGHT, + Platform.MEDIA_PLAYER, Platform.REMOTE, Platform.SWITCH, - Platform.BINARY_SENSOR, ] LOGGER = logging.getLogger(__name__) diff --git a/homeassistant/components/plaato/const.py b/homeassistant/components/plaato/const.py index c47b91a4adb..6825baff906 100644 --- a/homeassistant/components/plaato/const.py +++ b/homeassistant/components/plaato/const.py @@ -17,7 +17,7 @@ PLACEHOLDER_DOCS_URL = "docs_url" PLACEHOLDER_DEVICE_TYPE = "device_type" PLACEHOLDER_DEVICE_NAME = "device_name" DOCS_URL = "https://www.home-assistant.io/integrations/plaato/" -PLATFORMS = [Platform.SENSOR, Platform.BINARY_SENSOR] +PLATFORMS = [Platform.BINARY_SENSOR, Platform.SENSOR] SENSOR_DATA = "sensor_data" COORDINATOR = "coordinator" DEVICE = "device" diff --git a/homeassistant/components/progettihwsw/__init__.py b/homeassistant/components/progettihwsw/__init__.py index d1d27b78769..1bf23befbdb 100644 --- a/homeassistant/components/progettihwsw/__init__.py +++ b/homeassistant/components/progettihwsw/__init__.py @@ -10,7 +10,7 @@ from homeassistant.core import HomeAssistant from .const import DOMAIN -PLATFORMS = [Platform.SWITCH, Platform.BINARY_SENSOR] +PLATFORMS = [Platform.BINARY_SENSOR, Platform.SWITCH] async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: diff --git a/homeassistant/components/rachio/__init__.py b/homeassistant/components/rachio/__init__.py index e47004f5fb7..13299b4e7dc 100644 --- a/homeassistant/components/rachio/__init__.py +++ b/homeassistant/components/rachio/__init__.py @@ -22,7 +22,7 @@ from .webhooks import ( _LOGGER = logging.getLogger(__name__) -PLATFORMS = [Platform.SWITCH, Platform.BINARY_SENSOR] +PLATFORMS = [Platform.BINARY_SENSOR, Platform.SWITCH] CONFIG_SCHEMA = cv.removed(DOMAIN, raise_if_present=False) diff --git a/homeassistant/components/rainbird/__init__.py b/homeassistant/components/rainbird/__init__.py index e5731dc08fe..f7eab3bc2f2 100644 --- a/homeassistant/components/rainbird/__init__.py +++ b/homeassistant/components/rainbird/__init__.py @@ -20,11 +20,11 @@ from .coordinator import RainbirdData _LOGGER = logging.getLogger(__name__) PLATFORMS = [ - Platform.SWITCH, - Platform.SENSOR, Platform.BINARY_SENSOR, - Platform.NUMBER, Platform.CALENDAR, + Platform.NUMBER, + Platform.SENSOR, + Platform.SWITCH, ] diff --git a/homeassistant/components/rfxtrx/__init__.py b/homeassistant/components/rfxtrx/__init__.py index cfacc627744..ffbc3d26421 100644 --- a/homeassistant/components/rfxtrx/__init__.py +++ b/homeassistant/components/rfxtrx/__init__.py @@ -76,12 +76,12 @@ def _bytearray_string(data: Any) -> bytearray: SERVICE_SEND_SCHEMA = vol.Schema({ATTR_EVENT: _bytearray_string}) PLATFORMS = [ - Platform.SWITCH, - Platform.SENSOR, - Platform.LIGHT, Platform.BINARY_SENSOR, Platform.COVER, + Platform.LIGHT, + Platform.SENSOR, Platform.SIREN, + Platform.SWITCH, ] diff --git a/homeassistant/components/ring/const.py b/homeassistant/components/ring/const.py index 10d517ab4a3..4f208e4f63e 100644 --- a/homeassistant/components/ring/const.py +++ b/homeassistant/components/ring/const.py @@ -15,11 +15,11 @@ DEFAULT_ENTITY_NAMESPACE = "ring" PLATFORMS = [ Platform.BINARY_SENSOR, + Platform.CAMERA, Platform.LIGHT, Platform.SENSOR, - Platform.SWITCH, - Platform.CAMERA, Platform.SIREN, + Platform.SWITCH, ] diff --git a/homeassistant/components/roborock/const.py b/homeassistant/components/roborock/const.py index d7a3a9229f5..f163c9620d1 100644 --- a/homeassistant/components/roborock/const.py +++ b/homeassistant/components/roborock/const.py @@ -9,8 +9,8 @@ CONF_BASE_URL = "base_url" CONF_USER_DATA = "user_data" PLATFORMS = [ - Platform.BUTTON, Platform.BINARY_SENSOR, + Platform.BUTTON, Platform.IMAGE, Platform.NUMBER, Platform.SELECT, diff --git a/homeassistant/components/roomba/const.py b/homeassistant/components/roomba/const.py index 151d3bfb68e..71db96f8c21 100644 --- a/homeassistant/components/roomba/const.py +++ b/homeassistant/components/roomba/const.py @@ -2,7 +2,7 @@ from homeassistant.const import Platform DOMAIN = "roomba" -PLATFORMS = [Platform.SENSOR, Platform.BINARY_SENSOR, Platform.VACUUM] +PLATFORMS = [Platform.BINARY_SENSOR, Platform.SENSOR, Platform.VACUUM] CONF_CERT = "certificate" CONF_CONTINUOUS = "continuous" CONF_BLID = "blid" diff --git a/homeassistant/components/smartthings/const.py b/homeassistant/components/smartthings/const.py index 1bd21cd73cd..393242a30dd 100644 --- a/homeassistant/components/smartthings/const.py +++ b/homeassistant/components/smartthings/const.py @@ -34,15 +34,15 @@ STORAGE_VERSION = 1 # Ordered 'specific to least-specific platform' in order for capabilities # to be drawn-down and represented by the most appropriate platform. PLATFORMS = [ + Platform.BINARY_SENSOR, Platform.CLIMATE, + Platform.COVER, Platform.FAN, Platform.LIGHT, Platform.LOCK, - Platform.COVER, - Platform.SWITCH, - Platform.BINARY_SENSOR, - Platform.SENSOR, Platform.SCENE, + Platform.SENSOR, + Platform.SWITCH, ] IGNORED_CAPABILITIES = [ diff --git a/homeassistant/components/spider/const.py b/homeassistant/components/spider/const.py index 503625fedd2..e48e963637a 100644 --- a/homeassistant/components/spider/const.py +++ b/homeassistant/components/spider/const.py @@ -4,4 +4,4 @@ from homeassistant.const import Platform DOMAIN = "spider" DEFAULT_SCAN_INTERVAL = 300 -PLATFORMS = [Platform.CLIMATE, Platform.SWITCH, Platform.SENSOR] +PLATFORMS = [Platform.CLIMATE, Platform.SENSOR, Platform.SWITCH] diff --git a/homeassistant/components/tailwind/__init__.py b/homeassistant/components/tailwind/__init__.py index f4772050e5a..c7ceb88294a 100644 --- a/homeassistant/components/tailwind/__init__.py +++ b/homeassistant/components/tailwind/__init__.py @@ -9,7 +9,7 @@ from homeassistant.helpers import device_registry as dr from .const import DOMAIN from .coordinator import TailwindDataUpdateCoordinator -PLATFORMS = [Platform.BINARY_SENSOR, Platform.COVER, Platform.BUTTON, Platform.NUMBER] +PLATFORMS = [Platform.BINARY_SENSOR, Platform.BUTTON, Platform.COVER, Platform.NUMBER] async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: diff --git a/homeassistant/components/vodafone_station/__init__.py b/homeassistant/components/vodafone_station/__init__.py index 816e9241739..66960921750 100644 --- a/homeassistant/components/vodafone_station/__init__.py +++ b/homeassistant/components/vodafone_station/__init__.py @@ -7,7 +7,7 @@ from homeassistant.core import HomeAssistant from .const import DOMAIN from .coordinator import VodafoneStationRouter -PLATFORMS = [Platform.DEVICE_TRACKER, Platform.SENSOR, Platform.BUTTON] +PLATFORMS = [Platform.BUTTON, Platform.DEVICE_TRACKER, Platform.SENSOR] async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: diff --git a/homeassistant/components/wallbox/__init__.py b/homeassistant/components/wallbox/__init__.py index 8194a3ea262..4ca6e768f64 100644 --- a/homeassistant/components/wallbox/__init__.py +++ b/homeassistant/components/wallbox/__init__.py @@ -11,7 +11,7 @@ from homeassistant.exceptions import ConfigEntryAuthFailed from .const import CONF_STATION, DOMAIN, UPDATE_INTERVAL from .coordinator import InvalidAuth, WallboxCoordinator -PLATFORMS = [Platform.SENSOR, Platform.NUMBER, Platform.LOCK, Platform.SWITCH] +PLATFORMS = [Platform.LOCK, Platform.NUMBER, Platform.SENSOR, Platform.SWITCH] async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: diff --git a/pylint/plugins/hass_enforce_sorted_platforms.py b/pylint/plugins/hass_enforce_sorted_platforms.py new file mode 100644 index 00000000000..b3fb7c8adcc --- /dev/null +++ b/pylint/plugins/hass_enforce_sorted_platforms.py @@ -0,0 +1,39 @@ +"""Plugin for checking sorted platforms list.""" +from __future__ import annotations + +from astroid import nodes +from pylint.checkers import BaseChecker +from pylint.lint import PyLinter + + +class HassEnforceSortedPlatformsChecker(BaseChecker): + """Checker for sorted platforms list.""" + + name = "hass_enforce_sorted_platforms" + priority = -1 + msgs = { + "W7451": ( + "Platforms must be sorted alphabetically", + "hass-enforce-sorted-platforms", + "Used when PLATFORMS should be sorted alphabetically.", + ), + } + options = () + + def visit_assign(self, node: nodes.Assign) -> None: + """Check for sorted PLATFORMS const.""" + for target in node.targets: + if ( + isinstance(target, nodes.AssignName) + and target.name == "PLATFORMS" + and isinstance(node.value, nodes.List) + ): + platforms = [v.as_string() for v in node.value.elts] + sorted_platforms = sorted(platforms) + if platforms != sorted_platforms: + self.add_message("hass-enforce-sorted-platforms", node=node) + + +def register(linter: PyLinter) -> None: + """Register the checker.""" + linter.register_checker(HassEnforceSortedPlatformsChecker(linter)) diff --git a/pyproject.toml b/pyproject.toml index 3780642c0c5..4e2dfb9a77e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -103,6 +103,7 @@ init-hook = """\ load-plugins = [ "pylint.extensions.code_style", "pylint.extensions.typing", + "hass_enforce_sorted_platforms", "hass_enforce_super_call", "hass_enforce_type_hints", "hass_inheritance", diff --git a/tests/pylint/conftest.py b/tests/pylint/conftest.py index 03f637a646f..3554dc66c92 100644 --- a/tests/pylint/conftest.py +++ b/tests/pylint/conftest.py @@ -80,3 +80,24 @@ def super_call_checker_fixture(hass_enforce_super_call, linter) -> BaseChecker: super_call_checker = hass_enforce_super_call.HassEnforceSuperCallChecker(linter) super_call_checker.module = "homeassistant.components.pylint_test" return super_call_checker + + +@pytest.fixture(name="hass_enforce_sorted_platforms", scope="session") +def hass_enforce_sorted_platforms_fixture() -> ModuleType: + """Fixture to the content for the hass_enforce_sorted_platforms check.""" + return _load_plugin_from_file( + "hass_enforce_sorted_platforms", + "pylint/plugins/hass_enforce_sorted_platforms.py", + ) + + +@pytest.fixture(name="enforce_sorted_platforms_checker") +def enforce_sorted_platforms_checker_fixture( + hass_enforce_sorted_platforms, linter +) -> BaseChecker: + """Fixture to provide a hass_enforce_sorted_platforms checker.""" + enforce_sorted_platforms_checker = ( + hass_enforce_sorted_platforms.HassEnforceSortedPlatformsChecker(linter) + ) + enforce_sorted_platforms_checker.module = "homeassistant.components.pylint_test" + return enforce_sorted_platforms_checker diff --git a/tests/pylint/test_enforce_sorted_platforms.py b/tests/pylint/test_enforce_sorted_platforms.py new file mode 100644 index 00000000000..923291411f0 --- /dev/null +++ b/tests/pylint/test_enforce_sorted_platforms.py @@ -0,0 +1,71 @@ +"""Tests for pylint hass_enforce_sorted_platforms plugin.""" +from __future__ import annotations + +import astroid +from pylint.checkers import BaseChecker +from pylint.interfaces import UNDEFINED +from pylint.testutils import MessageTest +from pylint.testutils.unittest_linter import UnittestLinter +from pylint.utils.ast_walker import ASTWalker +import pytest + +from . import assert_adds_messages, assert_no_messages + + +@pytest.mark.parametrize( + "code", + [ + pytest.param( + """ + PLATFORMS = [Platform.SENSOR] + """, + id="one_platform", + ), + pytest.param( + """ + PLATFORMS = [Platform.BINARY_SENSOR, Platform.BUTTON, Platform.SENSOR] + """, + id="multiple_platforms", + ), + ], +) +def test_enforce_sorted_platforms( + linter: UnittestLinter, + enforce_sorted_platforms_checker: BaseChecker, + code: str, +) -> None: + """Good test cases.""" + root_node = astroid.parse(code, "homeassistant.components.pylint_test") + walker = ASTWalker(linter) + walker.add_checker(enforce_sorted_platforms_checker) + + with assert_no_messages(linter): + walker.walk(root_node) + + +def test_enforce_sorted_platforms_bad( + linter: UnittestLinter, + enforce_sorted_platforms_checker: BaseChecker, +) -> None: + """Bad test case.""" + assign_node = astroid.extract_node( + """ + PLATFORMS = [Platform.SENSOR, Platform.BINARY_SENSOR, Platform.BUTTON] + """, + "homeassistant.components.pylint_test", + ) + + with assert_adds_messages( + linter, + MessageTest( + msg_id="hass-enforce-sorted-platforms", + line=2, + node=assign_node, + args=None, + confidence=UNDEFINED, + col_offset=0, + end_line=2, + end_col_offset=70, + ), + ): + enforce_sorted_platforms_checker.visit_assign(assign_node)