mirror of
https://github.com/esphome/esphome.git
synced 2024-11-14 02:58:11 +01:00
Use copy for custom includes (#568)
This commit is contained in:
parent
5fca02c712
commit
4b7c5aa05c
5 changed files with 51 additions and 15 deletions
|
@ -612,9 +612,9 @@ def _format_vol_invalid(ex, config):
|
||||||
else:
|
else:
|
||||||
message += u'[{}] is an invalid option for [{}]. Please check the indentation.'.format(
|
message += u'[{}] is an invalid option for [{}]. Please check the indentation.'.format(
|
||||||
ex.path[-1], paren)
|
ex.path[-1], paren)
|
||||||
elif u'extra keys not allowed' in ex.error_message:
|
elif u'extra keys not allowed' in text_type(ex):
|
||||||
message += u'[{}] is an invalid option for [{}].'.format(ex.path[-1], paren)
|
message += u'[{}] is an invalid option for [{}].'.format(ex.path[-1], paren)
|
||||||
elif u'required key not provided' in ex.error_message:
|
elif u'required key not provided' in text_type(ex):
|
||||||
message += u"'{}' is a required option for [{}].".format(ex.path[-1], paren)
|
message += u"'{}' is a required option for [{}].".format(ex.path[-1], paren)
|
||||||
else:
|
else:
|
||||||
message += humanize_error(config, ex)
|
message += humanize_error(config, ex)
|
||||||
|
|
|
@ -20,7 +20,7 @@ from esphome.const import CONF_AVAILABILITY, CONF_COMMAND_TOPIC, CONF_DISCOVERY,
|
||||||
from esphome.core import CORE, HexInt, IPAddress, Lambda, TimePeriod, TimePeriodMicroseconds, \
|
from esphome.core import CORE, HexInt, IPAddress, Lambda, TimePeriod, TimePeriodMicroseconds, \
|
||||||
TimePeriodMilliseconds, TimePeriodSeconds, TimePeriodMinutes
|
TimePeriodMilliseconds, TimePeriodSeconds, TimePeriodMinutes
|
||||||
from esphome.helpers import list_starts_with
|
from esphome.helpers import list_starts_with
|
||||||
from esphome.py_compat import integer_types, string_types, text_type, IS_PY2
|
from esphome.py_compat import integer_types, string_types, text_type, IS_PY2, decode_text
|
||||||
from esphome.voluptuous_schema import _Schema
|
from esphome.voluptuous_schema import _Schema
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
@ -617,9 +617,9 @@ if IS_PY2:
|
||||||
# Override voluptuous invalid to unicode for py2
|
# Override voluptuous invalid to unicode for py2
|
||||||
def _vol_invalid_unicode(self):
|
def _vol_invalid_unicode(self):
|
||||||
path = u' @ data[%s]' % u']['.join(map(repr, self.path)) \
|
path = u' @ data[%s]' % u']['.join(map(repr, self.path)) \
|
||||||
if self.path else ''
|
if self.path else u''
|
||||||
# pylint: disable=no-member
|
# pylint: disable=no-member
|
||||||
output = self.message
|
output = decode_text(self.message)
|
||||||
if self.error_type:
|
if self.error_type:
|
||||||
output += u' for ' + self.error_type
|
output += u' for ' + self.error_type
|
||||||
return output + path
|
return output + path
|
||||||
|
|
|
@ -13,6 +13,7 @@ from esphome.const import ARDUINO_VERSION_ESP32_DEV, ARDUINO_VERSION_ESP8266_DEV
|
||||||
CONF_ESP8266_RESTORE_FROM_FLASH, __version__, ARDUINO_VERSION_ESP8266_2_3_0, \
|
CONF_ESP8266_RESTORE_FROM_FLASH, __version__, ARDUINO_VERSION_ESP8266_2_3_0, \
|
||||||
ARDUINO_VERSION_ESP8266_2_5_0, ARDUINO_VERSION_ESP8266_2_5_1, ARDUINO_VERSION_ESP8266_2_5_2
|
ARDUINO_VERSION_ESP8266_2_5_0, ARDUINO_VERSION_ESP8266_2_5_1, ARDUINO_VERSION_ESP8266_2_5_2
|
||||||
from esphome.core import CORE, coroutine_with_priority
|
from esphome.core import CORE, coroutine_with_priority
|
||||||
|
from esphome.helpers import copy_file_if_changed, walk_files
|
||||||
from esphome.pins import ESP8266_FLASH_SIZES, ESP8266_LD_SCRIPTS
|
from esphome.pins import ESP8266_FLASH_SIZES, ESP8266_LD_SCRIPTS
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
@ -59,6 +60,7 @@ PLATFORMIO_ESP8266_LUT = {
|
||||||
PLATFORMIO_ESP32_LUT = {
|
PLATFORMIO_ESP32_LUT = {
|
||||||
'1.0.0': 'espressif32@1.4.0',
|
'1.0.0': 'espressif32@1.4.0',
|
||||||
'1.0.1': 'espressif32@1.6.0',
|
'1.0.1': 'espressif32@1.6.0',
|
||||||
|
'1.0.2': 'espressif32@1.8.0',
|
||||||
'RECOMMENDED': 'espressif32@1.6.0',
|
'RECOMMENDED': 'espressif32@1.6.0',
|
||||||
'LATEST': 'espressif32',
|
'LATEST': 'espressif32',
|
||||||
'DEV': ARDUINO_VERSION_ESP32_DEV,
|
'DEV': ARDUINO_VERSION_ESP32_DEV,
|
||||||
|
@ -91,6 +93,22 @@ def default_build_path():
|
||||||
return CORE.name
|
return CORE.name
|
||||||
|
|
||||||
|
|
||||||
|
VALID_INCLUDE_EXTS = {'.h', '.hpp', '.tcc', '.ino', '.cpp', '.c'}
|
||||||
|
|
||||||
|
|
||||||
|
def valid_include(value):
|
||||||
|
try:
|
||||||
|
return cv.directory(value)
|
||||||
|
except cv.Invalid:
|
||||||
|
pass
|
||||||
|
value = cv.file_(value)
|
||||||
|
_, ext = os.path.splitext(value)
|
||||||
|
if ext not in VALID_INCLUDE_EXTS:
|
||||||
|
raise cv.Invalid(u"Include has invalid file extension {} - valid extensions are {}"
|
||||||
|
u"".format(ext, ', '.join(VALID_INCLUDE_EXTS)))
|
||||||
|
return value
|
||||||
|
|
||||||
|
|
||||||
CONFIG_SCHEMA = cv.Schema({
|
CONFIG_SCHEMA = cv.Schema({
|
||||||
cv.Required(CONF_NAME): cv.valid_name,
|
cv.Required(CONF_NAME): cv.valid_name,
|
||||||
cv.Required(CONF_PLATFORM): cv.one_of('ESP8266', 'ESP32', upper=True),
|
cv.Required(CONF_PLATFORM): cv.one_of('ESP8266', 'ESP32', upper=True),
|
||||||
|
@ -115,7 +133,7 @@ CONFIG_SCHEMA = cv.Schema({
|
||||||
cv.Optional(CONF_ON_LOOP): automation.validate_automation({
|
cv.Optional(CONF_ON_LOOP): automation.validate_automation({
|
||||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(LoopTrigger),
|
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(LoopTrigger),
|
||||||
}),
|
}),
|
||||||
cv.Optional(CONF_INCLUDES, default=[]): cv.ensure_list(cv.file_),
|
cv.Optional(CONF_INCLUDES, default=[]): cv.ensure_list(valid_include),
|
||||||
cv.Optional(CONF_LIBRARIES, default=[]): cv.ensure_list(cv.string_strict),
|
cv.Optional(CONF_LIBRARIES, default=[]): cv.ensure_list(cv.string_strict),
|
||||||
|
|
||||||
cv.Optional('esphome_core_version'): cv.invalid("The esphome_core_version option has been "
|
cv.Optional('esphome_core_version'): cv.invalid("The esphome_core_version option has been "
|
||||||
|
@ -153,13 +171,31 @@ def preload_core_config(config):
|
||||||
CORE.build_path = CORE.relative_config_path(out2[CONF_BUILD_PATH])
|
CORE.build_path = CORE.relative_config_path(out2[CONF_BUILD_PATH])
|
||||||
|
|
||||||
|
|
||||||
|
def include_file(path, basename):
|
||||||
|
parts = basename.split(os.path.sep)
|
||||||
|
dst = CORE.relative_src_path(*parts)
|
||||||
|
copy_file_if_changed(path, dst)
|
||||||
|
|
||||||
|
_, ext = os.path.splitext(path)
|
||||||
|
if ext in ['.h', '.hpp', '.tcc']:
|
||||||
|
# Header, add include statement
|
||||||
|
cg.add_global(cg.RawStatement(u'#include "{}"'.format(basename)))
|
||||||
|
|
||||||
|
|
||||||
@coroutine_with_priority(-1000.0)
|
@coroutine_with_priority(-1000.0)
|
||||||
def add_includes(includes):
|
def add_includes(includes):
|
||||||
# Add includes at the very end, so that the included files can access global variables
|
# Add includes at the very end, so that the included files can access global variables
|
||||||
for include in includes:
|
for include in includes:
|
||||||
path = CORE.relative_config_path(include)
|
path = CORE.relative_config_path(include)
|
||||||
res = os.path.relpath(path, CORE.relative_build_path('src')).replace(os.path.sep, '/')
|
if os.path.isdir(path):
|
||||||
cg.add_global(cg.RawStatement(u'#include "{}"'.format(res)))
|
# Directory, copy tree
|
||||||
|
for p in walk_files(path):
|
||||||
|
basename = os.path.relpath(p, os.path.dirname(path))
|
||||||
|
include_file(p, basename)
|
||||||
|
else:
|
||||||
|
# Copy file
|
||||||
|
basename = os.path.basename(path)
|
||||||
|
include_file(path, basename)
|
||||||
|
|
||||||
|
|
||||||
@coroutine_with_priority(100.0)
|
@coroutine_with_priority(100.0)
|
||||||
|
|
|
@ -157,6 +157,12 @@ def copy_file_if_changed(src, dst):
|
||||||
write_file(dst, src_text)
|
write_file(dst, src_text)
|
||||||
|
|
||||||
|
|
||||||
|
def walk_files(path):
|
||||||
|
for root, _, files in os.walk(path):
|
||||||
|
for name in files:
|
||||||
|
yield os.path.join(root, name)
|
||||||
|
|
||||||
|
|
||||||
def read_file(path):
|
def read_file(path):
|
||||||
try:
|
try:
|
||||||
with codecs.open(path, 'r', encoding='utf-8') as f_handle:
|
with codecs.open(path, 'r', encoding='utf-8') as f_handle:
|
||||||
|
|
|
@ -8,7 +8,7 @@ from esphome.config import iter_components
|
||||||
from esphome.const import CONF_BOARD_FLASH_MODE, CONF_ESPHOME, CONF_PLATFORMIO_OPTIONS, \
|
from esphome.const import CONF_BOARD_FLASH_MODE, CONF_ESPHOME, CONF_PLATFORMIO_OPTIONS, \
|
||||||
HEADER_FILE_EXTENSIONS, SOURCE_FILE_EXTENSIONS
|
HEADER_FILE_EXTENSIONS, SOURCE_FILE_EXTENSIONS
|
||||||
from esphome.core import CORE, EsphomeError
|
from esphome.core import CORE, EsphomeError
|
||||||
from esphome.helpers import mkdir_p, read_file, write_file_if_changed
|
from esphome.helpers import mkdir_p, read_file, write_file_if_changed, walk_files
|
||||||
from esphome.storage_json import StorageJSON, storage_path
|
from esphome.storage_json import StorageJSON, storage_path
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
@ -281,12 +281,6 @@ or use the custom_components folder.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
def walk_files(path):
|
|
||||||
for root, _, files in os.walk(path):
|
|
||||||
for name in files:
|
|
||||||
yield os.path.join(root, name)
|
|
||||||
|
|
||||||
|
|
||||||
def copy_src_tree():
|
def copy_src_tree():
|
||||||
import filecmp
|
import filecmp
|
||||||
import shutil
|
import shutil
|
||||||
|
|
Loading…
Reference in a new issue