From 7aef15ea76ca6117d9923a48b840d9de49ca3e08 Mon Sep 17 00:00:00 2001 From: Jos Verlinde Date: Mon, 8 Jul 2024 18:18:55 +0200 Subject: [PATCH] mpflash: fix device filtering on Windows Signed-off-by: Jos Verlinde --- src/mpflash/mpflash/cli_flash.py | 10 +++++- src/mpflash/mpflash/common.py | 13 +++++--- src/mpflash/mpflash/connected.py | 35 ++++++++++++++++----- src/mpflash/pyproject.toml | 2 +- src/mpflash/tests/test_filtered_comports.py | 6 ++++ 5 files changed, 53 insertions(+), 13 deletions(-) diff --git a/src/mpflash/mpflash/cli_flash.py b/src/mpflash/mpflash/cli_flash.py index 4ba233af..572613b8 100644 --- a/src/mpflash/mpflash/cli_flash.py +++ b/src/mpflash/mpflash/cli_flash.py @@ -67,6 +67,14 @@ show_default=True, metavar="SERIALPORT", ) +@click.option( + "--bluetooth/--no-bluetooth", + "-b/-nb", + is_flag=True, + default=False, + show_default=True, + help="""Include bluetooth ports in the list""", +) @click.option( "--port", "-p", @@ -133,7 +141,7 @@ def cli_flash_board(**kwargs) -> int: all_boards: List[MPRemoteBoard] = [] if not params.boards: # nothing specified - detect connected boards - params.ports, params.boards, all_boards = connected_ports_boards(include=params.ports, ignore=params.ignore) + params.ports, params.boards, all_boards = connected_ports_boards(include=params.ports, ignore=params.ignore, bluetooth=params.bluetooth) if params.boards == []: # No MicroPython boards detected, but it could be unflashed or in bootloader mode # Ask for serial port and board_id to flash diff --git a/src/mpflash/mpflash/common.py b/src/mpflash/mpflash/common.py index 703076ab..5ad8a9ea 100644 --- a/src/mpflash/mpflash/common.py +++ b/src/mpflash/mpflash/common.py @@ -1,6 +1,7 @@ import fnmatch import glob import os +import platform import sys from dataclasses import dataclass, field from enum import Enum @@ -84,6 +85,7 @@ class Params: fw_folder: Path = Path() serial: List[str] = field(default_factory=list) ignore: List[str] = field(default_factory=list) + bluetooth: bool = False @dataclass @@ -138,12 +140,15 @@ def filtered_comports( # remove ports that are to be ignored log.trace(f"{include=}, {ignore=}, {bluetooth=}") - # use p.location to filter out the bogus ports on newer Linux kernels + comports = [ - p - for p in list_ports.comports() - if p.location and not any(fnmatch.fnmatch(p.device, i) for i in ignore) + p for p in list_ports.comports() if not any(fnmatch.fnmatch(p.device, i) for i in ignore) ] + if platform.system() == "Linux": + # use p.location to filter out the bogus ports on newer Linux kernels + # filter out the bogus ports on newer Linux kernels + comports = [p for p in comports if p.location] + log.trace(f"comports: {[p.device for p in comports]}") # remove bluetooth ports diff --git a/src/mpflash/mpflash/connected.py b/src/mpflash/mpflash/connected.py index 0c692c73..9b87934e 100644 --- a/src/mpflash/mpflash/connected.py +++ b/src/mpflash/mpflash/connected.py @@ -4,11 +4,23 @@ from rich.progress import BarColumn, Progress, SpinnerColumn, TextColumn, TimeElapsedColumn from rich.table import Column -from mpflash.common import filtered_comports, find_serial_by_path +from mpflash.common import filtered_comports from mpflash.mpremoteboard import MPRemoteBoard +import os -def connected_ports_boards(*, include: List[str], ignore: List[str]) -> Tuple[List[str], List[str], List[MPRemoteBoard]]: +if os.name == "linux": + from mpflash.common import find_serial_by_path # type: ignore +else: + + def find_serial_by_path(path: str) -> str: + # log.warning(f"find_serial_by_path not implemented for {os.name}") + return path + + +def connected_ports_boards( + *, include: List[str], ignore: List[str], bluetooth: bool = False +) -> Tuple[List[str], List[str], List[MPRemoteBoard]]: """ Returns a tuple containing lists of unique ports and boards from the connected MCUs. Boards that are physically connected, but give no tangible response are ignored. @@ -19,10 +31,17 @@ def connected_ports_boards(*, include: List[str], ignore: List[str]) -> Tuple[Li - A list of unique board names of the connected MCUs. - A list of MPRemoteBoard instances of the connected MCUs. """ - mpr_boards = [b for b in list_mcus(include=include, ignore=ignore) if b.connected] - ports = list({b.port for b in mpr_boards}) - boards = list({b.board for b in mpr_boards}) - return (ports, boards, mpr_boards) + conn_mcus = [ + b for b in list_mcus(include=include, ignore=ignore, bluetooth=bluetooth) if b.connected + ] + # ignore boards that have the [micropython-stubber] ignore flag set + conn_mcus = [ + item for item in conn_mcus if not (item.toml.get("mpflash", {}).get("ignore", False)) + ] + + ports = list({b.port for b in conn_mcus}) + boards = list({b.board for b in conn_mcus}) + return (ports, boards, conn_mcus) # ######################################################################################################### @@ -31,7 +50,9 @@ def connected_ports_boards(*, include: List[str], ignore: List[str]) -> Tuple[Li rp_bar = BarColumn(bar_width=None, table_column=Column()) -def list_mcus(*, ignore: List[str], include: List[str], bluetooth: bool = False) -> List[MPRemoteBoard]: +def list_mcus( + *, ignore: List[str], include: List[str], bluetooth: bool = False +) -> List[MPRemoteBoard]: """ Retrieves information about connected microcontroller boards. diff --git a/src/mpflash/pyproject.toml b/src/mpflash/pyproject.toml index 8d54af14..b9d3ba6b 100644 --- a/src/mpflash/pyproject.toml +++ b/src/mpflash/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "mpflash" -version = "1.0.1" +version = "1.0.2" description = "Flash and download tool for MicroPython firmwares" authors = ["Jos Verlinde "] license = "MIT" diff --git a/src/mpflash/tests/test_filtered_comports.py b/src/mpflash/tests/test_filtered_comports.py index 31e67564..51ffc18b 100644 --- a/src/mpflash/tests/test_filtered_comports.py +++ b/src/mpflash/tests/test_filtered_comports.py @@ -71,6 +71,12 @@ def test_skip_bogus_comports_linux(mocker): ListPortInfo(device="/dev/tty001", skip_link_detection=True), ListPortInfo(device="/dev/tty002", skip_link_detection=True), ] + + def platform_system(): + return "Linux" + + mocker.patch("mpflash.common.platform.system", platform_system) + linux_ports[0].location = f"1-1.1:x.0" mocker.patch("mpflash.common.list_ports.comports", return_value=linux_ports) result = filtered_comports(include=["*"], ignore=[], bluetooth=False)