1
0
mirror of https://github.com/esphome/esphome.git synced 2025-09-03 11:52:20 +01:00

Implement external custom components installing from YAML (#1630)

* Move components import loading to importlib MetaPathFinder and importlib.resources

* Add external_components component

* Fix

* Fix

* fix cv.url return

* fix validate shorthand git

* implement git refresh

* Use finders from sys.path_hooks instead of looking for __init__.py

* use github:// schema

* error handling

* add test

* fix handling git output

* revert file check handling

* fix test

* allow full component path be specified for local

* fix test

* fix path handling

* lint

Co-authored-by: Guillermo Ruffino <glm.net@gmail.com>
This commit is contained in:
Otto Winter
2021-05-07 20:02:17 +02:00
committed by GitHub
parent 2225594ee8
commit 229bf719a2
15 changed files with 451 additions and 192 deletions

View File

@@ -1,6 +1,8 @@
import logging
import os
import re
from pathlib import Path
from typing import Dict
from esphome.config import iter_components
from esphome.const import (
@@ -24,6 +26,7 @@ from esphome.helpers import (
)
from esphome.storage_json import StorageJSON, storage_path
from esphome.pins import ESP8266_FLASH_SIZES, ESP8266_LD_SCRIPTS
from esphome import loader
_LOGGER = logging.getLogger(__name__)
@@ -355,7 +358,7 @@ or use the custom_components folder.
def copy_src_tree():
source_files = {}
source_files: Dict[Path, loader.SourceFile] = {}
for _, component, _ in iter_components(CORE.config):
source_files.update(component.source_files)
@@ -365,37 +368,40 @@ def copy_src_tree():
# Build #include list for esphome.h
include_l = []
for target, path in source_files_l:
if os.path.splitext(path)[1] in HEADER_FILE_EXTENSIONS:
for target, _ in source_files_l:
if target.suffix in HEADER_FILE_EXTENSIONS:
include_l.append(f'#include "{target}"')
include_l.append("")
include_s = "\n".join(include_l)
source_files_copy = source_files.copy()
source_files_copy.pop(DEFINES_H_TARGET)
ignore_targets = [Path(x) for x in (DEFINES_H_TARGET, VERSION_H_TARGET)]
for t in ignore_targets:
source_files_copy.pop(t)
for path in walk_files(CORE.relative_src_path("esphome")):
if os.path.splitext(path)[1] not in SOURCE_FILE_EXTENSIONS:
for fname in walk_files(CORE.relative_src_path("esphome")):
p = Path(fname)
if p.suffix not in SOURCE_FILE_EXTENSIONS:
# Not a source file, ignore
continue
# Transform path to target path name
target = os.path.relpath(path, CORE.relative_src_path()).replace(
os.path.sep, "/"
)
if target in (DEFINES_H_TARGET, VERSION_H_TARGET):
target = p.relative_to(CORE.relative_src_path())
if target in ignore_targets:
# Ignore defines.h, will be dealt with later
continue
if target not in source_files_copy:
# Source file removed, delete target
os.remove(path)
p.unlink()
else:
src_path = source_files_copy.pop(target)
copy_file_if_changed(src_path, path)
src_file = source_files_copy.pop(target)
with src_file.path() as src_path:
copy_file_if_changed(src_path, p)
# Now copy new files
for target, src_path in source_files_copy.items():
dst_path = CORE.relative_src_path(*target.split("/"))
copy_file_if_changed(src_path, dst_path)
for target, src_file in source_files_copy.items():
dst_path = CORE.relative_src_path(*target.parts)
with src_file.path() as src_path:
copy_file_if_changed(src_path, dst_path)
# Finally copy defines
write_file_if_changed(