From 30709fd0b36e135642565cdd3e89f2a8eb9331c6 Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Wed, 15 Jun 2022 15:36:17 +0300 Subject: [PATCH] Replaced monitor_flags with independent project configuration options: monitor_parity, monitor_eol, monitor_raw, monitor_echo --- HISTORY.rst | 2 + docs | 2 +- platformio/device/monitor/command.py | 64 ++++++++++++++---------- platformio/project/options.py | 31 +++++++++--- platformio/remote/cli.py | 75 ++++++++++++++-------------- 5 files changed, 103 insertions(+), 71 deletions(-) diff --git a/HISTORY.rst b/HISTORY.rst index b3f0490e..3a423748 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -21,6 +21,8 @@ PlatformIO Core 6 - Automatically reconnect if a connection fails - Added new `pio device monitor --no-reconnect `__ option to disable automatic reconnection - Handle disconnects more gracefully (`issue #3939 `_) + - Replaced ``monitor_flags`` with independent project configuration options: `monitor_parity `__, `monitor_eol `__, `monitor_raw `__, `monitor_echo `__ + - Fixed an issue when the monitor filters were not applied in their order (`issue #4320 `_) * Improved a serial port finder for a board with predefined HWIDs * Merged the |UNITTESTING| "building" stage with "uploading" for the embedded target (`issue #4307 `_) diff --git a/docs b/docs index f0acc304..a3c98fe6 160000 --- a/docs +++ b/docs @@ -1 +1 @@ -Subproject commit f0acc3040fa8132d59ef7b930052a36d4c6e0bd6 +Subproject commit a3c98fe6f3cf13738d16b497f0396c7bbe20ae0c diff --git a/platformio/device/monitor/command.py b/platformio/device/monitor/command.py index 16f3e8df..44df4043 100644 --- a/platformio/device/monitor/command.py +++ b/platformio/device/monitor/command.py @@ -13,6 +13,7 @@ # limitations under the License. import os +import sys import click @@ -31,24 +32,26 @@ from platformio.project.options import ProjectOptions @click.option( "-b", "--baud", - type=int, - show_default=True, + type=ProjectOptions["env.monitor_speed"].type, help="Set baud/speed [default=%d]" % ProjectOptions["env.monitor_speed"].default, ) @click.option( "--parity", - default="N", - show_default=True, - type=click.Choice(["N", "E", "O", "S", "M"]), - help="Set parity", + type=ProjectOptions["env.monitor_parity"].type, + help="Enable parity checking [default=%s]" + % ProjectOptions["env.monitor_parity"].default, ) @click.option("--rtscts", is_flag=True, help="Enable RTS/CTS flow control") @click.option("--xonxoff", is_flag=True, help="Enable software flow control") @click.option( - "--rts", default=None, type=click.IntRange(0, 1), help="Set initial RTS line state" + "--rts", + type=ProjectOptions["env.monitor_rts"].type, + help="Set initial RTS line state", ) @click.option( - "--dtr", default=None, type=click.IntRange(0, 1), help="Set initial DTR line state" + "--dtr", + type=ProjectOptions["env.monitor_dtr"].type, + help="Set initial DTR line state", ) @click.option("--echo", is_flag=True, help="Enable local echo") @click.option( @@ -58,16 +61,18 @@ from platformio.project.options import ProjectOptions help="Set the encoding for the serial port (e.g. hexlify, Latin1, UTF-8)", ) @click.option( - "-f", "--filter", "filters", multiple=True, help="Add filters/text transformations" + "-f", + "--filter", + "filters", + multiple=True, + help="Apply filters/text transformations", ) @click.option( "--eol", - default="CRLF", - show_default=True, - type=click.Choice(["CR", "LF", "CRLF"]), - help="End of line mode", + type=ProjectOptions["env.monitor_eol"].type, + help="End of line mode [default=%s]" % ProjectOptions["env.monitor_eol"].default, ) -@click.option("--raw", is_flag=True, help="Do not apply any encodings/transformations") +@click.option("--raw", is_flag=True, help=ProjectOptions["env.monitor_raw"].description) @click.option( "--exit-char", type=int, @@ -105,16 +110,17 @@ from platformio.project.options import ProjectOptions help="Load configuration from `platformio.ini` and the specified environment", ) def device_monitor_cmd(**options): - platform = None - project_options = {} with fs.cd(options["project_dir"]): + platform = None + project_options = {} try: project_options = get_project_options(options["environment"]) - options = apply_project_monitor_options(options, project_options) if "platform" in project_options: platform = PlatformFactory.new(project_options["platform"]) except NotPlatformIOProjectError: pass + + options = apply_project_monitor_options(options, project_options) register_filters(platform=platform, options=options) options["port"] = find_serial_port( initial_port=options["port"], @@ -125,8 +131,6 @@ def device_monitor_cmd(**options): ensure_ready=True, ) - options["baud"] = options["baud"] or ProjectOptions["env.monitor_speed"].default - if options["menu_char"] == options["exit_char"]: raise exception.UserSideException( "--exit-char can not be the same as --menu-char" @@ -143,12 +147,18 @@ def get_project_options(environment=None): def apply_project_monitor_options(initial_options, project_options): - for k in ("port", "speed", "rts", "dtr"): - k2 = "monitor_%s" % k - if k == "speed": - k = "baud" - if initial_options[k] is None and k2 in project_options: - initial_options[k] = project_options[k2] - if k != "port": - initial_options[k] = int(initial_options[k]) + for option_meta in ProjectOptions.values(): + if option_meta.group != "monitor": + continue + cli_key = option_meta.name.split("_", 1)[1] + if cli_key == "speed": + cli_key = "baud" + # value set from CLI, skip overriding + if initial_options[cli_key] not in (None, (), []) and ( + option_meta.type != click.BOOL or f"--{cli_key}" in sys.argv[1:] + ): + continue + initial_options[cli_key] = project_options.get( + option_meta.name, option_meta.default + ) return initial_options diff --git a/platformio/project/options.py b/platformio/project/options.py index ad96b24c..21a9a130 100644 --- a/platformio/project/options.py +++ b/platformio/project/options.py @@ -519,6 +519,13 @@ ProjectOptions = OrderedDict( oldnames=["monitor_baud"], default=9600, ), + ConfigEnvOption( + group="monitor", + name="monitor_parity", + description="A monitor parity checking", + type=click.Choice(["N", "E", "O", "S", "M"]), + default="N", + ), ConfigEnvOption( group="monitor", name="monitor_filters", @@ -541,12 +548,24 @@ ProjectOptions = OrderedDict( ), ConfigEnvOption( group="monitor", - name="monitor_flags", - description=( - "The extra flags and options for `platformio device monitor` " - "command" - ), - multiple=True, + name="monitor_eol", + description="A monitor end of line mode", + type=click.Choice(["CR", "LF", "CRLF"]), + default="CRLF", + ), + ConfigEnvOption( + group="monitor", + name="monitor_raw", + description="Disable encodings/transformations of device output", + type=click.BOOL, + default=False, + ), + ConfigEnvOption( + group="monitor", + name="monitor_echo", + description="Enable a monitor local echo", + type=click.BOOL, + default=False, ), # Library ConfigEnvOption( diff --git a/platformio/remote/cli.py b/platformio/remote/cli.py index 25f53800..bede41d1 100644 --- a/platformio/remote/cli.py +++ b/platformio/remote/cli.py @@ -270,60 +270,67 @@ def device_list(agents, json_output): @remote_device.command("monitor", short_help="Monitor remote device") @click.option("--port", "-p", help="Port, a number or a device name") @click.option( - "--baud", "-b", - type=int, - help="Set baud rate, default=%d" % ProjectOptions["env.monitor_speed"].default, + "--baud", + type=ProjectOptions["env.monitor_speed"].type, + help="Set baud/speed [default=%d]" % ProjectOptions["env.monitor_speed"].default, ) @click.option( "--parity", - default="N", - type=click.Choice(["N", "E", "O", "S", "M"]), - help="Set parity, default=N", + type=ProjectOptions["env.monitor_parity"].type, + help="Set parity [default=%s]" % ProjectOptions["env.monitor_parity"].default, ) -@click.option("--rtscts", is_flag=True, help="Enable RTS/CTS flow control, default=Off") +@click.option("--rtscts", is_flag=True, help="Enable RTS/CTS flow control") +@click.option("--xonxoff", is_flag=True, help="Enable software flow control") @click.option( - "--xonxoff", is_flag=True, help="Enable software flow control, default=Off" + "--rts", + type=ProjectOptions["env.monitor_rts"].type, + help="Set initial RTS line state", ) @click.option( - "--rts", default=None, type=click.IntRange(0, 1), help="Set initial RTS line state" + "--dtr", + type=ProjectOptions["env.monitor_dtr"].type, + help="Set initial DTR line state", ) -@click.option( - "--dtr", default=None, type=click.IntRange(0, 1), help="Set initial DTR line state" -) -@click.option("--echo", is_flag=True, help="Enable local echo, default=Off") +@click.option("--echo", is_flag=True, help="Enable local echo") @click.option( "--encoding", default="UTF-8", - help="Set the encoding for the serial port (e.g. hexlify, " - "Latin1, UTF-8), default: UTF-8", + show_default=True, + help="Set the encoding for the serial port (e.g. hexlify, Latin1, UTF-8)", +) +@click.option( + "-f", + "--filter", + "filters", + multiple=True, + help="Apply filters/text transformations", ) -@click.option("--filter", "-f", multiple=True, help="Add text transformation") @click.option( "--eol", - default="CRLF", - type=click.Choice(["CR", "LF", "CRLF"]), - help="End of line mode, default=CRLF", + type=ProjectOptions["env.monitor_eol"].type, + help="End of line mode [default=%s]" % ProjectOptions["env.monitor_eol"].default, ) -@click.option("--raw", is_flag=True, help="Do not apply any encodings/transformations") +@click.option("--raw", is_flag=True, help=ProjectOptions["env.monitor_raw"].description) @click.option( "--exit-char", type=int, default=3, + show_default=True, help="ASCII code of special character that is used to exit " - "the application, default=3 (Ctrl+C)", + "the application [default=3 (Ctrl+C)]", ) @click.option( "--menu-char", type=int, default=20, help="ASCII code of special character that is used to " - "control miniterm (menu), default=20 (DEC)", + "control terminal (menu) [default=20 (DEC)]", ) @click.option( "--quiet", is_flag=True, - help="Diagnostics: suppress non-error messages, default=Off", + help="Diagnostics: suppress non-error messages", ) @click.option( "-d", @@ -354,19 +361,17 @@ def device_monitor(ctx, agents, **kwargs): try: with fs.cd(kwargs["project_dir"]): project_options = get_project_options(kwargs["environment"]) - kwargs = apply_project_monitor_options(kwargs, project_options) except NotPlatformIOProjectError: pass - kwargs["baud"] = kwargs["baud"] or ProjectOptions["env.monitor_speed"].default - kwargs["reconnect"] = False + kwargs = apply_project_monitor_options(kwargs, project_options) def _tx_target(sock_dir): subcmd_argv = ["remote"] for agent in agents: subcmd_argv.extend(["--agent", agent]) subcmd_argv.extend(["device", "monitor"]) - subcmd_argv.extend(project_options_to_monitor_argv(kwargs, project_options)) + subcmd_argv.extend(project_options_to_monitor_argv(kwargs)) subcmd_argv.extend(["--sock", sock_dir]) subprocess.call([proc.where_is_program("platformio")] + subcmd_argv) @@ -381,6 +386,7 @@ def device_monitor(ctx, agents, **kwargs): return with open(sock_file, encoding="utf8") as fp: kwargs["port"] = fp.read() + kwargs["no_reconnect"] = True ctx.invoke(device_monitor_cmd, **kwargs) t.join(2) finally: @@ -389,19 +395,14 @@ def device_monitor(ctx, agents, **kwargs): return True -def project_options_to_monitor_argv(cli_options, project_options, ignore=None): - confmon_flags = project_options.get("monitor_flags", []) - result = confmon_flags[::] - - for f in project_options.get("monitor_filters", []): - result.extend(["--filter", f]) - +def project_options_to_monitor_argv(cli_options): + result = [] + for item in cli_options["filters"] or []: + result.extend(["--filter", item]) for k, v in cli_options.items(): - if v is None or (ignore and k in ignore): + if v is None or k == "filters": continue k = "--" + k.replace("_", "-") - if k in confmon_flags: - continue if isinstance(v, bool): if v: result.append(k)