diff --git a/.circleci/config.yml b/.circleci/config.yml index d31fd512abd..70d2f7af3a3 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -91,6 +91,12 @@ jobs: . venv/bin/activate flake8 + - run: + name: validate CODEOWNERS + command: | + . venv/bin/activate + python script/manifest/codeowners.py validate + - run: name: run static type check command: | diff --git a/CODEOWNERS b/CODEOWNERS index 5be5610a5c7..ae5bcb452cb 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -1,3 +1,4 @@ +# This file is generated by script/manifest/codeowners.py # People marked here will be automatically requested for a review # when the code that they own is touched. # https://github.com/blog/2392-introducing-code-owners @@ -7,288 +8,237 @@ setup.py @home-assistant/core homeassistant/*.py @home-assistant/core homeassistant/helpers/* @home-assistant/core homeassistant/util/* @home-assistant/core + +# Virtualization +Dockerfile @home-assistant/docker +virtualization/Docker/* @home-assistant/docker + +# Other code +homeassistant/scripts/check_config.py @kellerza + +# Integrations +homeassistant/components/airvisual/* @bachya +homeassistant/components/alarm_control_panel/* @colinodell +homeassistant/components/alpha_vantage/* @fabaff +homeassistant/components/amazon_polly/* @robbiet480 +homeassistant/components/ambient_station/* @bachya homeassistant/components/api/* @home-assistant/core +homeassistant/components/arduino/* @fabaff +homeassistant/components/arest/* @fabaff +homeassistant/components/asuswrt/* @kennedyshead homeassistant/components/auth/* @home-assistant/core +homeassistant/components/automatic/* @armills homeassistant/components/automation/* @home-assistant/core +homeassistant/components/aws/* @awarecan @robbiet480 +homeassistant/components/axis/* @kane610 +homeassistant/components/bitcoin/* @fabaff +homeassistant/components/blink/* @fronzbot +homeassistant/components/bmw_connected_drive/* @ChristianKuehnel +homeassistant/components/braviatv/* @robbiet480 +homeassistant/components/broadlink/* @danielhiversen +homeassistant/components/brunt/* @eavanvalkenburg +homeassistant/components/bt_smarthub/* @jxwolstenholme homeassistant/components/cloud/* @home-assistant/core +homeassistant/components/cloudflare/* @ludeeus homeassistant/components/config/* @home-assistant/core homeassistant/components/configurator/* @home-assistant/core homeassistant/components/conversation/* @home-assistant/core +homeassistant/components/coolmaster/* @OnFreund +homeassistant/components/counter/* @fabaff +homeassistant/components/cover/* @cdce8p +homeassistant/components/cpuspeed/* @fabaff +homeassistant/components/cups/* @fabaff +homeassistant/components/daikin/* @fredrike @rofrantz +homeassistant/components/darksky/* @fabaff +homeassistant/components/deconz/* @kane610 +homeassistant/components/demo/* @fabaff +homeassistant/components/digital_ocean/* @fabaff +homeassistant/components/discogs/* @thibmaek +homeassistant/components/doorbird/* @oblogic7 +homeassistant/components/dweet/* @fabaff +homeassistant/components/ecovacs/* @OverloadUT +homeassistant/components/edp_redy/* @abmantis +homeassistant/components/egardia/* @jeroenterheerdt +homeassistant/components/eight_sleep/* @mezz64 +homeassistant/components/emby/* @mezz64 +homeassistant/components/ephember/* @ttroy50 +homeassistant/components/eq3btsmart/* @rytilahti +homeassistant/components/esphome/* @OttoWinter +homeassistant/components/file/* @fabaff +homeassistant/components/filter/* @dgomes +homeassistant/components/fitbit/* @robbiet480 +homeassistant/components/fixer/* @fabaff +homeassistant/components/flock/* @fabaff +homeassistant/components/flunearyou/* @bachya +homeassistant/components/foursquare/* @robbiet480 +homeassistant/components/freebox/* @snoof85 homeassistant/components/frontend/* @home-assistant/core +homeassistant/components/gearbest/* @HerrHofrat +homeassistant/components/gitter/* @fabaff +homeassistant/components/glances/* @fabaff +homeassistant/components/gntp/* @robbiet480 +homeassistant/components/google_travel_time/* @robbiet480 +homeassistant/components/googlehome/* @ludeeus +homeassistant/components/gpsd/* @fabaff homeassistant/components/group/* @home-assistant/core +homeassistant/components/gtfs/* @robbiet480 +homeassistant/components/harmony/* @ehendrix23 +homeassistant/components/hassio/* @home-assistant/hassio +homeassistant/components/heos/* @andrewsayre +homeassistant/components/hikvision/* @mezz64 homeassistant/components/history/* @home-assistant/core +homeassistant/components/history_graph/* @andrey-git +homeassistant/components/hive/* @Rendili @KJonline +homeassistant/components/homeassistant/* @home-assistant/core +homeassistant/components/homekit/* @cdce8p +homeassistant/components/html5/* @robbiet480 homeassistant/components/http/* @home-assistant/core +homeassistant/components/huawei_lte/* @scop +homeassistant/components/huawei_router/* @abmantis +homeassistant/components/hue/* @balloob +homeassistant/components/influxdb/* @fabaff homeassistant/components/input_boolean/* @home-assistant/core homeassistant/components/input_datetime/* @home-assistant/core homeassistant/components/input_number/* @home-assistant/core homeassistant/components/input_select/* @home-assistant/core homeassistant/components/input_text/* @home-assistant/core +homeassistant/components/integration/* @dgomes homeassistant/components/introduction/* @home-assistant/core -homeassistant/components/logger/* @home-assistant/core -homeassistant/components/lovelace/* @home-assistant/core -homeassistant/components/mqtt/* @home-assistant/core -homeassistant/components/panel_custom/* @home-assistant/core -homeassistant/components/panel_iframe/* @home-assistant/core -homeassistant/components/onboarding/* @home-assistant/core -homeassistant/components/persistent_notification/* @home-assistant/core -homeassistant/components/scene/__init__.py @home-assistant/core -homeassistant/components/scene/homeassistant.py @home-assistant/core -homeassistant/components/script/* @home-assistant/core -homeassistant/components/shell_command/* @home-assistant/core -homeassistant/components/sun/* @home-assistant/core -homeassistant/components/updater/* @home-assistant/core -homeassistant/components/weblink/* @home-assistant/core -homeassistant/components/websocket_api/* @home-assistant/core -homeassistant/components/zone/* @home-assistant/core - -# Home Assistant Developer Teams -Dockerfile @home-assistant/docker -virtualization/Docker/* @home-assistant/docker - -homeassistant/components/zwave/* @home-assistant/z-wave - -homeassistant/components/hassio/* @home-assistant/hassio - -# Individual platforms - -# A -homeassistant/components/airvisual/sensor.py @bachya -homeassistant/components/alarm_control_panel/manual_mqtt.py @colinodell -homeassistant/components/alpha_vantage/sensor.py @fabaff -homeassistant/components/amazon_polly/* @robbiet480 -homeassistant/components/ambient_station/* @bachya -homeassistant/components/arduino/* @fabaff -homeassistant/components/arest/* @fabaff -homeassistant/components/asuswrt/device_tracker.py @kennedyshead -homeassistant/components/automatic/device_tracker.py @armills -homeassistant/components/aws/* @awarecan @robbiet480 -homeassistant/components/axis/* @kane610 - -# B -homeassistant/components/bitcoin/sensor.py @fabaff -homeassistant/components/blink/* @fronzbot -homeassistant/components/bmw_connected_drive/* @ChristianKuehnel -homeassistant/components/braviatv/media_player.py @robbiet480 -homeassistant/components/broadlink/* @danielhiversen -homeassistant/components/brunt/cover.py @eavanvalkenburg -homeassistant/components/bt_smarthub/device_tracker.py @jxwolstenholme - -# C -homeassistant/components/cloudflare/* @ludeeus -homeassistant/components/coolmaster/climate.py @OnFreund -homeassistant/components/counter/* @fabaff -homeassistant/components/cover/group.py @cdce8p -homeassistant/components/cpuspeed/sensor.py @fabaff -homeassistant/components/cups/sensor.py @fabaff - -# D -homeassistant/components/daikin/* @fredrike @rofrantz -homeassistant/components/darksky/* @fabaff -homeassistant/components/discogs/sensor.py @thibmaek -homeassistant/components/deconz/* @kane610 -homeassistant/components/demo/weather.py @fabaff -homeassistant/components/digital_ocean/* @fabaff -homeassistant/components/doorbird/* @oblogic7 -homeassistant/components/dweet/* @fabaff - -# E -homeassistant/components/ecovacs/* @OverloadUT -homeassistant/components/edp_redy/* @abmantis -homeassistant/components/eight_sleep/* @mezz64 -homeassistant/components/egardia/* @jeroenterheerdt -homeassistant/components/emby/media_player.py @mezz64 -homeassistant/components/ephember/climate.py @ttroy50 -homeassistant/components/eq3btsmart/climate.py @rytilahti -homeassistant/components/esphome/* @OttoWinter - -# F -homeassistant/components/file/* @fabaff -homeassistant/components/filter/sensor.py @dgomes -homeassistant/components/fitbit/sensor.py @robbiet480 -homeassistant/components/fixer/sensor.py @fabaff -homeassistant/components/flock/notify.py @fabaff -homeassistant/components/flunearyou/sensor.py @bachya -homeassistant/components/foursquare/* @robbiet480 -homeassistant/components/freebox/* @snoof85 - -# G -homeassistant/components/gearbest/sensor.py @HerrHofrat -homeassistant/components/gitter/sensor.py @fabaff -homeassistant/components/glances/sensor.py @fabaff -homeassistant/components/gntp/notify.py @robbiet480 -homeassistant/components/google_travel_time/sensor.py @robbiet480 -homeassistant/components/googlehome/* @ludeeus -homeassistant/components/gpsd/sensor.py @fabaff -homeassistant/components/gtfs/sensor.py @robbiet480 - -# H -homeassistant/components/harmony/* @ehendrix23 -homeassistant/components/heos/* @andrewsayre -homeassistant/components/hikvision/binary_sensor.py @mezz64 -homeassistant/components/history_graph/* @andrey-git -homeassistant/components/hive/* @Rendili @KJonline -homeassistant/components/homekit/* @cdce8p -homeassistant/components/html5/notify.py @robbiet480 -homeassistant/components/huawei_lte/* @scop -homeassistant/components/huawei_router/device_tracker.py @abmantis - -# I -homeassistant/components/influxdb/* @fabaff -homeassistant/components/integration/sensor.py @dgomes homeassistant/components/ios/* @robbiet480 homeassistant/components/ipma/* @dgomes -homeassistant/components/irish_rail_transport/sensor.py @ttroy50 - -# J -homeassistant/components/jewish_calendar/sensor.py @tsvi - -# K +homeassistant/components/irish_rail_transport/* @ttroy50 +homeassistant/components/jewish_calendar/* @tsvi homeassistant/components/knx/* @Julius2342 -homeassistant/components/kodi/media_player.py @armills +homeassistant/components/kodi/* @armills homeassistant/components/konnected/* @heythisisnate - -# L -homeassistant/components/lametric/notify.py @robbiet480 -homeassistant/components/launch_library/sensor.py @ludeeus +homeassistant/components/lametric/* @robbiet480 +homeassistant/components/launch_library/* @ludeeus homeassistant/components/lifx/* @amelchio -homeassistant/components/lifx_cloud/scene.py @amelchio -homeassistant/components/lifx_legacy/light.py @amelchio -homeassistant/components/linux_battery/sensor.py @fabaff -homeassistant/components/liveboxplaytv/media_player.py @pschmitt +homeassistant/components/lifx_cloud/* @amelchio +homeassistant/components/lifx_legacy/* @amelchio +homeassistant/components/linux_battery/* @fabaff +homeassistant/components/liveboxplaytv/* @pschmitt +homeassistant/components/logger/* @home-assistant/core +homeassistant/components/lovelace/* @home-assistant/core homeassistant/components/luftdaten/* @fabaff - -# M -homeassistant/components/mastodon/notify.py @fabaff +homeassistant/components/mastodon/* @fabaff homeassistant/components/matrix/* @tinloaf -homeassistant/components/mediaroom/media_player.py @dgomes +homeassistant/components/mediaroom/* @dgomes homeassistant/components/melissa/* @kennedyshead -homeassistant/components/met/weather.py @danielhiversen -homeassistant/components/miflora/sensor.py @danielhiversen @ChristianKuehnel -homeassistant/components/mill/climate.py @danielhiversen -homeassistant/components/min_max/sensor.py @fabaff +homeassistant/components/met/* @danielhiversen +homeassistant/components/miflora/* @danielhiversen @ChristianKuehnel +homeassistant/components/mill/* @danielhiversen +homeassistant/components/min_max/* @fabaff homeassistant/components/mobile_app/* @robbiet480 -homeassistant/components/monoprice/media_player.py @etsinko -homeassistant/components/moon/sensor.py @fabaff -homeassistant/components/mpd/media_player.py @fabaff +homeassistant/components/monoprice/* @etsinko +homeassistant/components/moon/* @fabaff +homeassistant/components/mpd/* @fabaff +homeassistant/components/mqtt/* @home-assistant/core homeassistant/components/mystrom/* @fabaff - -# N -homeassistant/components/nello/lock.py @pschmitt +homeassistant/components/nello/* @pschmitt homeassistant/components/ness_alarm/* @nickw444 homeassistant/components/nest/* @awarecan -homeassistant/components/netdata/sensor.py @fabaff +homeassistant/components/netdata/* @fabaff homeassistant/components/nissan_leaf/* @filcole -homeassistant/components/nmbs/sensor.py @thibmaek +homeassistant/components/nmbs/* @thibmaek homeassistant/components/no_ip/* @fabaff -homeassistant/components/nuki/lock.py @pschmitt -homeassistant/components/nsw_fuel_station/sensor.py @nickw444 - -# O -homeassistant/components/ohmconnect/sensor.py @robbiet480 +homeassistant/components/notify/* @flowolf +homeassistant/components/nsw_fuel_station/* @nickw444 +homeassistant/components/nuki/* @pschmitt +homeassistant/components/ohmconnect/* @robbiet480 +homeassistant/components/onboarding/* @home-assistant/core homeassistant/components/openuv/* @bachya -homeassistant/components/openweathermap/weather.py @fabaff +homeassistant/components/openweathermap/* @fabaff homeassistant/components/owlet/* @oblogic7 - -# P -homeassistant/components/pi_hole/sensor.py @fabaff +homeassistant/components/panel_custom/* @home-assistant/core +homeassistant/components/panel_iframe/* @home-assistant/core +homeassistant/components/persistent_notification/* @home-assistant/core +homeassistant/components/pi_hole/* @fabaff homeassistant/components/plant/* @ChristianKuehnel homeassistant/components/point/* @fredrike -homeassistant/components/pollen/sensor.py @bachya -homeassistant/components/push/camera.py @dgomes -homeassistant/components/pvoutput/sensor.py @fabaff - -# Q -homeassistant/components/qnap/sensor.py @colinodell -homeassistant/components/quantum_gateway/device_tracker.py @cisasteelersfan +homeassistant/components/pollen/* @bachya +homeassistant/components/push/* @dgomes +homeassistant/components/pvoutput/* @fabaff +homeassistant/components/qnap/* @colinodell +homeassistant/components/quantum_gateway/* @cisasteelersfan homeassistant/components/qwikswitch/* @kellerza - -# R homeassistant/components/rainmachine/* @bachya homeassistant/components/random/* @fabaff homeassistant/components/rfxtrx/* @danielhiversen homeassistant/components/rmvtransport/* @cgtobi -homeassistant/components/roomba/vacuum.py @pschmitt -homeassistant/components/ruter/sensor.py @ludeeus - -# S -homeassistant/components/scrape/sensor.py @fabaff -homeassistant/components/sensibo/climate.py @andrey-git -homeassistant/components/serial/sensor.py @fabaff -homeassistant/components/seventeentrack/sensor.py @bachya +homeassistant/components/roomba/* @pschmitt +homeassistant/components/ruter/* @ludeeus +homeassistant/components/scene/* @home-assistant/core +homeassistant/components/scrape/* @fabaff +homeassistant/components/script/* @home-assistant/core +homeassistant/components/sensibo/* @andrey-git +homeassistant/components/serial/* @fabaff +homeassistant/components/seventeentrack/* @bachya +homeassistant/components/shell_command/* @home-assistant/core homeassistant/components/shiftr/* @fabaff -homeassistant/components/shodan/sensor.py @fabaff +homeassistant/components/shodan/* @fabaff homeassistant/components/simplisafe/* @bachya -homeassistant/components/sma/sensor.py @kellerza +homeassistant/components/sma/* @kellerza homeassistant/components/smartthings/* @andrewsayre -homeassistant/components/smtp/notify.py @fabaff +homeassistant/components/smtp/* @fabaff homeassistant/components/sonos/* @amelchio homeassistant/components/spaceapi/* @fabaff homeassistant/components/spider/* @peternijssen -homeassistant/components/sql/sensor.py @dgomes -homeassistant/components/statistics/sensor.py @fabaff -homeassistant/components/swiss_public_transport/* @fabaff +homeassistant/components/sql/* @dgomes +homeassistant/components/statistics/* @fabaff +homeassistant/components/sun/* @home-assistant/core homeassistant/components/swiss_hydrological_data/* @fabaff -homeassistant/components/switchbot/switch.py @danielhiversen -homeassistant/components/switchmate/switch.py @danielhiversen -homeassistant/components/synology_srm/device_tracker.py @aerialls -homeassistant/components/syslog/notify.py @fabaff -homeassistant/components/sytadin/sensor.py @gautric - -# T +homeassistant/components/swiss_public_transport/* @fabaff +homeassistant/components/switchbot/* @danielhiversen +homeassistant/components/switchmate/* @danielhiversen +homeassistant/components/synology_srm/* @aerialls +homeassistant/components/syslog/* @fabaff +homeassistant/components/sytadin/* @gautric homeassistant/components/tahoma/* @philklei -homeassistant/components/tautulli/sensor.py @ludeeus +homeassistant/components/tautulli/* @ludeeus homeassistant/components/tellduslive/* @fredrike -homeassistant/components/template/cover.py @PhracturedBlue +homeassistant/components/template/* @PhracturedBlue homeassistant/components/tesla/* @zabuldon homeassistant/components/tfiac/* @fredrike @mellado homeassistant/components/thethingsnetwork/* @fabaff -homeassistant/components/threshold/binary_sensor.py @fabaff +homeassistant/components/threshold/* @fabaff homeassistant/components/tibber/* @danielhiversen -homeassistant/components/tile/device_tracker.py @bachya -homeassistant/components/time_date/sensor.py @fabaff +homeassistant/components/tile/* @bachya +homeassistant/components/time_date/* @fabaff homeassistant/components/toon/* @frenck homeassistant/components/tplink/* @rytilahti -homeassistant/components/traccar/device_tracker.py @ludeeus +homeassistant/components/traccar/* @ludeeus homeassistant/components/tradfri/* @ggravlingen -homeassistant/components/twilio_call/notify.py @robbiet480 -homeassistant/components/twilio_sms/notify.py @robbiet480 - -# U -homeassistant/components/uber/sensor.py @robbiet480 +homeassistant/components/tts/* @robbiet480 +homeassistant/components/twilio_call/* @robbiet480 +homeassistant/components/twilio_sms/* @robbiet480 +homeassistant/components/uber/* @robbiet480 homeassistant/components/unifi/* @kane610 homeassistant/components/upcloud/* @scop +homeassistant/components/updater/* @home-assistant/core homeassistant/components/upnp/* @robbiet480 -homeassistant/components/uptimerobot/binary_sensor.py @ludeeus +homeassistant/components/uptimerobot/* @ludeeus homeassistant/components/utility_meter/* @dgomes - -# V homeassistant/components/velux/* @Julius2342 -homeassistant/components/version/sensor.py @fabaff - -# W -homeassistant/components/waqi/sensor.py @andrey-git -homeassistant/components/weather/__init__.py @fabaff +homeassistant/components/version/* @fabaff +homeassistant/components/waqi/* @andrey-git +homeassistant/components/weather/* @fabaff +homeassistant/components/weblink/* @home-assistant/core +homeassistant/components/websocket_api/* @home-assistant/core homeassistant/components/wemo/* @sqldiablo -homeassistant/components/worldclock/sensor.py @fabaff - -# X -homeassistant/components/xfinity/device_tracker.py @cisasteelersfan +homeassistant/components/worldclock/* @fabaff +homeassistant/components/xfinity/* @cisasteelersfan homeassistant/components/xiaomi_aqara/* @danielhiversen @syssi homeassistant/components/xiaomi_miio/* @rytilahti @syssi -homeassistant/components/xiaomi_tv/media_player.py @fattdev -homeassistant/components/xmpp/notify.py @fabaff - -# Y +homeassistant/components/xiaomi_tv/* @fattdev +homeassistant/components/xmpp/* @fabaff homeassistant/components/yamaha_musiccast/* @jalmeroth homeassistant/components/yeelight/* @rytilahti @zewelor -homeassistant/components/yeelightsunflower/light.py @lindsaymarkward -homeassistant/components/yessssms/notify.py @flowolf -homeassistant/components/yi/camera.py @bachya - -# Z +homeassistant/components/yeelightsunflower/* @lindsaymarkward +homeassistant/components/yessssms/* @flowolf +homeassistant/components/yi/* @bachya homeassistant/components/zeroconf/* @robbiet480 homeassistant/components/zha/* @dmulcahey @adminiuga +homeassistant/components/zone/* @home-assistant/core homeassistant/components/zoneminder/* @rohankapoorcom - -# Other code -homeassistant/scripts/check_config.py @kellerza +homeassistant/components/zwave/* @home-assistant/z-wave diff --git a/script/manifest/codeowners.py b/script/manifest/codeowners.py new file mode 100755 index 00000000000..9745f3b82f2 --- /dev/null +++ b/script/manifest/codeowners.py @@ -0,0 +1,66 @@ +#!/usr/bin/env python3 +"""Generate CODEOWNERS.""" +import os +import sys + +from manifest_helper import iter_manifests + +BASE = """ +# This file is generated by script/manifest/codeowners.py +# People marked here will be automatically requested for a review +# when the code that they own is touched. +# https://github.com/blog/2392-introducing-code-owners + +# Home Assistant Core +setup.py @home-assistant/core +homeassistant/*.py @home-assistant/core +homeassistant/helpers/* @home-assistant/core +homeassistant/util/* @home-assistant/core + +# Virtualization +Dockerfile @home-assistant/docker +virtualization/Docker/* @home-assistant/docker + +# Other code +homeassistant/scripts/check_config.py @kellerza + +# Integrations +""" + + +def generate(): + """Generate CODEOWNERS.""" + parts = [BASE.strip()] + + for manifest in iter_manifests(): + if not manifest['codeowners']: + continue + + parts.append("homeassistant/components/{}/* {}".format( + manifest['domain'], ' '.join(manifest['codeowners']))) + + return '\n'.join(parts) + + +def main(validate): + """Runner for CODEOWNERS gen.""" + if not os.path.isfile('requirements_all.txt'): + print('Run this from HA root dir') + return 1 + + content = generate() + + if validate: + with open('CODEOWNERS', 'r') as fp: + if fp.read().strip() != content: + print("CODEOWNERS is not up to date. " + "Run python script/manifest/codeowners.py") + return 1 + return 0 + + with open('CODEOWNERS', 'w') as fp: + fp.write(content + '\n') + + +if __name__ == '__main__': + sys.exit(main(sys.argv[-1] == 'validate')) diff --git a/script/manifest/manifest_helper.py b/script/manifest/manifest_helper.py new file mode 100644 index 00000000000..3b4cfa11796 --- /dev/null +++ b/script/manifest/manifest_helper.py @@ -0,0 +1,15 @@ +"""Helpers to deal with manifests.""" +import json +import pathlib + + +component_dir = pathlib.Path('homeassistant/components') + + +def iter_manifests(): + """Iterate over all available manifests.""" + manifests = [ + json.loads(fil.read_text()) + for fil in component_dir.glob('*/manifest.json') + ] + return sorted(manifests, key=lambda man: man['domain'])