mirror of
https://github.com/esphome/esphome.git
synced 2025-09-28 08:02:23 +01:00
[core] Rename to clean-platform to clean-all (#10876)
This commit is contained in:
@@ -731,11 +731,11 @@ def command_clean_mqtt(args: ArgsProtocol, config: ConfigType) -> int | None:
|
|||||||
return clean_mqtt(config, args)
|
return clean_mqtt(config, args)
|
||||||
|
|
||||||
|
|
||||||
def command_clean_platform(args: ArgsProtocol, config: ConfigType) -> int | None:
|
def command_clean_all(args: ArgsProtocol) -> int | None:
|
||||||
try:
|
try:
|
||||||
writer.clean_platform()
|
writer.clean_all(args.configuration)
|
||||||
except OSError as err:
|
except OSError as err:
|
||||||
_LOGGER.error("Error deleting platform files: %s", err)
|
_LOGGER.error("Error cleaning all files: %s", err)
|
||||||
return 1
|
return 1
|
||||||
_LOGGER.info("Done!")
|
_LOGGER.info("Done!")
|
||||||
return 0
|
return 0
|
||||||
@@ -931,6 +931,7 @@ PRE_CONFIG_ACTIONS = {
|
|||||||
"dashboard": command_dashboard,
|
"dashboard": command_dashboard,
|
||||||
"vscode": command_vscode,
|
"vscode": command_vscode,
|
||||||
"update-all": command_update_all,
|
"update-all": command_update_all,
|
||||||
|
"clean-all": command_clean_all,
|
||||||
}
|
}
|
||||||
|
|
||||||
POST_CONFIG_ACTIONS = {
|
POST_CONFIG_ACTIONS = {
|
||||||
@@ -941,7 +942,6 @@ POST_CONFIG_ACTIONS = {
|
|||||||
"run": command_run,
|
"run": command_run,
|
||||||
"clean": command_clean,
|
"clean": command_clean,
|
||||||
"clean-mqtt": command_clean_mqtt,
|
"clean-mqtt": command_clean_mqtt,
|
||||||
"clean-platform": command_clean_platform,
|
|
||||||
"mqtt-fingerprint": command_mqtt_fingerprint,
|
"mqtt-fingerprint": command_mqtt_fingerprint,
|
||||||
"idedata": command_idedata,
|
"idedata": command_idedata,
|
||||||
"rename": command_rename,
|
"rename": command_rename,
|
||||||
@@ -951,7 +951,6 @@ POST_CONFIG_ACTIONS = {
|
|||||||
SIMPLE_CONFIG_ACTIONS = [
|
SIMPLE_CONFIG_ACTIONS = [
|
||||||
"clean",
|
"clean",
|
||||||
"clean-mqtt",
|
"clean-mqtt",
|
||||||
"clean-platform",
|
|
||||||
"config",
|
"config",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -1156,11 +1155,9 @@ def parse_args(argv):
|
|||||||
"configuration", help="Your YAML configuration file(s).", nargs="+"
|
"configuration", help="Your YAML configuration file(s).", nargs="+"
|
||||||
)
|
)
|
||||||
|
|
||||||
parser_clean = subparsers.add_parser(
|
parser_clean_all = subparsers.add_parser("clean-all", help="Clean all files.")
|
||||||
"clean-platform", help="Delete all platform files."
|
parser_clean_all.add_argument(
|
||||||
)
|
"configuration", help="Your YAML configuration directory.", nargs="*"
|
||||||
parser_clean.add_argument(
|
|
||||||
"configuration", help="Your YAML configuration file(s).", nargs="+"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
parser_dashboard = subparsers.add_parser(
|
parser_dashboard = subparsers.add_parser(
|
||||||
@@ -1209,7 +1206,7 @@ def parse_args(argv):
|
|||||||
|
|
||||||
parser_update = subparsers.add_parser("update-all")
|
parser_update = subparsers.add_parser("update-all")
|
||||||
parser_update.add_argument(
|
parser_update.add_argument(
|
||||||
"configuration", help="Your YAML configuration file directories.", nargs="+"
|
"configuration", help="Your YAML configuration file or directory.", nargs="+"
|
||||||
)
|
)
|
||||||
|
|
||||||
parser_idedata = subparsers.add_parser("idedata")
|
parser_idedata = subparsers.add_parser("idedata")
|
||||||
|
@@ -479,10 +479,12 @@ class EsphomeCleanMqttHandler(EsphomeCommandWebSocket):
|
|||||||
return [*DASHBOARD_COMMAND, "clean-mqtt", config_file]
|
return [*DASHBOARD_COMMAND, "clean-mqtt", config_file]
|
||||||
|
|
||||||
|
|
||||||
class EsphomeCleanPlatformHandler(EsphomeCommandWebSocket):
|
class EsphomeCleanAllHandler(EsphomeCommandWebSocket):
|
||||||
async def build_command(self, json_message: dict[str, Any]) -> list[str]:
|
async def build_command(self, json_message: dict[str, Any]) -> list[str]:
|
||||||
config_file = settings.rel_path(json_message["configuration"])
|
clean_build_dir = json_message.get("clean_build_dir", True)
|
||||||
return [*DASHBOARD_COMMAND, "clean-platform", config_file]
|
if clean_build_dir:
|
||||||
|
return [*DASHBOARD_COMMAND, "clean-all", settings.config_dir]
|
||||||
|
return [*DASHBOARD_COMMAND, "clean-all"]
|
||||||
|
|
||||||
|
|
||||||
class EsphomeCleanHandler(EsphomeCommandWebSocket):
|
class EsphomeCleanHandler(EsphomeCommandWebSocket):
|
||||||
@@ -1319,7 +1321,7 @@ def make_app(debug=get_bool_env(ENV_DEV)) -> tornado.web.Application:
|
|||||||
(f"{rel}compile", EsphomeCompileHandler),
|
(f"{rel}compile", EsphomeCompileHandler),
|
||||||
(f"{rel}validate", EsphomeValidateHandler),
|
(f"{rel}validate", EsphomeValidateHandler),
|
||||||
(f"{rel}clean-mqtt", EsphomeCleanMqttHandler),
|
(f"{rel}clean-mqtt", EsphomeCleanMqttHandler),
|
||||||
(f"{rel}clean-platform", EsphomeCleanPlatformHandler),
|
(f"{rel}clean-all", EsphomeCleanAllHandler),
|
||||||
(f"{rel}clean", EsphomeCleanHandler),
|
(f"{rel}clean", EsphomeCleanHandler),
|
||||||
(f"{rel}vscode", EsphomeVscodeHandler),
|
(f"{rel}vscode", EsphomeVscodeHandler),
|
||||||
(f"{rel}ace", EsphomeAceEditorHandler),
|
(f"{rel}ace", EsphomeAceEditorHandler),
|
||||||
|
@@ -335,13 +335,15 @@ def clean_build():
|
|||||||
shutil.rmtree(cache_dir)
|
shutil.rmtree(cache_dir)
|
||||||
|
|
||||||
|
|
||||||
def clean_platform():
|
def clean_all(configuration: list[str]):
|
||||||
import shutil
|
import shutil
|
||||||
|
|
||||||
# Clean entire build dir
|
# Clean entire build dir
|
||||||
if CORE.build_path.is_dir():
|
for dir in configuration:
|
||||||
_LOGGER.info("Deleting %s", CORE.build_path)
|
buid_dir = Path(dir) / ".esphome"
|
||||||
shutil.rmtree(CORE.build_path)
|
if buid_dir.is_dir():
|
||||||
|
_LOGGER.info("Deleting %s", buid_dir)
|
||||||
|
shutil.rmtree(buid_dir)
|
||||||
|
|
||||||
# Clean PlatformIO project files
|
# Clean PlatformIO project files
|
||||||
try:
|
try:
|
||||||
|
@@ -17,7 +17,7 @@ from esphome import platformio_api
|
|||||||
from esphome.__main__ import (
|
from esphome.__main__ import (
|
||||||
Purpose,
|
Purpose,
|
||||||
choose_upload_log_host,
|
choose_upload_log_host,
|
||||||
command_clean_platform,
|
command_clean_all,
|
||||||
command_rename,
|
command_rename,
|
||||||
command_update_all,
|
command_update_all,
|
||||||
command_wizard,
|
command_wizard,
|
||||||
@@ -1857,33 +1857,31 @@ esp32:
|
|||||||
assert "can only concatenate str" not in clean_output
|
assert "can only concatenate str" not in clean_output
|
||||||
|
|
||||||
|
|
||||||
def test_command_clean_platform_success(
|
def test_command_clean_all_success(
|
||||||
caplog: pytest.LogCaptureFixture,
|
caplog: pytest.LogCaptureFixture,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test command_clean_platform when writer.clean_platform() succeeds."""
|
"""Test command_clean_all when writer.clean_all() succeeds."""
|
||||||
args = MockArgs()
|
args = MockArgs(configuration=["/path/to/config1", "/path/to/config2"])
|
||||||
config = {}
|
|
||||||
|
|
||||||
# Set logger level to capture INFO messages
|
# Set logger level to capture INFO messages
|
||||||
with (
|
with (
|
||||||
caplog.at_level(logging.INFO),
|
caplog.at_level(logging.INFO),
|
||||||
patch("esphome.writer.clean_platform") as mock_clean_platform,
|
patch("esphome.writer.clean_all") as mock_clean_all,
|
||||||
):
|
):
|
||||||
result = command_clean_platform(args, config)
|
result = command_clean_all(args)
|
||||||
|
|
||||||
assert result == 0
|
assert result == 0
|
||||||
mock_clean_platform.assert_called_once()
|
mock_clean_all.assert_called_once_with(["/path/to/config1", "/path/to/config2"])
|
||||||
|
|
||||||
# Check that success message was logged
|
# Check that success message was logged
|
||||||
assert "Done!" in caplog.text
|
assert "Done!" in caplog.text
|
||||||
|
|
||||||
|
|
||||||
def test_command_clean_platform_oserror(
|
def test_command_clean_all_oserror(
|
||||||
caplog: pytest.LogCaptureFixture,
|
caplog: pytest.LogCaptureFixture,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test command_clean_platform when writer.clean_platform() raises OSError."""
|
"""Test command_clean_all when writer.clean_all() raises OSError."""
|
||||||
args = MockArgs()
|
args = MockArgs(configuration=["/path/to/config1"])
|
||||||
config = {}
|
|
||||||
|
|
||||||
# Create a mock OSError with a specific message
|
# Create a mock OSError with a specific message
|
||||||
mock_error = OSError("Permission denied: cannot delete directory")
|
mock_error = OSError("Permission denied: cannot delete directory")
|
||||||
@@ -1891,30 +1889,27 @@ def test_command_clean_platform_oserror(
|
|||||||
# Set logger level to capture ERROR and INFO messages
|
# Set logger level to capture ERROR and INFO messages
|
||||||
with (
|
with (
|
||||||
caplog.at_level(logging.INFO),
|
caplog.at_level(logging.INFO),
|
||||||
patch(
|
patch("esphome.writer.clean_all", side_effect=mock_error) as mock_clean_all,
|
||||||
"esphome.writer.clean_platform", side_effect=mock_error
|
|
||||||
) as mock_clean_platform,
|
|
||||||
):
|
):
|
||||||
result = command_clean_platform(args, config)
|
result = command_clean_all(args)
|
||||||
|
|
||||||
assert result == 1
|
assert result == 1
|
||||||
mock_clean_platform.assert_called_once()
|
mock_clean_all.assert_called_once_with(["/path/to/config1"])
|
||||||
|
|
||||||
# Check that error message was logged
|
# Check that error message was logged
|
||||||
assert (
|
assert (
|
||||||
"Error deleting platform files: Permission denied: cannot delete directory"
|
"Error cleaning all files: Permission denied: cannot delete directory"
|
||||||
in caplog.text
|
in caplog.text
|
||||||
)
|
)
|
||||||
# Should not have success message
|
# Should not have success message
|
||||||
assert "Done!" not in caplog.text
|
assert "Done!" not in caplog.text
|
||||||
|
|
||||||
|
|
||||||
def test_command_clean_platform_oserror_no_message(
|
def test_command_clean_all_oserror_no_message(
|
||||||
caplog: pytest.LogCaptureFixture,
|
caplog: pytest.LogCaptureFixture,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test command_clean_platform when writer.clean_platform() raises OSError without message."""
|
"""Test command_clean_all when writer.clean_all() raises OSError without message."""
|
||||||
args = MockArgs()
|
args = MockArgs(configuration=["/path/to/config1"])
|
||||||
config = {}
|
|
||||||
|
|
||||||
# Create a mock OSError without a message
|
# Create a mock OSError without a message
|
||||||
mock_error = OSError()
|
mock_error = OSError()
|
||||||
@@ -1922,34 +1917,33 @@ def test_command_clean_platform_oserror_no_message(
|
|||||||
# Set logger level to capture ERROR and INFO messages
|
# Set logger level to capture ERROR and INFO messages
|
||||||
with (
|
with (
|
||||||
caplog.at_level(logging.INFO),
|
caplog.at_level(logging.INFO),
|
||||||
patch(
|
patch("esphome.writer.clean_all", side_effect=mock_error) as mock_clean_all,
|
||||||
"esphome.writer.clean_platform", side_effect=mock_error
|
|
||||||
) as mock_clean_platform,
|
|
||||||
):
|
):
|
||||||
result = command_clean_platform(args, config)
|
result = command_clean_all(args)
|
||||||
|
|
||||||
assert result == 1
|
assert result == 1
|
||||||
mock_clean_platform.assert_called_once()
|
mock_clean_all.assert_called_once_with(["/path/to/config1"])
|
||||||
|
|
||||||
# Check that error message was logged (should show empty string for OSError without message)
|
# Check that error message was logged (should show empty string for OSError without message)
|
||||||
assert "Error deleting platform files:" in caplog.text
|
assert "Error cleaning all files:" in caplog.text
|
||||||
# Should not have success message
|
# Should not have success message
|
||||||
assert "Done!" not in caplog.text
|
assert "Done!" not in caplog.text
|
||||||
|
|
||||||
|
|
||||||
def test_command_clean_platform_args_and_config_ignored() -> None:
|
def test_command_clean_all_args_used() -> None:
|
||||||
"""Test that command_clean_platform ignores args and config parameters."""
|
"""Test that command_clean_all uses args.configuration parameter."""
|
||||||
# Test with various args and config to ensure they don't affect the function
|
# Test with different configuration paths
|
||||||
args1 = MockArgs(name="test1", file="test.bin")
|
args1 = MockArgs(configuration=["/path/to/config1"])
|
||||||
config1 = {"wifi": {"ssid": "test"}}
|
args2 = MockArgs(configuration=["/path/to/config2", "/path/to/config3"])
|
||||||
|
|
||||||
args2 = MockArgs(name="test2", dashboard=True)
|
with patch("esphome.writer.clean_all") as mock_clean_all:
|
||||||
config2 = {"api": {}, "ota": {}}
|
result1 = command_clean_all(args1)
|
||||||
|
result2 = command_clean_all(args2)
|
||||||
with patch("esphome.writer.clean_platform") as mock_clean_platform:
|
|
||||||
result1 = command_clean_platform(args1, config1)
|
|
||||||
result2 = command_clean_platform(args2, config2)
|
|
||||||
|
|
||||||
assert result1 == 0
|
assert result1 == 0
|
||||||
assert result2 == 0
|
assert result2 == 0
|
||||||
assert mock_clean_platform.call_count == 2
|
assert mock_clean_all.call_count == 2
|
||||||
|
|
||||||
|
# Verify the correct configuration paths were passed
|
||||||
|
mock_clean_all.assert_any_call(["/path/to/config1"])
|
||||||
|
mock_clean_all.assert_any_call(["/path/to/config2", "/path/to/config3"])
|
||||||
|
@@ -738,16 +738,24 @@ def test_write_cpp_with_duplicate_markers(
|
|||||||
|
|
||||||
|
|
||||||
@patch("esphome.writer.CORE")
|
@patch("esphome.writer.CORE")
|
||||||
def test_clean_platform(
|
def test_clean_all(
|
||||||
mock_core: MagicMock,
|
mock_core: MagicMock,
|
||||||
tmp_path: Path,
|
tmp_path: Path,
|
||||||
caplog: pytest.LogCaptureFixture,
|
caplog: pytest.LogCaptureFixture,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test clean_platform removes build and PlatformIO dirs."""
|
"""Test clean_all removes build and PlatformIO dirs."""
|
||||||
# Create build directory
|
# Create build directories for multiple configurations
|
||||||
build_dir = tmp_path / "build"
|
config1_dir = tmp_path / "config1"
|
||||||
build_dir.mkdir()
|
config2_dir = tmp_path / "config2"
|
||||||
(build_dir / "dummy.txt").write_text("x")
|
config1_dir.mkdir()
|
||||||
|
config2_dir.mkdir()
|
||||||
|
|
||||||
|
build_dir1 = config1_dir / ".esphome"
|
||||||
|
build_dir2 = config2_dir / ".esphome"
|
||||||
|
build_dir1.mkdir()
|
||||||
|
build_dir2.mkdir()
|
||||||
|
(build_dir1 / "dummy.txt").write_text("x")
|
||||||
|
(build_dir2 / "dummy.txt").write_text("x")
|
||||||
|
|
||||||
# Create PlatformIO directories
|
# Create PlatformIO directories
|
||||||
pio_cache = tmp_path / "pio_cache"
|
pio_cache = tmp_path / "pio_cache"
|
||||||
@@ -758,9 +766,6 @@ def test_clean_platform(
|
|||||||
d.mkdir()
|
d.mkdir()
|
||||||
(d / "keep").write_text("x")
|
(d / "keep").write_text("x")
|
||||||
|
|
||||||
# Setup CORE
|
|
||||||
mock_core.build_path = build_dir
|
|
||||||
|
|
||||||
# Mock ProjectConfig
|
# Mock ProjectConfig
|
||||||
with patch(
|
with patch(
|
||||||
"platformio.project.config.ProjectConfig.get_instance"
|
"platformio.project.config.ProjectConfig.get_instance"
|
||||||
@@ -780,13 +785,14 @@ def test_clean_platform(
|
|||||||
mock_config.get.side_effect = cfg_get
|
mock_config.get.side_effect = cfg_get
|
||||||
|
|
||||||
# Call
|
# Call
|
||||||
from esphome.writer import clean_platform
|
from esphome.writer import clean_all
|
||||||
|
|
||||||
with caplog.at_level("INFO"):
|
with caplog.at_level("INFO"):
|
||||||
clean_platform()
|
clean_all([str(config1_dir), str(config2_dir)])
|
||||||
|
|
||||||
# Verify deletions
|
# Verify deletions
|
||||||
assert not build_dir.exists()
|
assert not build_dir1.exists()
|
||||||
|
assert not build_dir2.exists()
|
||||||
assert not pio_cache.exists()
|
assert not pio_cache.exists()
|
||||||
assert not pio_packages.exists()
|
assert not pio_packages.exists()
|
||||||
assert not pio_platforms.exists()
|
assert not pio_platforms.exists()
|
||||||
@@ -794,7 +800,8 @@ def test_clean_platform(
|
|||||||
|
|
||||||
# Verify logging mentions each
|
# Verify logging mentions each
|
||||||
assert "Deleting" in caplog.text
|
assert "Deleting" in caplog.text
|
||||||
assert str(build_dir) in caplog.text
|
assert str(build_dir1) in caplog.text
|
||||||
|
assert str(build_dir2) in caplog.text
|
||||||
assert "PlatformIO cache" in caplog.text
|
assert "PlatformIO cache" in caplog.text
|
||||||
assert "PlatformIO packages" in caplog.text
|
assert "PlatformIO packages" in caplog.text
|
||||||
assert "PlatformIO platforms" in caplog.text
|
assert "PlatformIO platforms" in caplog.text
|
||||||
@@ -802,28 +809,29 @@ def test_clean_platform(
|
|||||||
|
|
||||||
|
|
||||||
@patch("esphome.writer.CORE")
|
@patch("esphome.writer.CORE")
|
||||||
def test_clean_platform_platformio_not_available(
|
def test_clean_all_platformio_not_available(
|
||||||
mock_core: MagicMock,
|
mock_core: MagicMock,
|
||||||
tmp_path: Path,
|
tmp_path: Path,
|
||||||
caplog: pytest.LogCaptureFixture,
|
caplog: pytest.LogCaptureFixture,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test clean_platform when PlatformIO is not available."""
|
"""Test clean_all when PlatformIO is not available."""
|
||||||
# Build dir
|
# Build dirs
|
||||||
build_dir = tmp_path / "build"
|
config_dir = tmp_path / "config"
|
||||||
|
config_dir.mkdir()
|
||||||
|
build_dir = config_dir / ".esphome"
|
||||||
build_dir.mkdir()
|
build_dir.mkdir()
|
||||||
mock_core.build_path = build_dir
|
|
||||||
|
|
||||||
# PlatformIO dirs that should remain untouched
|
# PlatformIO dirs that should remain untouched
|
||||||
pio_cache = tmp_path / "pio_cache"
|
pio_cache = tmp_path / "pio_cache"
|
||||||
pio_cache.mkdir()
|
pio_cache.mkdir()
|
||||||
|
|
||||||
from esphome.writer import clean_platform
|
from esphome.writer import clean_all
|
||||||
|
|
||||||
with (
|
with (
|
||||||
patch.dict("sys.modules", {"platformio.project.config": None}),
|
patch.dict("sys.modules", {"platformio.project.config": None}),
|
||||||
caplog.at_level("INFO"),
|
caplog.at_level("INFO"),
|
||||||
):
|
):
|
||||||
clean_platform()
|
clean_all([str(config_dir)])
|
||||||
|
|
||||||
# Build dir removed, PlatformIO dirs remain
|
# Build dir removed, PlatformIO dirs remain
|
||||||
assert not build_dir.exists()
|
assert not build_dir.exists()
|
||||||
@@ -834,14 +842,15 @@ def test_clean_platform_platformio_not_available(
|
|||||||
|
|
||||||
|
|
||||||
@patch("esphome.writer.CORE")
|
@patch("esphome.writer.CORE")
|
||||||
def test_clean_platform_partial_exists(
|
def test_clean_all_partial_exists(
|
||||||
mock_core: MagicMock,
|
mock_core: MagicMock,
|
||||||
tmp_path: Path,
|
tmp_path: Path,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test clean_platform when only build dir exists."""
|
"""Test clean_all when only some build dirs exist."""
|
||||||
build_dir = tmp_path / "build"
|
config_dir = tmp_path / "config"
|
||||||
|
config_dir.mkdir()
|
||||||
|
build_dir = config_dir / ".esphome"
|
||||||
build_dir.mkdir()
|
build_dir.mkdir()
|
||||||
mock_core.build_path = build_dir
|
|
||||||
|
|
||||||
with patch(
|
with patch(
|
||||||
"platformio.project.config.ProjectConfig.get_instance"
|
"platformio.project.config.ProjectConfig.get_instance"
|
||||||
@@ -853,8 +862,8 @@ def test_clean_platform_partial_exists(
|
|||||||
tmp_path / "does_not_exist"
|
tmp_path / "does_not_exist"
|
||||||
)
|
)
|
||||||
|
|
||||||
from esphome.writer import clean_platform
|
from esphome.writer import clean_all
|
||||||
|
|
||||||
clean_platform()
|
clean_all([str(config_dir)])
|
||||||
|
|
||||||
assert not build_dir.exists()
|
assert not build_dir.exists()
|
||||||
|
Reference in New Issue
Block a user