1
0
mirror of https://github.com/esphome/esphome.git synced 2025-03-01 08:18:16 +00:00

Factor PlatformIO buildgen out of writer.py

This commit is contained in:
Katherine Whitlock 2025-01-16 17:14:54 -05:00
parent 07be7ad7e2
commit 8f80489184
5 changed files with 89 additions and 84 deletions

View File

@ -66,7 +66,7 @@ def choose_prompt(options, purpose: str = None):
return options[0][1] return options[0][1]
safe_print( safe_print(
f'Found multiple options{f" for {purpose}" if purpose else ""}, please choose one:' f"Found multiple options{f' for {purpose}' if purpose else ''}, please choose one:"
) )
for i, (desc, _) in enumerate(options): for i, (desc, _) in enumerate(options):
safe_print(f" [{i + 1}] {desc}") safe_print(f" [{i + 1}] {desc}")
@ -225,7 +225,9 @@ def generate_cpp_contents(config):
def write_cpp_file(): def write_cpp_file():
writer.write_platformio_project() from esphome.build_gen import platformio
platformio.write_project()
code_s = indent(CORE.cpp_main_section) code_s = indent(CORE.cpp_main_section)
writer.write_cpp(code_s) writer.write_cpp(code_s)

View File

View File

@ -0,0 +1,78 @@
import os
from typing import Union
from esphome.const import ENV_NOGITIGNORE, __version__
from esphome.core import CORE
from esphome.helpers import get_bool_env, mkdir_p, read_file, write_file_if_changed
from esphome.writer import find_begin_end, update_storage_json, write_gitignore
INI_AUTO_GENERATE_BEGIN = "; ========== AUTO GENERATED CODE BEGIN ==========="
INI_AUTO_GENERATE_END = "; =========== AUTO GENERATED CODE END ============"
INI_BASE_FORMAT = (
"""; Auto generated code by esphome
[common]
lib_deps =
build_flags =
upload_flags =
""",
"""
""",
)
def format_ini(data: dict[str, Union[str, list[str]]]) -> str:
content = ""
for key, value in sorted(data.items()):
if isinstance(value, list):
content += f"{key} =\n"
for x in value:
content += f" {x}\n"
else:
content += f"{key} = {value}\n"
return content
def get_ini_content():
CORE.add_platformio_option(
"lib_deps",
[x.as_lib_dep for x in CORE.platformio_libraries] + ["${common.lib_deps}"],
)
# Sort to avoid changing build flags order
CORE.add_platformio_option("build_flags", sorted(CORE.build_flags))
content = "[platformio]\n"
content += f"description = ESPHome {__version__}\n"
content += f"[env:{CORE.name}]\n"
content += format_ini(CORE.platformio_options)
return content
def write_ini(content):
update_storage_json()
path = CORE.relative_build_path("platformio.ini")
if os.path.isfile(path):
text = read_file(path)
content_format = find_begin_end(
text, INI_AUTO_GENERATE_BEGIN, INI_AUTO_GENERATE_END
)
else:
content_format = INI_BASE_FORMAT
full_file = f"{content_format[0] + INI_AUTO_GENERATE_BEGIN}\n{content}"
full_file += INI_AUTO_GENERATE_END + content_format[1]
write_file_if_changed(path, full_file)
def write_project():
mkdir_p(CORE.build_path)
content = get_ini_content()
if not get_bool_env(ENV_NOGITIGNORE):
write_gitignore()
write_ini(content)

View File

@ -504,7 +504,7 @@ class EsphomeCore:
# A list of statements to insert in the global block (includes and global variables) # A list of statements to insert in the global block (includes and global variables)
self.global_statements: list[Statement] = [] self.global_statements: list[Statement] = []
# A set of platformio libraries to add to the project # A set of platformio libraries to add to the project
self.libraries: list[Library] = [] self.platformio_libraries: list[Library] = []
# A set of build flags to set in the platformio project # A set of build flags to set in the platformio project
self.build_flags: set[str] = set() self.build_flags: set[str] = set()
# A set of defines to set for the compile process in esphome/core/defines.h # A set of defines to set for the compile process in esphome/core/defines.h
@ -536,7 +536,7 @@ class EsphomeCore:
self.variables = {} self.variables = {}
self.main_statements = [] self.main_statements = []
self.global_statements = [] self.global_statements = []
self.libraries = [] self.platformio_libraries = []
self.build_flags = set() self.build_flags = set()
self.defines = set() self.defines = set()
self.platformio_options = {} self.platformio_options = {}
@ -707,7 +707,7 @@ class EsphomeCore:
raise ValueError( raise ValueError(
f"Library {library} must be instance of Library, not {type(library)}" f"Library {library} must be instance of Library, not {type(library)}"
) )
for other in self.libraries[:]: for other in self.platformio_libraries[:]:
if other.name is None or library.name is None: if other.name is None or library.name is None:
continue continue
library_name = ( library_name = (
@ -729,7 +729,7 @@ class EsphomeCore:
if library.repository is not None: if library.repository is not None:
# This is more specific since its using a repository # This is more specific since its using a repository
self.libraries.remove(other) self.platformio_libraries.remove(other)
continue continue
if library.version is None: if library.version is None:
@ -737,7 +737,7 @@ class EsphomeCore:
break break
if other.version is None: if other.version is None:
# Found more specific version requirement # Found more specific version requirement
self.libraries.remove(other) self.platformio_libraries.remove(other)
continue continue
if other.version == library.version: if other.version == library.version:
break break
@ -748,7 +748,7 @@ class EsphomeCore:
) )
else: else:
_LOGGER.debug("Adding library: %s", library) _LOGGER.debug("Adding library: %s", library)
self.libraries.append(library) self.platformio_libraries.append(library)
return library return library
def add_build_flag(self, build_flag): def add_build_flag(self, build_flag):

View File

@ -3,12 +3,10 @@ import logging
import os import os
from pathlib import Path from pathlib import Path
import re import re
from typing import Union
from esphome import loader from esphome import loader
from esphome.config import iter_component_configs, iter_components from esphome.config import iter_component_configs, iter_components
from esphome.const import ( from esphome.const import (
ENV_NOGITIGNORE,
HEADER_FILE_EXTENSIONS, HEADER_FILE_EXTENSIONS,
PLATFORM_ESP32, PLATFORM_ESP32,
SOURCE_FILE_EXTENSIONS, SOURCE_FILE_EXTENSIONS,
@ -17,8 +15,6 @@ from esphome.const import (
from esphome.core import CORE, EsphomeError from esphome.core import CORE, EsphomeError
from esphome.helpers import ( from esphome.helpers import (
copy_file_if_changed, copy_file_if_changed,
get_bool_env,
mkdir_p,
read_file, read_file,
walk_files, walk_files,
write_file_if_changed, write_file_if_changed,
@ -31,8 +27,6 @@ CPP_AUTO_GENERATE_BEGIN = "// ========== AUTO GENERATED CODE BEGIN ==========="
CPP_AUTO_GENERATE_END = "// =========== AUTO GENERATED CODE END ============" CPP_AUTO_GENERATE_END = "// =========== AUTO GENERATED CODE END ============"
CPP_INCLUDE_BEGIN = "// ========== AUTO GENERATED INCLUDE BLOCK BEGIN ===========" CPP_INCLUDE_BEGIN = "// ========== AUTO GENERATED INCLUDE BLOCK BEGIN ==========="
CPP_INCLUDE_END = "// ========== AUTO GENERATED INCLUDE BLOCK END ===========" CPP_INCLUDE_END = "// ========== AUTO GENERATED INCLUDE BLOCK END ==========="
INI_AUTO_GENERATE_BEGIN = "; ========== AUTO GENERATED CODE BEGIN ==========="
INI_AUTO_GENERATE_END = "; =========== AUTO GENERATED CODE END ============"
CPP_BASE_FORMAT = ( CPP_BASE_FORMAT = (
"""// Auto generated code by esphome """// Auto generated code by esphome
@ -51,20 +45,6 @@ void loop() {
""", """,
) )
INI_BASE_FORMAT = (
"""; Auto generated code by esphome
[common]
lib_deps =
build_flags =
upload_flags =
""",
"""
""",
)
UPLOAD_SPEED_OVERRIDE = { UPLOAD_SPEED_OVERRIDE = {
"esp210": 57600, "esp210": 57600,
} }
@ -132,34 +112,6 @@ def update_storage_json():
new.save(path) new.save(path)
def format_ini(data: dict[str, Union[str, list[str]]]) -> str:
content = ""
for key, value in sorted(data.items()):
if isinstance(value, list):
content += f"{key} =\n"
for x in value:
content += f" {x}\n"
else:
content += f"{key} = {value}\n"
return content
def get_ini_content():
CORE.add_platformio_option(
"lib_deps", [x.as_lib_dep for x in CORE.libraries] + ["${common.lib_deps}"]
)
# Sort to avoid changing build flags order
CORE.add_platformio_option("build_flags", sorted(CORE.build_flags))
content = "[platformio]\n"
content += f"description = ESPHome {__version__}\n"
content += f"[env:{CORE.name}]\n"
content += format_ini(CORE.platformio_options)
return content
def find_begin_end(text, begin_s, end_s): def find_begin_end(text, begin_s, end_s):
begin_index = text.find(begin_s) begin_index = text.find(begin_s)
if begin_index == -1: if begin_index == -1:
@ -187,34 +139,7 @@ def find_begin_end(text, begin_s, end_s):
return text[:begin_index], text[(end_index + len(end_s)) :] return text[:begin_index], text[(end_index + len(end_s)) :]
def write_platformio_ini(content): DEFINES_H_FORMAT = ESPHOME_H_FORMAT = """\
update_storage_json()
path = CORE.relative_build_path("platformio.ini")
if os.path.isfile(path):
text = read_file(path)
content_format = find_begin_end(
text, INI_AUTO_GENERATE_BEGIN, INI_AUTO_GENERATE_END
)
else:
content_format = INI_BASE_FORMAT
full_file = f"{content_format[0] + INI_AUTO_GENERATE_BEGIN}\n{content}"
full_file += INI_AUTO_GENERATE_END + content_format[1]
write_file_if_changed(path, full_file)
def write_platformio_project():
mkdir_p(CORE.build_path)
content = get_ini_content()
if not get_bool_env(ENV_NOGITIGNORE):
write_gitignore()
write_platformio_ini(content)
DEFINES_H_FORMAT = (
ESPHOME_H_FORMAT
) = """\
#pragma once #pragma once
#include "esphome/core/macros.h" #include "esphome/core/macros.h"
{} {}