mirror of
https://github.com/esphome/esphome.git
synced 2026-07-10 08:55:36 +00:00
[core] Add schema visibility hints to build & framework internals
Mark raw build-system and framework/SDK options with cv.Visibility so schema-aware editors (device-builder) render them appropriately: - YAML_ONLY (never in a visual editor): esphome build internals (build_path, platformio_options, build_flags, environment_variables, includes, includes_c, libraries, debug_scheduler) and platform framework internals (esp32 release/source/platform_version/ sdkconfig_options/advanced/components and partitions; esp8266/rp2040 source/platform_version; libretiny source; nrf52 framework advanced). - ADVANCED (advanced disclosure): min_version, compile_process_limit and the esp32 toolchain override -- real but rarely-touched knobs. Pure UI hints; validation and runtime are unchanged.
This commit is contained in:
@@ -1483,16 +1483,20 @@ FRAMEWORK_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.Optional(CONF_TYPE): cv.one_of(FRAMEWORK_ESP_IDF, FRAMEWORK_ARDUINO),
|
||||
cv.Optional(CONF_VERSION, default="recommended"): cv.string_strict,
|
||||
cv.Optional(CONF_RELEASE): cv.string_strict,
|
||||
cv.Optional(CONF_SOURCE): cv.string_strict,
|
||||
cv.Optional(CONF_PLATFORM_VERSION): _parse_pio_platform_version,
|
||||
cv.Optional(CONF_SDKCONFIG_OPTIONS, default={}): {
|
||||
cv.string_strict: cv.string_strict
|
||||
},
|
||||
cv.Optional(CONF_RELEASE, visibility=cv.Visibility.YAML_ONLY): cv.string_strict,
|
||||
cv.Optional(CONF_SOURCE, visibility=cv.Visibility.YAML_ONLY): cv.string_strict,
|
||||
cv.Optional(
|
||||
CONF_PLATFORM_VERSION, visibility=cv.Visibility.YAML_ONLY
|
||||
): _parse_pio_platform_version,
|
||||
cv.Optional(
|
||||
CONF_SDKCONFIG_OPTIONS, default={}, visibility=cv.Visibility.YAML_ONLY
|
||||
): {cv.string_strict: cv.string_strict},
|
||||
cv.Optional(CONF_LOG_LEVEL, default="ERROR"): cv.one_of(
|
||||
*LOG_LEVELS_IDF, upper=True
|
||||
),
|
||||
cv.Optional(CONF_ADVANCED, default={}): cv.Schema(
|
||||
cv.Optional(
|
||||
CONF_ADVANCED, default={}, visibility=cv.Visibility.YAML_ONLY
|
||||
): cv.Schema(
|
||||
{
|
||||
cv.Optional(CONF_ASSERTION_LEVEL): cv.one_of(
|
||||
*ASSERTION_LEVELS, upper=True
|
||||
@@ -1570,7 +1574,9 @@ FRAMEWORK_SCHEMA = cv.Schema(
|
||||
cv.Optional(CONF_DISABLE_FATFS, default=True): cv.boolean,
|
||||
}
|
||||
),
|
||||
cv.Optional(CONF_COMPONENTS, default=[]): cv.ensure_list(
|
||||
cv.Optional(
|
||||
CONF_COMPONENTS, default=[], visibility=cv.Visibility.YAML_ONLY
|
||||
): cv.ensure_list(
|
||||
cv.All(
|
||||
cv.Any(
|
||||
cv.All(cv.string_strict, _parse_idf_component),
|
||||
@@ -1723,7 +1729,7 @@ CONFIG_SCHEMA = cv.All(
|
||||
cv.Optional(CONF_FLASH_FREQUENCY): cv.one_of(
|
||||
*FLASH_FREQUENCIES, upper=True
|
||||
),
|
||||
cv.Optional(CONF_PARTITIONS): cv.Any(
|
||||
cv.Optional(CONF_PARTITIONS, visibility=cv.Visibility.YAML_ONLY): cv.Any(
|
||||
cv.file_,
|
||||
cv.ensure_list(
|
||||
cv.All(
|
||||
@@ -1747,7 +1753,9 @@ CONFIG_SCHEMA = cv.All(
|
||||
),
|
||||
cv.Optional(CONF_VARIANT): cv.one_of(*VARIANTS, upper=True),
|
||||
cv.Optional(CONF_FRAMEWORK): FRAMEWORK_SCHEMA,
|
||||
cv.Optional(CONF_TOOLCHAIN): _validate_toolchain,
|
||||
cv.Optional(
|
||||
CONF_TOOLCHAIN, visibility=cv.Visibility.ADVANCED
|
||||
): _validate_toolchain,
|
||||
cv.Optional(CONF_WATCHDOG_TIMEOUT, default="5s"): cv.All(
|
||||
cv.positive_time_period_seconds,
|
||||
cv.Range(min=cv.TimePeriod(seconds=5), max=cv.TimePeriod(seconds=60)),
|
||||
|
||||
@@ -205,8 +205,12 @@ ARDUINO_FRAMEWORK_SCHEMA = cv.All(
|
||||
cv.Schema(
|
||||
{
|
||||
cv.Optional(CONF_VERSION, default="recommended"): cv.string_strict,
|
||||
cv.Optional(CONF_SOURCE): cv.string_strict,
|
||||
cv.Optional(CONF_PLATFORM_VERSION): _parse_platform_version,
|
||||
cv.Optional(
|
||||
CONF_SOURCE, visibility=cv.Visibility.YAML_ONLY
|
||||
): cv.string_strict,
|
||||
cv.Optional(
|
||||
CONF_PLATFORM_VERSION, visibility=cv.Visibility.YAML_ONLY
|
||||
): _parse_platform_version,
|
||||
}
|
||||
),
|
||||
_arduino_check_versions,
|
||||
|
||||
@@ -259,7 +259,10 @@ FRAMEWORK_SCHEMA = cv.All(
|
||||
cv.Schema(
|
||||
{
|
||||
cv.Optional(CONF_VERSION, default="recommended"): cv.string_strict,
|
||||
cv.Optional(CONF_SOURCE): cv.string_strict,
|
||||
# Raw PlatformIO package source — build internal, not a UI field.
|
||||
cv.Optional(
|
||||
CONF_SOURCE, visibility=cv.Visibility.YAML_ONLY
|
||||
): cv.string_strict,
|
||||
cv.Optional(CONF_LOGLEVEL, default="warn"): (
|
||||
cv.one_of(*LT_LOGLEVELS, upper=True)
|
||||
),
|
||||
|
||||
@@ -238,7 +238,9 @@ CONFIG_SCHEMA = cv.All(
|
||||
): cv.Schema(
|
||||
{
|
||||
cv.Optional(CONF_VERSION): cv.string_strict,
|
||||
cv.Optional(CONF_ADVANCED, default={}): cv.Schema(
|
||||
cv.Optional(
|
||||
CONF_ADVANCED, default={}, visibility=cv.Visibility.YAML_ONLY
|
||||
): cv.Schema(
|
||||
{
|
||||
cv.Optional(
|
||||
CONF_ENABLE_OTA_ROLLBACK, default=True
|
||||
|
||||
@@ -240,8 +240,12 @@ ARDUINO_FRAMEWORK_SCHEMA = cv.All(
|
||||
cv.Schema(
|
||||
{
|
||||
cv.Optional(CONF_VERSION, default="recommended"): cv.string_strict,
|
||||
cv.Optional(CONF_SOURCE): cv.string_strict,
|
||||
cv.Optional(CONF_PLATFORM_VERSION): _parse_platform_version,
|
||||
cv.Optional(
|
||||
CONF_SOURCE, visibility=cv.Visibility.YAML_ONLY
|
||||
): cv.string_strict,
|
||||
cv.Optional(
|
||||
CONF_PLATFORM_VERSION, visibility=cv.Visibility.YAML_ONLY
|
||||
): _parse_platform_version,
|
||||
}
|
||||
),
|
||||
_arduino_check_versions,
|
||||
|
||||
+34
-12
@@ -283,14 +283,24 @@ CONFIG_SCHEMA = cv.All(
|
||||
cv.Optional(CONF_COMMENT): cv.All(
|
||||
cv.string, cv.ByteLength(max=COMMENT_MAX_LEN)
|
||||
),
|
||||
cv.Required(CONF_BUILD_PATH): cv.string,
|
||||
cv.Optional(CONF_PLATFORMIO_OPTIONS, default={}): cv.Schema(
|
||||
cv.Required(CONF_BUILD_PATH, visibility=cv.Visibility.YAML_ONLY): cv.string,
|
||||
cv.Optional(
|
||||
CONF_PLATFORMIO_OPTIONS,
|
||||
default={},
|
||||
visibility=cv.Visibility.YAML_ONLY,
|
||||
): cv.Schema(
|
||||
{
|
||||
cv.string_strict: cv.Any([cv.string], cv.string),
|
||||
}
|
||||
),
|
||||
cv.Optional(CONF_BUILD_FLAGS, default=[]): cv.ensure_list(cv.string_strict),
|
||||
cv.Optional(CONF_ENVIRONMENT_VARIABLES, default={}): cv.Schema(
|
||||
cv.Optional(
|
||||
CONF_BUILD_FLAGS, default=[], visibility=cv.Visibility.YAML_ONLY
|
||||
): cv.ensure_list(cv.string_strict),
|
||||
cv.Optional(
|
||||
CONF_ENVIRONMENT_VARIABLES,
|
||||
default={},
|
||||
visibility=cv.Visibility.YAML_ONLY,
|
||||
): cv.Schema(
|
||||
{
|
||||
cv.string_strict: cv.string,
|
||||
}
|
||||
@@ -312,11 +322,19 @@ CONFIG_SCHEMA = cv.All(
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(LoopTrigger),
|
||||
}
|
||||
),
|
||||
cv.Optional(CONF_INCLUDES, default=[]): cv.ensure_list(valid_include),
|
||||
cv.Optional(CONF_INCLUDES_C, default=[]): cv.ensure_list(valid_include),
|
||||
cv.Optional(CONF_LIBRARIES, default=[]): cv.ensure_list(cv.string_strict),
|
||||
cv.Optional(
|
||||
CONF_INCLUDES, default=[], visibility=cv.Visibility.YAML_ONLY
|
||||
): cv.ensure_list(valid_include),
|
||||
cv.Optional(
|
||||
CONF_INCLUDES_C, default=[], visibility=cv.Visibility.YAML_ONLY
|
||||
): cv.ensure_list(valid_include),
|
||||
cv.Optional(
|
||||
CONF_LIBRARIES, default=[], visibility=cv.Visibility.YAML_ONLY
|
||||
): cv.ensure_list(cv.string_strict),
|
||||
cv.Optional(CONF_NAME_ADD_MAC_SUFFIX, default=False): cv.boolean,
|
||||
cv.Optional(CONF_DEBUG_SCHEDULER, default=False): cv.boolean,
|
||||
cv.Optional(
|
||||
CONF_DEBUG_SCHEDULER, default=False, visibility=cv.Visibility.YAML_ONLY
|
||||
): cv.boolean,
|
||||
cv.Optional(CONF_PROJECT): cv.Schema(
|
||||
{
|
||||
cv.Required(CONF_NAME): cv.All(
|
||||
@@ -336,11 +354,15 @@ CONFIG_SCHEMA = cv.All(
|
||||
),
|
||||
}
|
||||
),
|
||||
cv.Optional(CONF_MIN_VERSION, default=ESPHOME_VERSION): cv.All(
|
||||
cv.version_number, cv.validate_esphome_version
|
||||
),
|
||||
cv.Optional(
|
||||
CONF_COMPILE_PROCESS_LIMIT, default=_compile_process_limit_default
|
||||
CONF_MIN_VERSION,
|
||||
default=ESPHOME_VERSION,
|
||||
visibility=cv.Visibility.ADVANCED,
|
||||
): cv.All(cv.version_number, cv.validate_esphome_version),
|
||||
cv.Optional(
|
||||
CONF_COMPILE_PROCESS_LIMIT,
|
||||
default=_compile_process_limit_default,
|
||||
visibility=cv.Visibility.ADVANCED,
|
||||
): cv.int_range(min=1, max=get_usable_cpu_count()),
|
||||
cv.Optional(CONF_AREAS, default=[]): cv.ensure_list(AREA_SCHEMA),
|
||||
cv.Optional(CONF_DEVICES, default=[]): cv.ensure_list(DEVICE_SCHEMA),
|
||||
|
||||
@@ -534,3 +534,37 @@ def test_network_wifi_ble_coexistence_reconciles_end_to_end(
|
||||
assert sdkconfig.get("CONFIG_LWIP_DHCPS") is False
|
||||
# WiFi present alongside BT -> WiFi stack must stay enabled.
|
||||
assert "CONFIG_ESP_WIFI_ENABLED" not in sdkconfig
|
||||
|
||||
|
||||
def test_esp32_build_internals_are_yaml_only() -> None:
|
||||
"""ESP32 raw framework / build inputs are ``YAML_ONLY``.
|
||||
|
||||
The framework block's PlatformIO package pins, raw ESP-IDF
|
||||
sdkconfig options, the low-level ``advanced`` block, extra IDF
|
||||
component sources, plus the partition table and toolchain override
|
||||
on the main schema are build internals — never UI form fields.
|
||||
User-facing choices (framework type/version, board, variant, …)
|
||||
stay on the main form.
|
||||
"""
|
||||
from esphome.components.esp32 import CONFIG_SCHEMA, FRAMEWORK_SCHEMA
|
||||
|
||||
fw_markers = {str(k): k for k in FRAMEWORK_SCHEMA.schema}
|
||||
for field in (
|
||||
"release",
|
||||
"source",
|
||||
"platform_version",
|
||||
"sdkconfig_options",
|
||||
"advanced",
|
||||
"components",
|
||||
):
|
||||
assert fw_markers[field].visibility is cv.Visibility.YAML_ONLY, field
|
||||
# Framework type/version remain user-facing.
|
||||
assert fw_markers["type"].visibility is None
|
||||
assert fw_markers["version"].visibility is None
|
||||
|
||||
main_markers = {str(k): k for k in CONFIG_SCHEMA.validators[0].schema}
|
||||
assert main_markers["partitions"].visibility is cv.Visibility.YAML_ONLY
|
||||
# toolchain is a real but rarely-touched override -> advanced disclosure.
|
||||
assert main_markers["toolchain"].visibility is cv.Visibility.ADVANCED
|
||||
assert main_markers["board"].visibility is None
|
||||
assert main_markers["flash_size"].visibility is None
|
||||
|
||||
@@ -1284,3 +1284,34 @@ async def test_to_code_adds_libraries(yaml_file: Callable[[str], Path]) -> None:
|
||||
mock_cg.add_library.assert_any_call(
|
||||
"noise-c", None, "https://github.com/esphome/noise-c.git"
|
||||
)
|
||||
|
||||
|
||||
def test_esphome_build_internals_are_yaml_only() -> None:
|
||||
"""Raw build-system inputs in the ``esphome:`` block are ``YAML_ONLY``.
|
||||
|
||||
These knobs (compiler flags, raw PlatformIO options, C/C++ includes,
|
||||
libraries, build host parallelism, the min-version gate, …) are not
|
||||
meaningful as visual-editor form fields and a wrong value breaks the
|
||||
build, so they must never render in a schema-aware UI.
|
||||
"""
|
||||
# CONFIG_SCHEMA is cv.All(cv.Schema({...}), validate_hostname).
|
||||
inner = config.CONFIG_SCHEMA.validators[0].schema
|
||||
markers = {str(k): k for k in inner}
|
||||
yaml_only_fields = {
|
||||
CONF_BUILD_PATH,
|
||||
"platformio_options",
|
||||
"build_flags",
|
||||
"environment_variables",
|
||||
"includes",
|
||||
"includes_c",
|
||||
"libraries",
|
||||
"debug_scheduler",
|
||||
}
|
||||
for field in yaml_only_fields:
|
||||
assert markers[field].visibility is cv.Visibility.YAML_ONLY, field
|
||||
# Packaging / build-host knobs are real but rarely-touched overrides:
|
||||
# surface them under the editor's advanced disclosure, not yaml-only.
|
||||
for field in ("min_version", "compile_process_limit"):
|
||||
assert markers[field].visibility is cv.Visibility.ADVANCED, field
|
||||
# A regular device-config field stays on the main form.
|
||||
assert markers[CONF_NAME_ADD_MAC_SUFFIX].visibility is None
|
||||
|
||||
Reference in New Issue
Block a user