micropython-stubber 1.23.1.post1__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 (152) hide show
  1. {micropython_stubber-1.23.1.post1.dist-info → micropython_stubber-1.23.2.dist-info}/LICENSE +30 -30
  2. {micropython_stubber-1.23.1.post1.dist-info → micropython_stubber-1.23.2.dist-info}/METADATA +4 -4
  3. micropython_stubber-1.23.2.dist-info/RECORD +158 -0
  4. mpflash/README.md +220 -220
  5. mpflash/libusb_flash.ipynb +203 -203
  6. mpflash/mpflash/add_firmware.py +98 -98
  7. mpflash/mpflash/ask_input.py +236 -236
  8. mpflash/mpflash/basicgit.py +284 -284
  9. mpflash/mpflash/bootloader/__init__.py +2 -2
  10. mpflash/mpflash/bootloader/activate.py +60 -60
  11. mpflash/mpflash/bootloader/detect.py +82 -82
  12. mpflash/mpflash/bootloader/manual.py +101 -101
  13. mpflash/mpflash/bootloader/micropython.py +12 -12
  14. mpflash/mpflash/bootloader/touch1200.py +36 -36
  15. mpflash/mpflash/cli_download.py +129 -129
  16. mpflash/mpflash/cli_flash.py +224 -216
  17. mpflash/mpflash/cli_group.py +111 -111
  18. mpflash/mpflash/cli_list.py +87 -87
  19. mpflash/mpflash/cli_main.py +39 -39
  20. mpflash/mpflash/common.py +210 -166
  21. mpflash/mpflash/config.py +44 -44
  22. mpflash/mpflash/connected.py +96 -77
  23. mpflash/mpflash/download.py +364 -364
  24. mpflash/mpflash/downloaded.py +130 -130
  25. mpflash/mpflash/errors.py +9 -9
  26. mpflash/mpflash/flash/__init__.py +55 -55
  27. mpflash/mpflash/flash/esp.py +59 -59
  28. mpflash/mpflash/flash/stm32.py +19 -19
  29. mpflash/mpflash/flash/stm32_dfu.py +104 -104
  30. mpflash/mpflash/flash/uf2/__init__.py +88 -88
  31. mpflash/mpflash/flash/uf2/boardid.py +15 -15
  32. mpflash/mpflash/flash/uf2/linux.py +136 -130
  33. mpflash/mpflash/flash/uf2/macos.py +42 -42
  34. mpflash/mpflash/flash/uf2/uf2disk.py +12 -12
  35. mpflash/mpflash/flash/uf2/windows.py +43 -43
  36. mpflash/mpflash/flash/worklist.py +170 -170
  37. mpflash/mpflash/list.py +106 -106
  38. mpflash/mpflash/logger.py +41 -41
  39. mpflash/mpflash/mpboard_id/__init__.py +93 -93
  40. mpflash/mpflash/mpboard_id/add_boards.py +251 -251
  41. mpflash/mpflash/mpboard_id/board.py +37 -37
  42. mpflash/mpflash/mpboard_id/board_id.py +86 -86
  43. mpflash/mpflash/mpboard_id/store.py +43 -43
  44. mpflash/mpflash/mpremoteboard/__init__.py +266 -266
  45. mpflash/mpflash/mpremoteboard/mpy_fw_info.py +141 -141
  46. mpflash/mpflash/mpremoteboard/runner.py +140 -140
  47. mpflash/mpflash/vendor/click_aliases.py +91 -91
  48. mpflash/mpflash/vendor/dfu.py +165 -165
  49. mpflash/mpflash/vendor/pydfu.py +605 -605
  50. mpflash/mpflash/vendor/readme.md +2 -2
  51. mpflash/mpflash/versions.py +135 -135
  52. mpflash/poetry.lock +1599 -1599
  53. mpflash/pyproject.toml +65 -65
  54. mpflash/stm32_udev_rules.md +62 -62
  55. stubber/__init__.py +3 -3
  56. stubber/board/board_info.csv +193 -193
  57. stubber/board/boot.py +34 -34
  58. stubber/board/createstubs.py +1004 -986
  59. stubber/board/createstubs_db.py +826 -825
  60. stubber/board/createstubs_db_min.py +332 -331
  61. stubber/board/createstubs_db_mpy.mpy +0 -0
  62. stubber/board/createstubs_lvgl.py +741 -741
  63. stubber/board/createstubs_lvgl_min.py +741 -741
  64. stubber/board/createstubs_mem.py +767 -766
  65. stubber/board/createstubs_mem_min.py +307 -306
  66. stubber/board/createstubs_mem_mpy.mpy +0 -0
  67. stubber/board/createstubs_min.py +295 -294
  68. stubber/board/createstubs_mpy.mpy +0 -0
  69. stubber/board/fw_info.py +141 -141
  70. stubber/board/info.py +183 -183
  71. stubber/board/main.py +19 -19
  72. stubber/board/modulelist.txt +247 -247
  73. stubber/board/pyrightconfig.json +34 -34
  74. stubber/bulk/mcu_stubber.py +437 -437
  75. stubber/codemod/_partials/__init__.py +48 -48
  76. stubber/codemod/_partials/db_main.py +147 -147
  77. stubber/codemod/_partials/lvgl_main.py +77 -77
  78. stubber/codemod/_partials/modules_reader.py +80 -80
  79. stubber/codemod/add_comment.py +53 -53
  80. stubber/codemod/add_method.py +65 -65
  81. stubber/codemod/board.py +317 -317
  82. stubber/codemod/enrich.py +151 -145
  83. stubber/codemod/merge_docstub.py +284 -284
  84. stubber/codemod/modify_list.py +54 -54
  85. stubber/codemod/utils.py +56 -56
  86. stubber/commands/build_cmd.py +94 -94
  87. stubber/commands/cli.py +49 -49
  88. stubber/commands/clone_cmd.py +78 -78
  89. stubber/commands/config_cmd.py +29 -29
  90. stubber/commands/enrich_folder_cmd.py +71 -71
  91. stubber/commands/get_core_cmd.py +71 -71
  92. stubber/commands/get_docstubs_cmd.py +92 -92
  93. stubber/commands/get_frozen_cmd.py +117 -117
  94. stubber/commands/get_mcu_cmd.py +102 -102
  95. stubber/commands/merge_cmd.py +66 -66
  96. stubber/commands/publish_cmd.py +118 -118
  97. stubber/commands/stub_cmd.py +31 -31
  98. stubber/commands/switch_cmd.py +62 -62
  99. stubber/commands/variants_cmd.py +48 -48
  100. stubber/cst_transformer.py +178 -178
  101. stubber/data/board_info.csv +193 -193
  102. stubber/data/board_info.json +1729 -1729
  103. stubber/data/micropython_tags.csv +15 -15
  104. stubber/data/requirements-core-micropython.txt +38 -38
  105. stubber/data/requirements-core-pycopy.txt +39 -39
  106. stubber/downloader.py +37 -37
  107. stubber/freeze/common.py +72 -72
  108. stubber/freeze/freeze_folder.py +69 -69
  109. stubber/freeze/freeze_manifest_2.py +126 -126
  110. stubber/freeze/get_frozen.py +131 -131
  111. stubber/get_cpython.py +112 -112
  112. stubber/get_lobo.py +59 -59
  113. stubber/minify.py +423 -423
  114. stubber/publish/bump.py +86 -86
  115. stubber/publish/candidates.py +275 -275
  116. stubber/publish/database.py +18 -18
  117. stubber/publish/defaults.py +40 -40
  118. stubber/publish/enums.py +24 -24
  119. stubber/publish/helpers.py +29 -29
  120. stubber/publish/merge_docstubs.py +136 -132
  121. stubber/publish/missing_class_methods.py +51 -51
  122. stubber/publish/package.py +150 -150
  123. stubber/publish/pathnames.py +51 -51
  124. stubber/publish/publish.py +120 -120
  125. stubber/publish/pypi.py +42 -42
  126. stubber/publish/stubpackage.py +1055 -1051
  127. stubber/rst/__init__.py +9 -9
  128. stubber/rst/classsort.py +78 -78
  129. stubber/rst/lookup.py +533 -531
  130. stubber/rst/output_dict.py +401 -401
  131. stubber/rst/reader.py +814 -814
  132. stubber/rst/report_return.py +77 -77
  133. stubber/rst/rst_utils.py +541 -541
  134. stubber/stubber.py +38 -38
  135. stubber/stubs_from_docs.py +90 -90
  136. stubber/tools/manifestfile.py +654 -654
  137. stubber/tools/readme.md +6 -6
  138. stubber/update_fallback.py +117 -117
  139. stubber/update_module_list.py +123 -123
  140. stubber/utils/__init__.py +6 -6
  141. stubber/utils/config.py +137 -137
  142. stubber/utils/makeversionhdr.py +54 -54
  143. stubber/utils/manifest.py +90 -90
  144. stubber/utils/post.py +80 -80
  145. stubber/utils/repos.py +156 -156
  146. stubber/utils/stubmaker.py +139 -139
  147. stubber/utils/typed_config_toml.py +80 -80
  148. stubber/variants.py +106 -106
  149. micropython_stubber-1.23.1.post1.dist-info/RECORD +0 -159
  150. mpflash/basicgit.py +0 -288
  151. {micropython_stubber-1.23.1.post1.dist-info → micropython_stubber-1.23.2.dist-info}/WHEEL +0 -0
  152. {micropython_stubber-1.23.1.post1.dist-info → micropython_stubber-1.23.2.dist-info}/entry_points.txt +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,106 +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, 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=40)
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.replace("/dev/", ""),
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
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")