From 7e9b637143bdfeca7d79a7b0309ad0bfe7f254cb Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Sat, 15 Apr 2023 19:21:46 +0300 Subject: [PATCH] Resolved an issue where the PlatformIO Debugging solution was not escaping the tool installation process into MI2 correctly // Resolve #4565 --- HISTORY.rst | 4 +- platformio/debug/cli.py | 99 ++++++++++++++------------------- platformio/debug/config/base.py | 6 +- 3 files changed, 47 insertions(+), 62 deletions(-) diff --git a/HISTORY.rst b/HISTORY.rst index 64971a1ffe..9ff6d5f4f5 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -6,6 +6,7 @@ Release Notes .. |LDF| replace:: `LDF `__ .. |INTERPOLATION| replace:: `Interpolation of Values `__ .. |UNITTESTING| replace:: `Unit Testing `__ +.. |DEBUGGING| replace:: `Debugging `__ .. _release_notes_6: @@ -26,9 +27,10 @@ PlatformIO Core 6 * Implemented a fix for shell injection vulnerabilities when converting INO files to CPP, ensuring your code is safe and secure (`issue #4532 `_) * Restored the project generator for the `NetBeans IDE `__, providing you with more flexibility and options for your development workflow * Resolved an issue where the `build_cache_dir `__ setting was not being recognized consistently across multiple environments (`issue #4574 `_) -* Fixed an issue where organization details could not be updated using the `pio org update `__ command +* Resolved an issue where organization details could not be updated using the `pio org update `__ command * Resolved an issue where the incorrect debugging environment was generated for VSCode in "Auto" mode (`issue #4597 `_) * Resolved an issue where native tests would fail if a custom program name was specified (`issue #4546 `_) +* Resolved an issue where the PlatformIO |DEBUGGING| solution was not escaping the tool installation process into MI2 correctly (`issue #4565 `_) 6.1.6 (2023-01-23) ~~~~~~~~~~~~~~~~~~ diff --git a/platformio/debug/cli.py b/platformio/debug/cli.py index 64bd1b4399..7137c98dd0 100644 --- a/platformio/debug/cli.py +++ b/platformio/debug/cli.py @@ -28,9 +28,9 @@ from platformio.debug.config.factory import DebugConfigFactory from platformio.debug.exception import DebugInvalidOptionsError from platformio.debug.process.gdb import GDBClientProcess +from platformio.exception import ReturnErrorCode from platformio.platform.factory import PlatformFactory from platformio.project.config import ProjectConfig -from platformio.project.exception import ProjectEnvsNotAvailableError from platformio.project.helpers import is_platformio_project from platformio.project.options import ProjectOptions @@ -81,61 +81,57 @@ def cli( project_dir = os.getenv(name) with fs.cd(project_dir): - return _debug_in_project_dir( + project_config = ProjectConfig.get_instance(project_conf) + project_config.validate(envs=[environment] if environment else None) + env_name = environment or helpers.get_default_debug_env(project_config) + + if not interface: + return helpers.predebug_project( + ctx, project_dir, project_config, env_name, False, verbose + ) + + configure_args = ( ctx, - project_dir, - project_conf, - environment, + project_config, + env_name, load_mode, verbose, - interface, __unprocessed, ) + if helpers.is_gdbmi_mode(): + os.environ["PLATFORMIO_DISABLE_PROGRESSBAR"] = "true" + stream = helpers.GDBMIConsoleStream() + with proc.capture_std_streams(stream): + debug_config = _configure(*configure_args) + stream.close() + else: + debug_config = _configure(*configure_args) + _run(project_dir, debug_config, __unprocessed) -def _debug_in_project_dir( - ctx, - project_dir, - project_conf, - environment, - load_mode, - verbose, - interface, - __unprocessed, -): - project_config = ProjectConfig.get_instance(project_conf) - project_config.validate(envs=[environment] if environment else None) - env_name = environment or helpers.get_default_debug_env(project_config) - - if not interface: - return helpers.predebug_project( - ctx, project_dir, project_config, env_name, False, verbose - ) + return None - env_options = project_config.items(env=env_name, as_dict=True) - if "platform" not in env_options: - raise ProjectEnvsNotAvailableError() +def _configure(ctx, project_config, env_name, load_mode, verbose, __unprocessed): + platform = PlatformFactory.new( + project_config.get(f"env:{env_name}", "platform"), autoinstall=True + ) debug_config = DebugConfigFactory.new( - PlatformFactory.new(env_options["platform"], autoinstall=True), + platform, project_config, env_name, ) - if "--version" in __unprocessed: - return subprocess.run( - [debug_config.client_executable_path, "--version"], check=True + raise ReturnErrorCode( + subprocess.run( + [debug_config.client_executable_path, "--version"], check=True + ).returncode ) try: fs.ensure_udev_rules() except exception.InvalidUdevRules as exc: - click.echo( - helpers.escape_gdbmi_stream("~", str(exc) + "\n") - if helpers.is_gdbmi_mode() - else str(exc) + "\n", - nl=False, - ) + click.echo(str(exc)) rebuild_prog = False preload = debug_config.load_cmds == ["preload"] @@ -157,25 +153,10 @@ def _debug_in_project_dir( debug_config.load_cmds = [] if rebuild_prog: - if helpers.is_gdbmi_mode(): - click.echo( - helpers.escape_gdbmi_stream( - "~", "Preparing firmware for debugging...\n" - ), - nl=False, - ) - stream = helpers.GDBMIConsoleStream() - with proc.capture_std_streams(stream): - helpers.predebug_project( - ctx, project_dir, project_config, env_name, preload, verbose - ) - stream.close() - else: - click.echo("Preparing firmware for debugging...") - helpers.predebug_project( - ctx, project_dir, project_config, env_name, preload, verbose - ) - + click.echo("Preparing firmware for debugging...") + helpers.predebug_project( + ctx, os.getcwd(), project_config, env_name, preload, verbose + ) # save SHA sum of newly created prog if load_mode == "modified": helpers.is_prog_obsolete(debug_config.program_path) @@ -183,6 +164,10 @@ def _debug_in_project_dir( if not os.path.isfile(debug_config.program_path): raise DebugInvalidOptionsError("Program/firmware is missed") + return debug_config + + +def _run(project_dir, debug_config, __unprocessed): loop = asyncio.ProactorEventLoop() if IS_WINDOWS else asyncio.get_event_loop() asyncio.set_event_loop(loop) @@ -199,5 +184,3 @@ def _debug_in_project_dir( finally: client.close() loop.close() - - return True diff --git a/platformio/debug/config/base.py b/platformio/debug/config/base.py index 24e20516d8..cb49658174 100644 --- a/platformio/debug/config/base.py +++ b/platformio/debug/config/base.py @@ -146,9 +146,9 @@ def server_ready_pattern(self): def _load_build_data(self): data = load_build_metadata(os.getcwd(), self.env_name, cache=True, debug=True) - if data: - return data - raise DebugInvalidOptionsError("Could not load a build configuration") + if not data: + raise DebugInvalidOptionsError("Could not load a build configuration") + return data def _configure_server(self): # user disabled server in platformio.ini