micropython-stubber 1.23.1__py3-none-any.whl → 1.23.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (153) hide show
  1. {micropython_stubber-1.23.1.dist-info → micropython_stubber-1.23.2.dist-info}/LICENSE +30 -30
  2. {micropython_stubber-1.23.1.dist-info → micropython_stubber-1.23.2.dist-info}/METADATA +32 -15
  3. micropython_stubber-1.23.2.dist-info/RECORD +158 -0
  4. micropython_stubber-1.23.2.dist-info/entry_points.txt +5 -0
  5. mpflash/README.md +220 -194
  6. mpflash/libusb_flash.ipynb +203 -203
  7. mpflash/mpflash/add_firmware.py +98 -98
  8. mpflash/mpflash/ask_input.py +236 -236
  9. mpflash/mpflash/basicgit.py +284 -284
  10. mpflash/mpflash/bootloader/__init__.py +2 -2
  11. mpflash/mpflash/bootloader/activate.py +60 -60
  12. mpflash/mpflash/bootloader/detect.py +82 -82
  13. mpflash/mpflash/bootloader/manual.py +101 -101
  14. mpflash/mpflash/bootloader/micropython.py +12 -12
  15. mpflash/mpflash/bootloader/touch1200.py +36 -36
  16. mpflash/mpflash/cli_download.py +129 -129
  17. mpflash/mpflash/cli_flash.py +224 -219
  18. mpflash/mpflash/cli_group.py +111 -111
  19. mpflash/mpflash/cli_list.py +87 -81
  20. mpflash/mpflash/cli_main.py +39 -39
  21. mpflash/mpflash/common.py +210 -165
  22. mpflash/mpflash/config.py +44 -44
  23. mpflash/mpflash/connected.py +96 -78
  24. mpflash/mpflash/download.py +364 -364
  25. mpflash/mpflash/downloaded.py +130 -130
  26. mpflash/mpflash/errors.py +9 -9
  27. mpflash/mpflash/flash/__init__.py +55 -55
  28. mpflash/mpflash/flash/esp.py +59 -59
  29. mpflash/mpflash/flash/stm32.py +19 -19
  30. mpflash/mpflash/flash/stm32_dfu.py +104 -104
  31. mpflash/mpflash/flash/uf2/__init__.py +88 -88
  32. mpflash/mpflash/flash/uf2/boardid.py +15 -15
  33. mpflash/mpflash/flash/uf2/linux.py +136 -130
  34. mpflash/mpflash/flash/uf2/macos.py +42 -42
  35. mpflash/mpflash/flash/uf2/uf2disk.py +12 -12
  36. mpflash/mpflash/flash/uf2/windows.py +43 -43
  37. mpflash/mpflash/flash/worklist.py +170 -170
  38. mpflash/mpflash/list.py +106 -99
  39. mpflash/mpflash/logger.py +41 -41
  40. mpflash/mpflash/mpboard_id/__init__.py +93 -93
  41. mpflash/mpflash/mpboard_id/add_boards.py +251 -251
  42. mpflash/mpflash/mpboard_id/board.py +37 -37
  43. mpflash/mpflash/mpboard_id/board_id.py +86 -86
  44. mpflash/mpflash/mpboard_id/store.py +43 -43
  45. mpflash/mpflash/mpremoteboard/__init__.py +266 -222
  46. mpflash/mpflash/mpremoteboard/mpy_fw_info.py +141 -141
  47. mpflash/mpflash/mpremoteboard/runner.py +140 -140
  48. mpflash/mpflash/vendor/click_aliases.py +91 -91
  49. mpflash/mpflash/vendor/dfu.py +165 -165
  50. mpflash/mpflash/vendor/pydfu.py +605 -605
  51. mpflash/mpflash/vendor/readme.md +2 -2
  52. mpflash/mpflash/versions.py +135 -135
  53. mpflash/poetry.lock +1599 -1599
  54. mpflash/pyproject.toml +65 -65
  55. mpflash/stm32_udev_rules.md +62 -62
  56. stubber/__init__.py +3 -3
  57. stubber/board/board_info.csv +193 -193
  58. stubber/board/boot.py +34 -34
  59. stubber/board/createstubs.py +1004 -986
  60. stubber/board/createstubs_db.py +826 -825
  61. stubber/board/createstubs_db_min.py +332 -331
  62. stubber/board/createstubs_db_mpy.mpy +0 -0
  63. stubber/board/createstubs_lvgl.py +741 -741
  64. stubber/board/createstubs_lvgl_min.py +741 -741
  65. stubber/board/createstubs_mem.py +767 -766
  66. stubber/board/createstubs_mem_min.py +307 -306
  67. stubber/board/createstubs_mem_mpy.mpy +0 -0
  68. stubber/board/createstubs_min.py +295 -294
  69. stubber/board/createstubs_mpy.mpy +0 -0
  70. stubber/board/fw_info.py +141 -141
  71. stubber/board/info.py +183 -183
  72. stubber/board/main.py +19 -19
  73. stubber/board/modulelist.txt +247 -247
  74. stubber/board/pyrightconfig.json +34 -34
  75. stubber/bulk/mcu_stubber.py +437 -454
  76. stubber/codemod/_partials/__init__.py +48 -48
  77. stubber/codemod/_partials/db_main.py +147 -147
  78. stubber/codemod/_partials/lvgl_main.py +77 -77
  79. stubber/codemod/_partials/modules_reader.py +80 -80
  80. stubber/codemod/add_comment.py +53 -53
  81. stubber/codemod/add_method.py +65 -65
  82. stubber/codemod/board.py +317 -317
  83. stubber/codemod/enrich.py +151 -145
  84. stubber/codemod/merge_docstub.py +284 -284
  85. stubber/codemod/modify_list.py +54 -54
  86. stubber/codemod/utils.py +56 -56
  87. stubber/commands/build_cmd.py +94 -94
  88. stubber/commands/cli.py +49 -55
  89. stubber/commands/clone_cmd.py +78 -78
  90. stubber/commands/config_cmd.py +29 -29
  91. stubber/commands/enrich_folder_cmd.py +71 -71
  92. stubber/commands/get_core_cmd.py +71 -71
  93. stubber/commands/get_docstubs_cmd.py +92 -89
  94. stubber/commands/get_frozen_cmd.py +117 -114
  95. stubber/commands/get_mcu_cmd.py +102 -61
  96. stubber/commands/merge_cmd.py +66 -66
  97. stubber/commands/publish_cmd.py +118 -118
  98. stubber/commands/stub_cmd.py +31 -31
  99. stubber/commands/switch_cmd.py +62 -62
  100. stubber/commands/variants_cmd.py +48 -48
  101. stubber/cst_transformer.py +178 -178
  102. stubber/data/board_info.csv +193 -193
  103. stubber/data/board_info.json +1729 -1729
  104. stubber/data/micropython_tags.csv +15 -15
  105. stubber/data/requirements-core-micropython.txt +38 -38
  106. stubber/data/requirements-core-pycopy.txt +39 -39
  107. stubber/downloader.py +37 -36
  108. stubber/freeze/common.py +72 -68
  109. stubber/freeze/freeze_folder.py +69 -69
  110. stubber/freeze/freeze_manifest_2.py +126 -113
  111. stubber/freeze/get_frozen.py +131 -127
  112. stubber/get_cpython.py +112 -101
  113. stubber/get_lobo.py +59 -59
  114. stubber/minify.py +423 -419
  115. stubber/publish/bump.py +86 -86
  116. stubber/publish/candidates.py +275 -256
  117. stubber/publish/database.py +18 -18
  118. stubber/publish/defaults.py +40 -40
  119. stubber/publish/enums.py +24 -24
  120. stubber/publish/helpers.py +29 -29
  121. stubber/publish/merge_docstubs.py +136 -130
  122. stubber/publish/missing_class_methods.py +51 -49
  123. stubber/publish/package.py +150 -146
  124. stubber/publish/pathnames.py +51 -51
  125. stubber/publish/publish.py +120 -120
  126. stubber/publish/pypi.py +42 -38
  127. stubber/publish/stubpackage.py +1055 -1027
  128. stubber/rst/__init__.py +9 -9
  129. stubber/rst/classsort.py +78 -77
  130. stubber/rst/lookup.py +533 -530
  131. stubber/rst/output_dict.py +401 -401
  132. stubber/rst/reader.py +814 -814
  133. stubber/rst/report_return.py +77 -69
  134. stubber/rst/rst_utils.py +541 -540
  135. stubber/stubber.py +38 -38
  136. stubber/stubs_from_docs.py +90 -90
  137. stubber/tools/manifestfile.py +654 -654
  138. stubber/tools/readme.md +6 -6
  139. stubber/update_fallback.py +117 -117
  140. stubber/update_module_list.py +123 -123
  141. stubber/utils/__init__.py +6 -6
  142. stubber/utils/config.py +137 -125
  143. stubber/utils/makeversionhdr.py +54 -54
  144. stubber/utils/manifest.py +90 -90
  145. stubber/utils/post.py +80 -79
  146. stubber/utils/repos.py +156 -150
  147. stubber/utils/stubmaker.py +139 -139
  148. stubber/utils/typed_config_toml.py +80 -77
  149. stubber/variants.py +106 -106
  150. micropython_stubber-1.23.1.dist-info/RECORD +0 -159
  151. micropython_stubber-1.23.1.dist-info/entry_points.txt +0 -3
  152. mpflash/basicgit.py +0 -288
  153. {micropython_stubber-1.23.1.dist-info → micropython_stubber-1.23.2.dist-info}/WHEEL +0 -0
@@ -1,170 +1,170 @@
1
- """Worklist for updating boards"""
2
-
3
- from pathlib import Path
4
- from typing import Dict, List, Optional, Tuple
5
-
6
- from loguru import logger as log
7
-
8
- from mpflash.common import FWInfo, filtered_comports
9
- from mpflash.downloaded import find_downloaded_firmware
10
- from mpflash.errors import MPFlashError
11
- from mpflash.list import show_mcus
12
- from mpflash.mpboard_id import find_known_board
13
- from mpflash.mpremoteboard import MPRemoteBoard
14
-
15
- # #########################################################################################################
16
- WorkList = List[Tuple[MPRemoteBoard, FWInfo]]
17
- # #########################################################################################################
18
-
19
-
20
- def auto_update(
21
- conn_boards: List[MPRemoteBoard],
22
- target_version: str,
23
- fw_folder: Path,
24
- *,
25
- selector: Optional[Dict[str, str]] = None,
26
- ) -> WorkList:
27
- """Builds a list of boards to update based on the connected boards and the firmwares available locally in the firmware folder.
28
-
29
- Args:
30
- conn_boards (List[MPRemoteBoard]): List of connected boards
31
- target_version (str): Target firmware version
32
- fw_folder (Path): Path to the firmware folder
33
- selector (Optional[Dict[str, str]], optional): Selector for filtering firmware. Defaults to None.
34
-
35
- Returns:
36
- WorkList: List of boards and firmware information to update
37
- """
38
- if selector is None:
39
- selector = {}
40
- wl: WorkList = []
41
- for mcu in conn_boards:
42
- if mcu.family not in ("micropython", "unknown"):
43
- log.warning(f"Skipping flashing {mcu.family} {mcu.port} {mcu.board} on {mcu.serialport} as it is not a MicroPython firmware")
44
- continue
45
- board_firmwares = find_downloaded_firmware(
46
- fw_folder=fw_folder,
47
- board_id=mcu.board,
48
- version=target_version,
49
- port=mcu.port,
50
- selector=selector,
51
- )
52
-
53
- if not board_firmwares:
54
- log.error(f"No {target_version} firmware found for {mcu.board} on {mcu.serialport}.")
55
- continue
56
-
57
- if len(board_firmwares) > 1:
58
- log.warning(f"Multiple {target_version} firmwares found for {mcu.board} on {mcu.serialport}.")
59
-
60
- # just use the last firmware
61
- fw_info = board_firmwares[-1]
62
- log.info(f"Found {target_version} firmware {fw_info.filename} for {mcu.board} on {mcu.serialport}.")
63
- wl.append((mcu, fw_info))
64
- return wl
65
-
66
-
67
- def manual_worklist(
68
- serial: str,
69
- *,
70
- board_id: str,
71
- version: str,
72
- fw_folder: Path,
73
- ) -> WorkList:
74
- """Create a worklist for a single board specified manually.
75
-
76
- Args:
77
- serial (str): Serial port of the board
78
- board (str): Board_ID
79
- version (str): Firmware version
80
- fw_folder (Path): Path to the firmware folder
81
-
82
- Returns:
83
- WorkList: List of boards and firmware information to update
84
- """
85
- log.trace(f"Manual updating {serial} to {board_id} {version}")
86
- mcu = MPRemoteBoard(serial)
87
- # Lookup the matching port and cpu in board_info based in the board name
88
- try:
89
- info = find_known_board(board_id)
90
- mcu.port = info.port
91
- # need the CPU type for the esptool
92
- mcu.cpu = info.cpu
93
- except (LookupError, MPFlashError) as e:
94
- log.error(f"Board {board_id} not found in board_info.zip")
95
- log.exception(e)
96
- return []
97
- mcu.board = board_id
98
- firmwares = find_downloaded_firmware(fw_folder=fw_folder, board_id=board_id, version=version, port=mcu.port)
99
- if not firmwares:
100
- log.error(f"No firmware found for {mcu.port} {board_id} version {version}")
101
- return []
102
- # use the most recent matching firmware
103
- return [(mcu, firmwares[-1])] # type: ignore
104
-
105
-
106
- def single_auto_worklist(
107
- serial: str,
108
- *,
109
- version: str,
110
- fw_folder: Path,
111
- ) -> WorkList:
112
- """Create a worklist for a single serial-port.
113
-
114
- Args:
115
- serial_port (str): Serial port of the board
116
- version (str): Firmware version
117
- fw_folder (Path): Path to the firmware folder
118
-
119
- Returns:
120
- WorkList: List of boards and firmware information to update
121
- """
122
- log.trace(f"Auto updating {serial} to {version}")
123
- conn_boards = [MPRemoteBoard(serial)]
124
- todo = auto_update(conn_boards, version, fw_folder) # type: ignore # List / list
125
- show_mcus(conn_boards) # type: ignore
126
- return todo
127
-
128
-
129
- def full_auto_worklist(
130
- all_boards: List[MPRemoteBoard], *, include: List[str], ignore: List[str], version: str, fw_folder: Path
131
- ) -> WorkList:
132
- """
133
- Create a worklist for all connected micropython boards based on the information retrieved from the board.
134
- This allows the firmware version of one or moae boards to be changed without needing to specify the port or board_id manually.
135
-
136
- Args:
137
- version (str): Firmware version
138
- fw_folder (Path): Path to the firmware folder
139
-
140
- Returns:
141
- WorkList: List of boards and firmware information to update
142
- """
143
- log.trace(f"Auto updating all boards to {version}")
144
- if selected_boards := filter_boards(all_boards, include=include, ignore=ignore):
145
- return auto_update(selected_boards, version, fw_folder)
146
- else:
147
- return []
148
-
149
-
150
- def filter_boards(
151
- all_boards: List[MPRemoteBoard],
152
- *,
153
- include: List[str],
154
- ignore: List[str],
155
- ):
156
- try:
157
- comports = [
158
- p.device
159
- for p in filtered_comports(
160
- ignore=ignore,
161
- include=include,
162
- bluetooth=False,
163
- )
164
- ]
165
- selected_boards = [b for b in all_boards if b.serialport in comports]
166
- # [MPRemoteBoard(port.device, update=True) for port in comports]
167
- except ConnectionError as e:
168
- log.error(f"Error connecting to boards: {e}")
169
- return []
170
- return selected_boards # type: ignore
1
+ """Worklist for updating boards"""
2
+
3
+ from pathlib import Path
4
+ from typing import Dict, List, Optional, Tuple
5
+
6
+ from loguru import logger as log
7
+
8
+ from mpflash.common import FWInfo, filtered_comports
9
+ from mpflash.downloaded import find_downloaded_firmware
10
+ from mpflash.errors import MPFlashError
11
+ from mpflash.list import show_mcus
12
+ from mpflash.mpboard_id import find_known_board
13
+ from mpflash.mpremoteboard import MPRemoteBoard
14
+
15
+ # #########################################################################################################
16
+ WorkList = List[Tuple[MPRemoteBoard, FWInfo]]
17
+ # #########################################################################################################
18
+
19
+
20
+ def auto_update(
21
+ conn_boards: List[MPRemoteBoard],
22
+ target_version: str,
23
+ fw_folder: Path,
24
+ *,
25
+ selector: Optional[Dict[str, str]] = None,
26
+ ) -> WorkList:
27
+ """Builds a list of boards to update based on the connected boards and the firmwares available locally in the firmware folder.
28
+
29
+ Args:
30
+ conn_boards (List[MPRemoteBoard]): List of connected boards
31
+ target_version (str): Target firmware version
32
+ fw_folder (Path): Path to the firmware folder
33
+ selector (Optional[Dict[str, str]], optional): Selector for filtering firmware. Defaults to None.
34
+
35
+ Returns:
36
+ WorkList: List of boards and firmware information to update
37
+ """
38
+ if selector is None:
39
+ selector = {}
40
+ wl: WorkList = []
41
+ for mcu in conn_boards:
42
+ if mcu.family not in ("micropython", "unknown"):
43
+ log.warning(f"Skipping flashing {mcu.family} {mcu.port} {mcu.board} on {mcu.serialport} as it is not a MicroPython firmware")
44
+ continue
45
+ board_firmwares = find_downloaded_firmware(
46
+ fw_folder=fw_folder,
47
+ board_id=mcu.board,
48
+ version=target_version,
49
+ port=mcu.port,
50
+ selector=selector,
51
+ )
52
+
53
+ if not board_firmwares:
54
+ log.error(f"No {target_version} firmware found for {mcu.board} on {mcu.serialport}.")
55
+ continue
56
+
57
+ if len(board_firmwares) > 1:
58
+ log.warning(f"Multiple {target_version} firmwares found for {mcu.board} on {mcu.serialport}.")
59
+
60
+ # just use the last firmware
61
+ fw_info = board_firmwares[-1]
62
+ log.info(f"Found {target_version} firmware {fw_info.filename} for {mcu.board} on {mcu.serialport}.")
63
+ wl.append((mcu, fw_info))
64
+ return wl
65
+
66
+
67
+ def manual_worklist(
68
+ serial: str,
69
+ *,
70
+ board_id: str,
71
+ version: str,
72
+ fw_folder: Path,
73
+ ) -> WorkList:
74
+ """Create a worklist for a single board specified manually.
75
+
76
+ Args:
77
+ serial (str): Serial port of the board
78
+ board (str): Board_ID
79
+ version (str): Firmware version
80
+ fw_folder (Path): Path to the firmware folder
81
+
82
+ Returns:
83
+ WorkList: List of boards and firmware information to update
84
+ """
85
+ log.trace(f"Manual updating {serial} to {board_id} {version}")
86
+ mcu = MPRemoteBoard(serial)
87
+ # Lookup the matching port and cpu in board_info based in the board name
88
+ try:
89
+ info = find_known_board(board_id)
90
+ mcu.port = info.port
91
+ # need the CPU type for the esptool
92
+ mcu.cpu = info.cpu
93
+ except (LookupError, MPFlashError) as e:
94
+ log.error(f"Board {board_id} not found in board_info.zip")
95
+ log.exception(e)
96
+ return []
97
+ mcu.board = board_id
98
+ firmwares = find_downloaded_firmware(fw_folder=fw_folder, board_id=board_id, version=version, port=mcu.port)
99
+ if not firmwares:
100
+ log.error(f"No firmware found for {mcu.port} {board_id} version {version}")
101
+ return []
102
+ # use the most recent matching firmware
103
+ return [(mcu, firmwares[-1])] # type: ignore
104
+
105
+
106
+ def single_auto_worklist(
107
+ serial: str,
108
+ *,
109
+ version: str,
110
+ fw_folder: Path,
111
+ ) -> WorkList:
112
+ """Create a worklist for a single serial-port.
113
+
114
+ Args:
115
+ serial_port (str): Serial port of the board
116
+ version (str): Firmware version
117
+ fw_folder (Path): Path to the firmware folder
118
+
119
+ Returns:
120
+ WorkList: List of boards and firmware information to update
121
+ """
122
+ log.trace(f"Auto updating {serial} to {version}")
123
+ conn_boards = [MPRemoteBoard(serial)]
124
+ todo = auto_update(conn_boards, version, fw_folder) # type: ignore # List / list
125
+ show_mcus(conn_boards) # type: ignore
126
+ return todo
127
+
128
+
129
+ def full_auto_worklist(
130
+ all_boards: List[MPRemoteBoard], *, include: List[str], ignore: List[str], version: str, fw_folder: Path
131
+ ) -> WorkList:
132
+ """
133
+ Create a worklist for all connected micropython boards based on the information retrieved from the board.
134
+ This allows the firmware version of one or moae boards to be changed without needing to specify the port or board_id manually.
135
+
136
+ Args:
137
+ version (str): Firmware version
138
+ fw_folder (Path): Path to the firmware folder
139
+
140
+ Returns:
141
+ WorkList: List of boards and firmware information to update
142
+ """
143
+ log.trace(f"Auto updating all boards to {version}")
144
+ if selected_boards := filter_boards(all_boards, include=include, ignore=ignore):
145
+ return auto_update(selected_boards, version, fw_folder)
146
+ else:
147
+ return []
148
+
149
+
150
+ def filter_boards(
151
+ all_boards: List[MPRemoteBoard],
152
+ *,
153
+ include: List[str],
154
+ ignore: List[str],
155
+ ):
156
+ try:
157
+ comports = [
158
+ p.device
159
+ for p in filtered_comports(
160
+ ignore=ignore,
161
+ include=include,
162
+ bluetooth=False,
163
+ )
164
+ ]
165
+ selected_boards = [b for b in all_boards if b.serialport in comports]
166
+ # [MPRemoteBoard(port.device, update=True) for port in comports]
167
+ except ConnectionError as e:
168
+ log.error(f"Error connecting to boards: {e}")
169
+ return []
170
+ return selected_boards # type: ignore
mpflash/mpflash/list.py CHANGED
@@ -1,99 +1,106 @@
1
- from typing import List
2
-
3
- from rich.progress import track
4
- from rich.table import Table
5
-
6
- from mpflash.config import config
7
- from mpflash.mpremoteboard import MPRemoteBoard
8
- from mpflash.versions import clean_version
9
-
10
- from .logger import console
11
-
12
-
13
- def show_mcus(
14
- conn_mcus: List[MPRemoteBoard],
15
- title: str = "Connected boards",
16
- refresh: bool = True,
17
- ):
18
- console.print(mcu_table(conn_mcus, title, refresh))
19
-
20
-
21
- def abbrv_family(family: str, is_wide: bool) -> str:
22
- if not is_wide:
23
- ABRV = {"micropython": "upy", "circuitpython": "cpy", "unknown": "?"}
24
- return ABRV.get(family, family[:4])
25
- return family
26
-
27
-
28
- def mcu_table(
29
- conn_mcus: List[MPRemoteBoard],
30
- title: str = "Connected boards",
31
- refresh: bool = True,
32
- ):
33
- """
34
- builds a rich table with the connected boards information
35
- The columns of the table are adjusted to the terminal width
36
- the columns are :
37
- Narrow Wide
38
- - Serial Yes Yes
39
- - Family abbrv. Yes
40
- - Port - yes
41
- - Board Yes Yes BOARD_ID and Description
42
- - CPU - Yes
43
- - Version Yes Yes
44
- - Build * * only if any of the mcus have a build
45
- """
46
- table = Table(
47
- title=title,
48
- title_style="magenta",
49
- header_style="bold magenta",
50
- collapse_padding=True,
51
- padding=(0, 0),
52
- )
53
- # check if the terminal is wide enough to show all columns or if we need to collapse some
54
- is_wide = console.width > 99
55
- needs_build = any(mcu.build for mcu in conn_mcus)
56
-
57
- table.add_column("Serial" if is_wide else "Ser.", overflow="fold")
58
- table.add_column("Family" if is_wide else "Fam.", overflow="crop", max_width=None if is_wide else 4)
59
- if is_wide:
60
- table.add_column("Port")
61
- table.add_column("Board", overflow="fold")
62
- # table.add_column("Variant") # TODO: add variant
63
- if is_wide:
64
- table.add_column("CPU")
65
- table.add_column("Version", overflow="fold", min_width=5, max_width=16)
66
- if needs_build:
67
- table.add_column("Build" if is_wide else "Bld", justify="right")
68
- if config.usb:
69
- table.add_column("Location", overflow="fold", max_width=40)
70
- for mcu in track(
71
- conn_mcus,
72
- description="Updating board info",
73
- transient=True,
74
- show_speed=False,
75
- refresh_per_second=1,
76
- ):
77
- if refresh:
78
- try:
79
- mcu.get_mcu_info()
80
- except ConnectionError:
81
- continue
82
- description = f"[italic bright_cyan]{mcu.description}" if mcu.description else ""
83
- row = [
84
- mcu.serialport.replace("/dev/", ""),
85
- abbrv_family(mcu.family, is_wide),
86
- ]
87
- if is_wide:
88
- row.append(mcu.port)
89
- row.append(f"{mcu.board}\n{description}".strip())
90
- if is_wide:
91
- row.append(mcu.cpu)
92
- row.append(clean_version(mcu.version))
93
- if needs_build:
94
- row.append(mcu.build)
95
- if config.usb:
96
- row.append(mcu.location)
97
-
98
- table.add_row(*row)
99
- return table
1
+ from typing import List
2
+
3
+ from rich.progress import track
4
+ from rich.table import Table
5
+
6
+ from mpflash.config import config
7
+ from mpflash.mpremoteboard import MPRemoteBoard
8
+ from mpflash.versions import clean_version
9
+
10
+ from .logger import console
11
+
12
+
13
+ def show_mcus(
14
+ conn_mcus: List[MPRemoteBoard],
15
+ title: str = "Connected boards",
16
+ refresh: bool = True,
17
+ ):
18
+ console.print(mcu_table(conn_mcus, title, refresh))
19
+
20
+
21
+ def abbrv_family(family: str, is_wide: bool) -> str:
22
+ if not is_wide:
23
+ ABRV = {"micropython": "upy", "circuitpython": "cpy", "unknown": "?"}
24
+ return ABRV.get(family, family[:4])
25
+ return family
26
+
27
+
28
+ def mcu_table(
29
+ conn_mcus: List[MPRemoteBoard],
30
+ title: str = "Connected boards",
31
+ refresh: bool = True,
32
+ ):
33
+ """
34
+ builds a rich table with the connected boards information
35
+ The columns of the table are adjusted to the terminal width
36
+ the columns are :
37
+ Narrow Wide
38
+ - Serial Yes Yes
39
+ - Family abbrv. Yes
40
+ - Port - yes
41
+ - Board Yes Yes BOARD_ID and Description, and the description from board_info.toml
42
+ - CPU - Yes
43
+ - Version Yes Yes
44
+ - Build * * only if any of the mcus have a build
45
+ - Location - - only if --usb is given
46
+ """
47
+ # refresh if requested
48
+ if refresh:
49
+ for mcu in track(
50
+ conn_mcus,
51
+ description="Updating board info",
52
+ transient=True,
53
+ show_speed=False,
54
+ refresh_per_second=1,
55
+ ):
56
+ try:
57
+ mcu.get_mcu_info()
58
+ except ConnectionError:
59
+ continue
60
+ table = Table(
61
+ title=title,
62
+ title_style="magenta",
63
+ header_style="bold magenta",
64
+ collapse_padding=True,
65
+ padding=(0, 0),
66
+ )
67
+ # Build the table
68
+ # check if the terminal is wide enough to show all columns or if we need to collapse some
69
+ is_wide = console.width > 99
70
+ needs_build = any(mcu.build for mcu in conn_mcus)
71
+
72
+ table.add_column("Serial" if is_wide else "Ser.", overflow="fold")
73
+ table.add_column("Family" if is_wide else "Fam.", overflow="crop", max_width=None if is_wide else 4)
74
+ if is_wide:
75
+ table.add_column("Port")
76
+ table.add_column("Board", overflow="fold")
77
+ # table.add_column("Variant") # TODO: add variant
78
+ if is_wide:
79
+ table.add_column("CPU")
80
+ table.add_column("Version", overflow="fold", min_width=5, max_width=16)
81
+ if needs_build:
82
+ table.add_column("Build" if is_wide else "Bld", justify="right")
83
+ if config.usb:
84
+ table.add_column("Location", overflow="fold", max_width=60)
85
+ # fill the table with the data
86
+ for mcu in conn_mcus:
87
+ description = f"[italic bright_cyan]{mcu.description}" if mcu.description else ""
88
+ if "description" in mcu.toml:
89
+ description += f"\n[italic bright_green]{mcu.toml['description']}"
90
+ row = [
91
+ mcu.serialport if is_wide else mcu.serialport.replace("/dev/tty", "tty"),
92
+ abbrv_family(mcu.family, is_wide),
93
+ ]
94
+ if is_wide:
95
+ row.append(mcu.port)
96
+ row.append(f"{mcu.board}\n{description}".strip())
97
+ if is_wide:
98
+ row.append(mcu.cpu)
99
+ row.append(clean_version(mcu.version))
100
+ if needs_build:
101
+ row.append(mcu.build)
102
+ if config.usb:
103
+ row.append(mcu.location)
104
+
105
+ table.add_row(*row)
106
+ return table
mpflash/mpflash/logger.py CHANGED
@@ -1,41 +1,41 @@
1
- """Logging."""
2
-
3
- from loguru import logger as log
4
- from rich.console import Console
5
-
6
- from .config import config
7
-
8
- console = Console()
9
-
10
-
11
- def _log_formatter(record: dict) -> str:
12
- """Log message formatter to combine loguru and rich formatting."""
13
- color_map = {
14
- "TRACE": "dim blue",
15
- "DEBUG": "cyan",
16
- "INFO": "bold",
17
- "SUCCESS": "bold green",
18
- "WARNING": "yellow",
19
- "ERROR": "bold red",
20
- "CRITICAL": "bold white on red",
21
- }
22
- lvl_color = color_map.get(record["level"].name, "cyan")
23
- return (
24
- "[not bold green]{time:HH:mm:ss}[/not bold green] | {level.icon} " + f"[{lvl_color}]{{message}}[/{lvl_color}]"
25
- )
26
-
27
-
28
- def set_loglevel(loglevel: str):
29
- """Set the log level for the logger"""
30
- try:
31
- log.remove()
32
- except ValueError:
33
- pass
34
- log.add(console.print, level=loglevel.upper(), colorize=False, format=_log_formatter) # type: ignore
35
-
36
-
37
- def make_quiet():
38
- """Make the logger quiet"""
39
- config.quiet = True
40
- console.quiet = True
41
- set_loglevel("CRITICAL")
1
+ """Logging."""
2
+
3
+ from loguru import logger as log
4
+ from rich.console import Console
5
+
6
+ from .config import config
7
+
8
+ console = Console()
9
+
10
+
11
+ def _log_formatter(record: dict) -> str:
12
+ """Log message formatter to combine loguru and rich formatting."""
13
+ color_map = {
14
+ "TRACE": "dim blue",
15
+ "DEBUG": "cyan",
16
+ "INFO": "bold",
17
+ "SUCCESS": "bold green",
18
+ "WARNING": "yellow",
19
+ "ERROR": "bold red",
20
+ "CRITICAL": "bold white on red",
21
+ }
22
+ lvl_color = color_map.get(record["level"].name, "cyan")
23
+ return (
24
+ "[not bold green]{time:HH:mm:ss}[/not bold green] | {level.icon} " + f"[{lvl_color}]{{message}}[/{lvl_color}]"
25
+ )
26
+
27
+
28
+ def set_loglevel(loglevel: str):
29
+ """Set the log level for the logger"""
30
+ try:
31
+ log.remove()
32
+ except ValueError:
33
+ pass
34
+ log.add(console.print, level=loglevel.upper(), colorize=False, format=_log_formatter) # type: ignore
35
+
36
+
37
+ def make_quiet():
38
+ """Make the logger quiet"""
39
+ config.quiet = True
40
+ console.quiet = True
41
+ set_loglevel("CRITICAL")