mirror of
https://github.com/esphome/esphome.git
synced 2024-11-25 08:28:12 +01:00
Add CODEOWNERS mechanism (#1199)
This commit is contained in:
parent
5887fe8302
commit
4996967c79
48 changed files with 195 additions and 8 deletions
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
|
@ -143,6 +143,8 @@ jobs:
|
||||||
run: script/ci-custom.py
|
run: script/ci-custom.py
|
||||||
- name: Lint Python
|
- name: Lint Python
|
||||||
run: script/lint-python
|
run: script/lint-python
|
||||||
|
- name: Lint CODEOWNERS
|
||||||
|
run: script/build_codeowners.py --check
|
||||||
|
|
||||||
test:
|
test:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
2
.github/workflows/release-dev.yml
vendored
2
.github/workflows/release-dev.yml
vendored
|
@ -98,6 +98,8 @@ jobs:
|
||||||
run: script/ci-custom.py
|
run: script/ci-custom.py
|
||||||
- name: Lint Python
|
- name: Lint Python
|
||||||
run: script/lint-python
|
run: script/lint-python
|
||||||
|
- name: Lint CODEOWNERS
|
||||||
|
run: script/build_codeowners.py --check
|
||||||
|
|
||||||
test:
|
test:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
|
@ -97,6 +97,8 @@ jobs:
|
||||||
run: script/ci-custom.py
|
run: script/ci-custom.py
|
||||||
- name: Lint Python
|
- name: Lint Python
|
||||||
run: script/lint-python
|
run: script/lint-python
|
||||||
|
- name: Lint CODEOWNERS
|
||||||
|
run: script/build_codeowners.py --check
|
||||||
|
|
||||||
test:
|
test:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
54
CODEOWNERS
Normal file
54
CODEOWNERS
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
# This file is generated by script/build_codeowners.py
|
||||||
|
# People marked here will be automatically requested for a review
|
||||||
|
# when the code that they own is touched.
|
||||||
|
#
|
||||||
|
# Every time an issue is created with a label corresponding to an integration,
|
||||||
|
# the integration's code owner is automatically notified.
|
||||||
|
|
||||||
|
# Core Code
|
||||||
|
setup.py @esphome/core
|
||||||
|
esphome/*.py @esphome/core
|
||||||
|
esphome/core/* @esphome/core
|
||||||
|
|
||||||
|
# Integrations
|
||||||
|
esphome/components/adc/* @esphome/core
|
||||||
|
esphome/components/api/* @OttoWinter
|
||||||
|
esphome/components/async_tcp/* @OttoWinter
|
||||||
|
esphome/components/bang_bang/* @OttoWinter
|
||||||
|
esphome/components/binary_sensor/* @esphome/core
|
||||||
|
esphome/components/captive_portal/* @OttoWinter
|
||||||
|
esphome/components/climate/* @esphome/core
|
||||||
|
esphome/components/cover/* @esphome/core
|
||||||
|
esphome/components/debug/* @OttoWinter
|
||||||
|
esphome/components/dht/* @OttoWinter
|
||||||
|
esphome/components/exposure_notifications/* @OttoWinter
|
||||||
|
esphome/components/fastled_base/* @OttoWinter
|
||||||
|
esphome/components/globals/* @esphome/core
|
||||||
|
esphome/components/gpio/* @esphome/core
|
||||||
|
esphome/components/homeassistant/* @OttoWinter
|
||||||
|
esphome/components/i2c/* @esphome/core
|
||||||
|
esphome/components/integration/* @OttoWinter
|
||||||
|
esphome/components/interval/* @esphome/core
|
||||||
|
esphome/components/json/* @OttoWinter
|
||||||
|
esphome/components/ledc/* @OttoWinter
|
||||||
|
esphome/components/light/* @esphome/core
|
||||||
|
esphome/components/logger/* @esphome/core
|
||||||
|
esphome/components/network/* @esphome/core
|
||||||
|
esphome/components/ota/* @esphome/core
|
||||||
|
esphome/components/output/* @esphome/core
|
||||||
|
esphome/components/pid/* @OttoWinter
|
||||||
|
esphome/components/pn532/* @OttoWinter
|
||||||
|
esphome/components/power_supply/* @esphome/core
|
||||||
|
esphome/components/restart/* @esphome/core
|
||||||
|
esphome/components/script/* @esphome/core
|
||||||
|
esphome/components/sensor/* @esphome/core
|
||||||
|
esphome/components/shutdown/* @esphome/core
|
||||||
|
esphome/components/spi/* @esphome/core
|
||||||
|
esphome/components/substitutions/* @esphome/core
|
||||||
|
esphome/components/sun/* @OttoWinter
|
||||||
|
esphome/components/switch/* @esphome/core
|
||||||
|
esphome/components/time/* @OttoWinter
|
||||||
|
esphome/components/uart/* @esphome/core
|
||||||
|
esphome/components/ultrasonic/* @OttoWinter
|
||||||
|
esphome/components/version/* @esphome/core
|
||||||
|
esphome/components/web_server_base/* @OttoWinter
|
|
@ -0,0 +1 @@
|
||||||
|
CODEOWNERS = ['@esphome/core']
|
|
@ -8,6 +8,7 @@ from esphome.core import coroutine_with_priority
|
||||||
|
|
||||||
DEPENDENCIES = ['network']
|
DEPENDENCIES = ['network']
|
||||||
AUTO_LOAD = ['async_tcp']
|
AUTO_LOAD = ['async_tcp']
|
||||||
|
CODEOWNERS = ['@OttoWinter']
|
||||||
|
|
||||||
api_ns = cg.esphome_ns.namespace('api')
|
api_ns = cg.esphome_ns.namespace('api')
|
||||||
APIServer = api_ns.class_('APIServer', cg.Component, cg.Controller)
|
APIServer = api_ns.class_('APIServer', cg.Component, cg.Controller)
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
import esphome.codegen as cg
|
import esphome.codegen as cg
|
||||||
from esphome.core import CORE, coroutine_with_priority
|
from esphome.core import CORE, coroutine_with_priority
|
||||||
|
|
||||||
|
CODEOWNERS = ['@OttoWinter']
|
||||||
|
|
||||||
|
|
||||||
@coroutine_with_priority(200.0)
|
@coroutine_with_priority(200.0)
|
||||||
def to_code(config):
|
def to_code(config):
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
CODEOWNERS = ['@OttoWinter']
|
|
@ -11,6 +11,7 @@ from esphome.const import CONF_DEVICE_CLASS, CONF_FILTERS, \
|
||||||
from esphome.core import CORE, coroutine, coroutine_with_priority
|
from esphome.core import CORE, coroutine, coroutine_with_priority
|
||||||
from esphome.util import Registry
|
from esphome.util import Registry
|
||||||
|
|
||||||
|
CODEOWNERS = ['@esphome/core']
|
||||||
DEVICE_CLASSES = [
|
DEVICE_CLASSES = [
|
||||||
'', 'battery', 'cold', 'connectivity', 'door', 'garage_door', 'gas',
|
'', 'battery', 'cold', 'connectivity', 'door', 'garage_door', 'gas',
|
||||||
'heat', 'light', 'lock', 'moisture', 'motion', 'moving', 'occupancy',
|
'heat', 'light', 'lock', 'moisture', 'motion', 'moving', 'occupancy',
|
||||||
|
|
|
@ -7,6 +7,7 @@ from esphome.core import coroutine_with_priority
|
||||||
|
|
||||||
AUTO_LOAD = ['web_server_base']
|
AUTO_LOAD = ['web_server_base']
|
||||||
DEPENDENCIES = ['wifi']
|
DEPENDENCIES = ['wifi']
|
||||||
|
CODEOWNERS = ['@OttoWinter']
|
||||||
|
|
||||||
captive_portal_ns = cg.esphome_ns.namespace('captive_portal')
|
captive_portal_ns = cg.esphome_ns.namespace('captive_portal')
|
||||||
CaptivePortal = captive_portal_ns.class_('CaptivePortal', cg.Component)
|
CaptivePortal = captive_portal_ns.class_('CaptivePortal', cg.Component)
|
||||||
|
|
|
@ -10,6 +10,7 @@ from esphome.core import CORE, coroutine, coroutine_with_priority
|
||||||
|
|
||||||
IS_PLATFORM_COMPONENT = True
|
IS_PLATFORM_COMPONENT = True
|
||||||
|
|
||||||
|
CODEOWNERS = ['@esphome/core']
|
||||||
climate_ns = cg.esphome_ns.namespace('climate')
|
climate_ns = cg.esphome_ns.namespace('climate')
|
||||||
|
|
||||||
Climate = climate_ns.class_('Climate', cg.Nameable)
|
Climate = climate_ns.class_('Climate', cg.Nameable)
|
||||||
|
|
|
@ -9,6 +9,7 @@ from esphome.core import CORE, coroutine, coroutine_with_priority
|
||||||
|
|
||||||
IS_PLATFORM_COMPONENT = True
|
IS_PLATFORM_COMPONENT = True
|
||||||
|
|
||||||
|
CODEOWNERS = ['@esphome/core']
|
||||||
DEVICE_CLASSES = [
|
DEVICE_CLASSES = [
|
||||||
'', 'awning', 'blind', 'curtain', 'damper', 'door', 'garage',
|
'', 'awning', 'blind', 'curtain', 'damper', 'door', 'garage',
|
||||||
'gate', 'shade', 'shutter', 'window'
|
'gate', 'shade', 'shutter', 'window'
|
||||||
|
|
|
@ -2,6 +2,7 @@ import esphome.config_validation as cv
|
||||||
import esphome.codegen as cg
|
import esphome.codegen as cg
|
||||||
from esphome.const import CONF_ID
|
from esphome.const import CONF_ID
|
||||||
|
|
||||||
|
CODEOWNERS = ['@OttoWinter']
|
||||||
DEPENDENCIES = ['logger']
|
DEPENDENCIES = ['logger']
|
||||||
|
|
||||||
debug_ns = cg.esphome_ns.namespace('debug')
|
debug_ns = cg.esphome_ns.namespace('debug')
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
CODEOWNERS = ['@OttoWinter']
|
|
@ -4,6 +4,7 @@ import esphome.config_validation as cv
|
||||||
from esphome.components import esp32_ble_tracker
|
from esphome.components import esp32_ble_tracker
|
||||||
from esphome.const import CONF_TRIGGER_ID
|
from esphome.const import CONF_TRIGGER_ID
|
||||||
|
|
||||||
|
CODEOWNERS = ['@OttoWinter']
|
||||||
DEPENDENCIES = ['esp32_ble_tracker']
|
DEPENDENCIES = ['esp32_ble_tracker']
|
||||||
|
|
||||||
exposure_notifications_ns = cg.esphome_ns.namespace('exposure_notifications')
|
exposure_notifications_ns = cg.esphome_ns.namespace('exposure_notifications')
|
||||||
|
|
|
@ -4,6 +4,7 @@ from esphome.components import light
|
||||||
from esphome.const import CONF_OUTPUT_ID, CONF_NUM_LEDS, CONF_RGB_ORDER, CONF_MAX_REFRESH_RATE
|
from esphome.const import CONF_OUTPUT_ID, CONF_NUM_LEDS, CONF_RGB_ORDER, CONF_MAX_REFRESH_RATE
|
||||||
from esphome.core import coroutine
|
from esphome.core import coroutine
|
||||||
|
|
||||||
|
CODEOWNERS = ['@OttoWinter']
|
||||||
fastled_base_ns = cg.esphome_ns.namespace('fastled_base')
|
fastled_base_ns = cg.esphome_ns.namespace('fastled_base')
|
||||||
FastLEDLightOutput = fastled_base_ns.class_('FastLEDLightOutput', light.AddressableLight)
|
FastLEDLightOutput = fastled_base_ns.class_('FastLEDLightOutput', light.AddressableLight)
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ from esphome import codegen as cg
|
||||||
from esphome.const import CONF_ID, CONF_INITIAL_VALUE, CONF_RESTORE_VALUE, CONF_TYPE, CONF_VALUE
|
from esphome.const import CONF_ID, CONF_INITIAL_VALUE, CONF_RESTORE_VALUE, CONF_TYPE, CONF_VALUE
|
||||||
from esphome.core import coroutine_with_priority
|
from esphome.core import coroutine_with_priority
|
||||||
|
|
||||||
|
CODEOWNERS = ['@esphome/core']
|
||||||
globals_ns = cg.esphome_ns.namespace('globals')
|
globals_ns = cg.esphome_ns.namespace('globals')
|
||||||
GlobalsComponent = globals_ns.class_('GlobalsComponent', cg.Component)
|
GlobalsComponent = globals_ns.class_('GlobalsComponent', cg.Component)
|
||||||
GlobalVarSetAction = globals_ns.class_('GlobalVarSetAction', automation.Action)
|
GlobalVarSetAction = globals_ns.class_('GlobalVarSetAction', automation.Action)
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
import esphome.codegen as cg
|
import esphome.codegen as cg
|
||||||
|
|
||||||
|
CODEOWNERS = ['@esphome/core']
|
||||||
gpio_ns = cg.esphome_ns.namespace('gpio')
|
gpio_ns = cg.esphome_ns.namespace('gpio')
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
import esphome.codegen as cg
|
import esphome.codegen as cg
|
||||||
|
|
||||||
|
CODEOWNERS = ['@OttoWinter']
|
||||||
homeassistant_ns = cg.esphome_ns.namespace('homeassistant')
|
homeassistant_ns = cg.esphome_ns.namespace('homeassistant')
|
||||||
|
|
|
@ -5,6 +5,7 @@ from esphome.const import CONF_FREQUENCY, CONF_ID, CONF_SCAN, CONF_SCL, CONF_SDA
|
||||||
CONF_I2C_ID
|
CONF_I2C_ID
|
||||||
from esphome.core import coroutine, coroutine_with_priority
|
from esphome.core import coroutine, coroutine_with_priority
|
||||||
|
|
||||||
|
CODEOWNERS = ['@esphome/core']
|
||||||
i2c_ns = cg.esphome_ns.namespace('i2c')
|
i2c_ns = cg.esphome_ns.namespace('i2c')
|
||||||
I2CComponent = i2c_ns.class_('I2CComponent', cg.Component)
|
I2CComponent = i2c_ns.class_('I2CComponent', cg.Component)
|
||||||
I2CDevice = i2c_ns.class_('I2CDevice')
|
I2CDevice = i2c_ns.class_('I2CDevice')
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
CODEOWNERS = ['@OttoWinter']
|
|
@ -3,6 +3,7 @@ import esphome.config_validation as cv
|
||||||
from esphome import automation
|
from esphome import automation
|
||||||
from esphome.const import CONF_ID, CONF_INTERVAL
|
from esphome.const import CONF_ID, CONF_INTERVAL
|
||||||
|
|
||||||
|
CODEOWNERS = ['@esphome/core']
|
||||||
interval_ns = cg.esphome_ns.namespace('interval')
|
interval_ns = cg.esphome_ns.namespace('interval')
|
||||||
IntervalTrigger = interval_ns.class_('IntervalTrigger', automation.Trigger.template(),
|
IntervalTrigger = interval_ns.class_('IntervalTrigger', automation.Trigger.template(),
|
||||||
cg.PollingComponent)
|
cg.PollingComponent)
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import esphome.codegen as cg
|
import esphome.codegen as cg
|
||||||
from esphome.core import coroutine_with_priority
|
from esphome.core import coroutine_with_priority
|
||||||
|
|
||||||
|
CODEOWNERS = ['@OttoWinter']
|
||||||
json_ns = cg.esphome_ns.namespace('json')
|
json_ns = cg.esphome_ns.namespace('json')
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
CODEOWNERS = ['@OttoWinter']
|
|
@ -14,6 +14,7 @@ from .types import ( # noqa
|
||||||
LightState, AddressableLightState, light_ns, LightOutput, AddressableLight, \
|
LightState, AddressableLightState, light_ns, LightOutput, AddressableLight, \
|
||||||
LightTurnOnTrigger, LightTurnOffTrigger)
|
LightTurnOnTrigger, LightTurnOffTrigger)
|
||||||
|
|
||||||
|
CODEOWNERS = ['@esphome/core']
|
||||||
IS_PLATFORM_COMPONENT = True
|
IS_PLATFORM_COMPONENT = True
|
||||||
|
|
||||||
LightRestoreMode = light_ns.enum('LightRestoreMode')
|
LightRestoreMode = light_ns.enum('LightRestoreMode')
|
||||||
|
|
|
@ -8,6 +8,7 @@ from esphome.const import CONF_ARGS, CONF_BAUD_RATE, CONF_FORMAT, CONF_HARDWARE_
|
||||||
CONF_LEVEL, CONF_LOGS, CONF_ON_MESSAGE, CONF_TAG, CONF_TRIGGER_ID, CONF_TX_BUFFER_SIZE
|
CONF_LEVEL, CONF_LOGS, CONF_ON_MESSAGE, CONF_TAG, CONF_TRIGGER_ID, CONF_TX_BUFFER_SIZE
|
||||||
from esphome.core import CORE, EsphomeError, Lambda, coroutine_with_priority
|
from esphome.core import CORE, EsphomeError, Lambda, coroutine_with_priority
|
||||||
|
|
||||||
|
CODEOWNERS = ['@esphome/core']
|
||||||
logger_ns = cg.esphome_ns.namespace('logger')
|
logger_ns = cg.esphome_ns.namespace('logger')
|
||||||
LOG_LEVELS = {
|
LOG_LEVELS = {
|
||||||
'NONE': cg.global_ns.ESPHOME_LOG_LEVEL_NONE,
|
'NONE': cg.global_ns.ESPHOME_LOG_LEVEL_NONE,
|
||||||
|
|
|
@ -1 +1,2 @@
|
||||||
# Dummy package to allow components to depend on network
|
# Dummy package to allow components to depend on network
|
||||||
|
CODEOWNERS = ['@esphome/core']
|
||||||
|
|
|
@ -3,6 +3,7 @@ import esphome.config_validation as cv
|
||||||
from esphome.const import CONF_ID, CONF_PASSWORD, CONF_PORT, CONF_SAFE_MODE
|
from esphome.const import CONF_ID, CONF_PASSWORD, CONF_PORT, CONF_SAFE_MODE
|
||||||
from esphome.core import CORE, coroutine_with_priority
|
from esphome.core import CORE, coroutine_with_priority
|
||||||
|
|
||||||
|
CODEOWNERS = ['@esphome/core']
|
||||||
DEPENDENCIES = ['network']
|
DEPENDENCIES = ['network']
|
||||||
|
|
||||||
ota_ns = cg.esphome_ns.namespace('ota')
|
ota_ns = cg.esphome_ns.namespace('ota')
|
||||||
|
|
|
@ -7,6 +7,8 @@ from esphome.const import CONF_ID, CONF_INVERTED, CONF_LEVEL, CONF_MAX_POWER, \
|
||||||
CONF_MIN_POWER, CONF_POWER_SUPPLY
|
CONF_MIN_POWER, CONF_POWER_SUPPLY
|
||||||
from esphome.core import CORE, coroutine
|
from esphome.core import CORE, coroutine
|
||||||
|
|
||||||
|
|
||||||
|
CODEOWNERS = ['@esphome/core']
|
||||||
IS_PLATFORM_COMPONENT = True
|
IS_PLATFORM_COMPONENT = True
|
||||||
|
|
||||||
BINARY_OUTPUT_SCHEMA = cv.Schema({
|
BINARY_OUTPUT_SCHEMA = cv.Schema({
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
CODEOWNERS = ['@OttoWinter']
|
|
@ -4,6 +4,7 @@ from esphome import automation
|
||||||
from esphome.components import spi
|
from esphome.components import spi
|
||||||
from esphome.const import CONF_ID, CONF_ON_TAG, CONF_TRIGGER_ID
|
from esphome.const import CONF_ID, CONF_ON_TAG, CONF_TRIGGER_ID
|
||||||
|
|
||||||
|
CODEOWNERS = ['@OttoWinter']
|
||||||
DEPENDENCIES = ['spi']
|
DEPENDENCIES = ['spi']
|
||||||
AUTO_LOAD = ['binary_sensor']
|
AUTO_LOAD = ['binary_sensor']
|
||||||
MULTI_CONF = True
|
MULTI_CONF = True
|
||||||
|
|
|
@ -3,6 +3,7 @@ import esphome.config_validation as cv
|
||||||
from esphome import pins
|
from esphome import pins
|
||||||
from esphome.const import CONF_ENABLE_TIME, CONF_ID, CONF_KEEP_ON_TIME, CONF_PIN
|
from esphome.const import CONF_ENABLE_TIME, CONF_ID, CONF_KEEP_ON_TIME, CONF_PIN
|
||||||
|
|
||||||
|
CODEOWNERS = ['@esphome/core']
|
||||||
power_supply_ns = cg.esphome_ns.namespace('power_supply')
|
power_supply_ns = cg.esphome_ns.namespace('power_supply')
|
||||||
PowerSupply = power_supply_ns.class_('PowerSupply', cg.Component)
|
PowerSupply = power_supply_ns.class_('PowerSupply', cg.Component)
|
||||||
MULTI_CONF = True
|
MULTI_CONF = True
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
CODEOWNERS = ['@esphome/core']
|
|
@ -4,6 +4,7 @@ from esphome import automation
|
||||||
from esphome.automation import maybe_simple_id
|
from esphome.automation import maybe_simple_id
|
||||||
from esphome.const import CONF_ID, CONF_MODE
|
from esphome.const import CONF_ID, CONF_MODE
|
||||||
|
|
||||||
|
CODEOWNERS = ['@esphome/core']
|
||||||
script_ns = cg.esphome_ns.namespace('script')
|
script_ns = cg.esphome_ns.namespace('script')
|
||||||
Script = script_ns.class_('Script', automation.Trigger.template())
|
Script = script_ns.class_('Script', automation.Trigger.template())
|
||||||
ScriptExecuteAction = script_ns.class_('ScriptExecuteAction', automation.Action)
|
ScriptExecuteAction = script_ns.class_('ScriptExecuteAction', automation.Action)
|
||||||
|
|
|
@ -12,6 +12,7 @@ from esphome.const import CONF_ABOVE, CONF_ACCURACY_DECIMALS, CONF_ALPHA, CONF_B
|
||||||
from esphome.core import CORE, coroutine, coroutine_with_priority
|
from esphome.core import CORE, coroutine, coroutine_with_priority
|
||||||
from esphome.util import Registry
|
from esphome.util import Registry
|
||||||
|
|
||||||
|
CODEOWNERS = ['@esphome/core']
|
||||||
IS_PLATFORM_COMPONENT = True
|
IS_PLATFORM_COMPONENT = True
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
CODEOWNERS = ['@esphome/core']
|
|
@ -5,6 +5,7 @@ from esphome.const import CONF_CLK_PIN, CONF_ID, CONF_MISO_PIN, CONF_MOSI_PIN, C
|
||||||
CONF_CS_PIN
|
CONF_CS_PIN
|
||||||
from esphome.core import coroutine, coroutine_with_priority
|
from esphome.core import coroutine, coroutine_with_priority
|
||||||
|
|
||||||
|
CODEOWNERS = ['@esphome/core']
|
||||||
spi_ns = cg.esphome_ns.namespace('spi')
|
spi_ns = cg.esphome_ns.namespace('spi')
|
||||||
SPIComponent = spi_ns.class_('SPIComponent', cg.Component)
|
SPIComponent = spi_ns.class_('SPIComponent', cg.Component)
|
||||||
SPIDevice = spi_ns.class_('SPIDevice')
|
SPIDevice = spi_ns.class_('SPIDevice')
|
||||||
|
|
|
@ -5,6 +5,7 @@ import esphome.config_validation as cv
|
||||||
from esphome import core
|
from esphome import core
|
||||||
from esphome.const import CONF_SUBSTITUTIONS
|
from esphome.const import CONF_SUBSTITUTIONS
|
||||||
|
|
||||||
|
CODEOWNERS = ['@esphome/core']
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
VALID_SUBSTITUTIONS_CHARACTERS = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' \
|
VALID_SUBSTITUTIONS_CHARACTERS = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' \
|
||||||
|
|
|
@ -4,6 +4,7 @@ from esphome import automation
|
||||||
from esphome.components import time
|
from esphome.components import time
|
||||||
from esphome.const import CONF_TIME_ID, CONF_ID, CONF_TRIGGER_ID
|
from esphome.const import CONF_TIME_ID, CONF_ID, CONF_TRIGGER_ID
|
||||||
|
|
||||||
|
CODEOWNERS = ['@OttoWinter']
|
||||||
sun_ns = cg.esphome_ns.namespace('sun')
|
sun_ns = cg.esphome_ns.namespace('sun')
|
||||||
|
|
||||||
Sun = sun_ns.class_('Sun')
|
Sun = sun_ns.class_('Sun')
|
||||||
|
|
|
@ -7,6 +7,7 @@ from esphome.const import CONF_ICON, CONF_ID, CONF_INTERNAL, CONF_INVERTED, CONF
|
||||||
CONF_ON_TURN_ON, CONF_TRIGGER_ID, CONF_MQTT_ID, CONF_NAME
|
CONF_ON_TURN_ON, CONF_TRIGGER_ID, CONF_MQTT_ID, CONF_NAME
|
||||||
from esphome.core import CORE, coroutine, coroutine_with_priority
|
from esphome.core import CORE, coroutine, coroutine_with_priority
|
||||||
|
|
||||||
|
CODEOWNERS = ['@esphome/core']
|
||||||
IS_PLATFORM_COMPONENT = True
|
IS_PLATFORM_COMPONENT = True
|
||||||
|
|
||||||
switch_ns = cg.esphome_ns.namespace('switch_')
|
switch_ns = cg.esphome_ns.namespace('switch_')
|
||||||
|
|
|
@ -17,6 +17,7 @@ from esphome.core import coroutine, coroutine_with_priority
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
CODEOWNERS = ['@OttoWinter']
|
||||||
IS_PLATFORM_COMPONENT = True
|
IS_PLATFORM_COMPONENT = True
|
||||||
|
|
||||||
time_ns = cg.esphome_ns.namespace('time')
|
time_ns = cg.esphome_ns.namespace('time')
|
||||||
|
|
|
@ -5,6 +5,7 @@ from esphome.const import CONF_BAUD_RATE, CONF_ID, CONF_RX_PIN, CONF_TX_PIN, CON
|
||||||
CONF_DATA, CONF_RX_BUFFER_SIZE
|
CONF_DATA, CONF_RX_BUFFER_SIZE
|
||||||
from esphome.core import CORE, coroutine
|
from esphome.core import CORE, coroutine
|
||||||
|
|
||||||
|
CODEOWNERS = ['@esphome/core']
|
||||||
uart_ns = cg.esphome_ns.namespace('uart')
|
uart_ns = cg.esphome_ns.namespace('uart')
|
||||||
UARTComponent = uart_ns.class_('UARTComponent', cg.Component)
|
UARTComponent = uart_ns.class_('UARTComponent', cg.Component)
|
||||||
UARTDevice = uart_ns.class_('UARTDevice')
|
UARTDevice = uart_ns.class_('UARTDevice')
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
CODEOWNERS = ['@OttoWinter']
|
|
@ -0,0 +1 @@
|
||||||
|
CODEOWNERS = ['@esphome/core']
|
|
@ -3,6 +3,7 @@ import esphome.codegen as cg
|
||||||
from esphome.const import CONF_ID
|
from esphome.const import CONF_ID
|
||||||
from esphome.core import coroutine_with_priority, CORE
|
from esphome.core import coroutine_with_priority, CORE
|
||||||
|
|
||||||
|
CODEOWNERS = ['@OttoWinter']
|
||||||
DEPENDENCIES = ['network']
|
DEPENDENCIES = ['network']
|
||||||
AUTO_LOAD = ['async_tcp']
|
AUTO_LOAD = ['async_tcp']
|
||||||
|
|
||||||
|
|
|
@ -66,6 +66,10 @@ class ComponentManifest:
|
||||||
def auto_load(self):
|
def auto_load(self):
|
||||||
return getattr(self.module, 'AUTO_LOAD', [])
|
return getattr(self.module, 'AUTO_LOAD', [])
|
||||||
|
|
||||||
|
@property
|
||||||
|
def codeowners(self) -> List[str]:
|
||||||
|
return getattr(self.module, 'CODEOWNERS', [])
|
||||||
|
|
||||||
def _get_flags_set(self, name, config):
|
def _get_flags_set(self, name, config):
|
||||||
if not hasattr(self.module, name):
|
if not hasattr(self.module, name):
|
||||||
return set()
|
return set()
|
||||||
|
|
|
@ -2,6 +2,9 @@ import codecs
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
from pathlib import Path
|
||||||
|
from typing import Union
|
||||||
|
import tempfile
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -168,15 +171,21 @@ def read_file(path):
|
||||||
raise EsphomeError(f"Error reading file {path}: {err}")
|
raise EsphomeError(f"Error reading file {path}: {err}")
|
||||||
|
|
||||||
|
|
||||||
def _write_file(path, text):
|
def _write_file(path: Union[Path, str], text: Union[str, bytes]):
|
||||||
import tempfile
|
"""Atomically writes `text` to the given path.
|
||||||
directory = os.path.dirname(path)
|
|
||||||
mkdir_p(directory)
|
|
||||||
|
|
||||||
tmp_path = None
|
Automatically creates all parent directories.
|
||||||
|
"""
|
||||||
|
if not isinstance(path, Path):
|
||||||
|
path = Path(path)
|
||||||
data = text
|
data = text
|
||||||
if isinstance(text, str):
|
if isinstance(text, str):
|
||||||
data = text.encode()
|
data = text.encode()
|
||||||
|
|
||||||
|
directory = path.parent
|
||||||
|
directory.mkdir(exist_ok=True, parents=True)
|
||||||
|
|
||||||
|
tmp_path = None
|
||||||
try:
|
try:
|
||||||
with tempfile.NamedTemporaryFile(mode="wb", dir=directory, delete=False) as f_handle:
|
with tempfile.NamedTemporaryFile(mode="wb", dir=directory, delete=False) as f_handle:
|
||||||
tmp_path = f_handle.name
|
tmp_path = f_handle.name
|
||||||
|
@ -193,7 +202,7 @@ def _write_file(path, text):
|
||||||
_LOGGER.error("Write file cleanup failed: %s", err)
|
_LOGGER.error("Write file cleanup failed: %s", err)
|
||||||
|
|
||||||
|
|
||||||
def write_file(path, text):
|
def write_file(path: Union[Path, str], text: str):
|
||||||
try:
|
try:
|
||||||
_write_file(path, text)
|
_write_file(path, text)
|
||||||
except OSError:
|
except OSError:
|
||||||
|
@ -201,9 +210,12 @@ def write_file(path, text):
|
||||||
raise EsphomeError(f"Could not write file at {path}")
|
raise EsphomeError(f"Could not write file at {path}")
|
||||||
|
|
||||||
|
|
||||||
def write_file_if_changed(path, text):
|
def write_file_if_changed(path: Union[Path, str], text: str):
|
||||||
|
if not isinstance(path, Path):
|
||||||
|
path = Path(path)
|
||||||
|
|
||||||
src_content = None
|
src_content = None
|
||||||
if os.path.isfile(path):
|
if path.is_file():
|
||||||
src_content = read_file(path)
|
src_content = read_file(path)
|
||||||
if src_content != text:
|
if src_content != text:
|
||||||
write_file(path, text)
|
write_file(path, text)
|
||||||
|
|
68
script/build_codeowners.py
Executable file
68
script/build_codeowners.py
Executable file
|
@ -0,0 +1,68 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
from pathlib import Path
|
||||||
|
import sys
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
from esphome.helpers import write_file_if_changed
|
||||||
|
from esphome.config import get_component
|
||||||
|
from esphome.core import CORE
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument('--check', help="Check if the CODEOWNERS file is up to date.",
|
||||||
|
action='store_true')
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
# The root directory of the repo
|
||||||
|
root = Path(__file__).parent.parent
|
||||||
|
components_dir = root / 'esphome' / 'components'
|
||||||
|
|
||||||
|
BASE = """
|
||||||
|
# This file is generated by script/build_codeowners.py
|
||||||
|
# People marked here will be automatically requested for a review
|
||||||
|
# when the code that they own is touched.
|
||||||
|
#
|
||||||
|
# Every time an issue is created with a label corresponding to an integration,
|
||||||
|
# the integration's code owner is automatically notified.
|
||||||
|
|
||||||
|
# Core Code
|
||||||
|
setup.py @esphome/core
|
||||||
|
esphome/*.py @esphome/core
|
||||||
|
esphome/core/* @esphome/core
|
||||||
|
|
||||||
|
# Integrations
|
||||||
|
""".strip()
|
||||||
|
|
||||||
|
parts = [BASE]
|
||||||
|
|
||||||
|
# Fake some diretory so that get_component works
|
||||||
|
CORE.config_path = str(root)
|
||||||
|
|
||||||
|
for path in sorted(components_dir.iterdir()):
|
||||||
|
if not path.is_dir():
|
||||||
|
continue
|
||||||
|
if not (path / '__init__.py').is_file():
|
||||||
|
continue
|
||||||
|
name = path.name
|
||||||
|
comp = get_component(name)
|
||||||
|
if comp.codeowners:
|
||||||
|
for owner in comp.codeowners:
|
||||||
|
if not owner.startswith('@'):
|
||||||
|
print(f"Codeowner {owner} for integration {name} must start with an '@' symbol!")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
parts.append(f"esphome/components/{name}/* {' '.join(comp.codeowners)}")
|
||||||
|
|
||||||
|
# End newline
|
||||||
|
parts.append('')
|
||||||
|
content = '\n'.join(parts)
|
||||||
|
codeowners_file = root / 'CODEOWNERS'
|
||||||
|
|
||||||
|
if args.check:
|
||||||
|
if codeowners_file.read_text() != content:
|
||||||
|
print("CODEOWNERS file is not up to date.")
|
||||||
|
print("Please run `script/build_codeowners.py`")
|
||||||
|
sys.exit(1)
|
||||||
|
print("CODEOWNERS file is up to date")
|
||||||
|
else:
|
||||||
|
write_file_if_changed(codeowners_file, content)
|
||||||
|
print("Wrote CODEOWNERS")
|
Loading…
Reference in a new issue