mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-31 07:03:55 +00:00 
			
		
		
		
	Use copy for custom includes (#568)
This commit is contained in:
		| @@ -612,9 +612,9 @@ def _format_vol_invalid(ex, config): | ||||
|         else: | ||||
|             message += u'[{}] is an invalid option for [{}]. Please check the indentation.'.format( | ||||
|                 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) | ||||
|     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) | ||||
|     else: | ||||
|         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, \ | ||||
|     TimePeriodMilliseconds, TimePeriodSeconds, TimePeriodMinutes | ||||
| 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 | ||||
|  | ||||
| _LOGGER = logging.getLogger(__name__) | ||||
| @@ -617,9 +617,9 @@ if IS_PY2: | ||||
|     # Override voluptuous invalid to unicode for py2 | ||||
|     def _vol_invalid_unicode(self): | ||||
|         path = u' @ data[%s]' % u']['.join(map(repr, self.path)) \ | ||||
|             if self.path else '' | ||||
|             if self.path else u'' | ||||
|         # pylint: disable=no-member | ||||
|         output = self.message | ||||
|         output = decode_text(self.message) | ||||
|         if self.error_type: | ||||
|             output += u' for ' + self.error_type | ||||
|         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, \ | ||||
|     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.helpers import copy_file_if_changed, walk_files | ||||
| from esphome.pins import ESP8266_FLASH_SIZES, ESP8266_LD_SCRIPTS | ||||
|  | ||||
| _LOGGER = logging.getLogger(__name__) | ||||
| @@ -59,6 +60,7 @@ PLATFORMIO_ESP8266_LUT = { | ||||
| PLATFORMIO_ESP32_LUT = { | ||||
|     '1.0.0': 'espressif32@1.4.0', | ||||
|     '1.0.1': 'espressif32@1.6.0', | ||||
|     '1.0.2': 'espressif32@1.8.0', | ||||
|     'RECOMMENDED': 'espressif32@1.6.0', | ||||
|     'LATEST': 'espressif32', | ||||
|     'DEV': ARDUINO_VERSION_ESP32_DEV, | ||||
| @@ -91,6 +93,22 @@ def default_build_path(): | ||||
|     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({ | ||||
|     cv.Required(CONF_NAME): cv.valid_name, | ||||
|     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.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('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]) | ||||
|  | ||||
|  | ||||
| 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) | ||||
| def add_includes(includes): | ||||
|     # Add includes at the very end, so that the included files can access global variables | ||||
|     for include in includes: | ||||
|         path = CORE.relative_config_path(include) | ||||
|         res = os.path.relpath(path, CORE.relative_build_path('src')).replace(os.path.sep, '/') | ||||
|         cg.add_global(cg.RawStatement(u'#include "{}"'.format(res))) | ||||
|         if os.path.isdir(path): | ||||
|             # 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) | ||||
|   | ||||
| @@ -157,6 +157,12 @@ def copy_file_if_changed(src, dst): | ||||
|     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): | ||||
|     try: | ||||
|         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, \ | ||||
|     HEADER_FILE_EXTENSIONS, SOURCE_FILE_EXTENSIONS | ||||
| 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 | ||||
|  | ||||
| _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(): | ||||
|     import filecmp | ||||
|     import shutil | ||||
|   | ||||
		Reference in New Issue
	
	Block a user