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