micropython-stubber 1.20.1__py3-none-any.whl → 1.20.4__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 (60) hide show
  1. {micropython_stubber-1.20.1.dist-info → micropython_stubber-1.20.4.dist-info}/METADATA +4 -3
  2. {micropython_stubber-1.20.1.dist-info → micropython_stubber-1.20.4.dist-info}/RECORD +58 -51
  3. {micropython_stubber-1.20.1.dist-info → micropython_stubber-1.20.4.dist-info}/WHEEL +1 -1
  4. mpflash/README.md +16 -5
  5. mpflash/mpflash/add_firmware.py +98 -0
  6. mpflash/mpflash/ask_input.py +97 -120
  7. mpflash/mpflash/cli_download.py +42 -25
  8. mpflash/mpflash/cli_flash.py +70 -32
  9. mpflash/mpflash/cli_group.py +17 -14
  10. mpflash/mpflash/cli_list.py +39 -3
  11. mpflash/mpflash/cli_main.py +17 -6
  12. mpflash/mpflash/common.py +125 -12
  13. mpflash/mpflash/config.py +12 -0
  14. mpflash/mpflash/connected.py +74 -0
  15. mpflash/mpflash/download.py +132 -51
  16. mpflash/mpflash/downloaded.py +36 -15
  17. mpflash/mpflash/flash.py +2 -2
  18. mpflash/mpflash/flash_esp.py +2 -2
  19. mpflash/mpflash/flash_uf2.py +14 -8
  20. mpflash/mpflash/flash_uf2_boardid.py +2 -1
  21. mpflash/mpflash/flash_uf2_linux.py +5 -16
  22. mpflash/mpflash/flash_uf2_macos.py +37 -0
  23. mpflash/mpflash/flash_uf2_windows.py +5 -5
  24. mpflash/mpflash/list.py +57 -57
  25. mpflash/mpflash/mpboard_id/__init__.py +41 -44
  26. mpflash/mpflash/mpboard_id/add_boards.py +255 -0
  27. mpflash/mpflash/mpboard_id/board.py +37 -0
  28. mpflash/mpflash/mpboard_id/board_id.py +54 -34
  29. mpflash/mpflash/mpboard_id/board_info.zip +0 -0
  30. mpflash/mpflash/mpboard_id/store.py +43 -0
  31. mpflash/mpflash/mpremoteboard/__init__.py +18 -6
  32. mpflash/mpflash/uf2disk.py +12 -0
  33. mpflash/mpflash/vendor/basicgit.py +288 -0
  34. mpflash/mpflash/vendor/dfu.py +1 -0
  35. mpflash/mpflash/vendor/versions.py +7 -3
  36. mpflash/mpflash/worklist.py +71 -48
  37. mpflash/poetry.lock +164 -138
  38. mpflash/pyproject.toml +18 -15
  39. stubber/__init__.py +1 -1
  40. stubber/board/createstubs.py +13 -3
  41. stubber/board/createstubs_db.py +5 -7
  42. stubber/board/createstubs_db_min.py +329 -825
  43. stubber/board/createstubs_db_mpy.mpy +0 -0
  44. stubber/board/createstubs_mem.py +6 -7
  45. stubber/board/createstubs_mem_min.py +304 -765
  46. stubber/board/createstubs_mem_mpy.mpy +0 -0
  47. stubber/board/createstubs_min.py +293 -975
  48. stubber/board/createstubs_mpy.mpy +0 -0
  49. stubber/board/modulelist.txt +10 -0
  50. stubber/commands/get_core_cmd.py +7 -6
  51. stubber/commands/get_docstubs_cmd.py +8 -3
  52. stubber/commands/get_frozen_cmd.py +5 -2
  53. stubber/publish/publish.py +18 -7
  54. stubber/update_module_list.py +2 -24
  55. stubber/utils/makeversionhdr.py +3 -2
  56. stubber/utils/versions.py +2 -1
  57. mpflash/mpflash/mpboard_id/board_info.csv +0 -2213
  58. mpflash/mpflash/mpboard_id/board_info.json +0 -19910
  59. {micropython_stubber-1.20.1.dist-info → micropython_stubber-1.20.4.dist-info}/LICENSE +0 -0
  60. {micropython_stubber-1.20.1.dist-info → micropython_stubber-1.20.4.dist-info}/entry_points.txt +0 -0
mpflash/mpflash/list.py CHANGED
@@ -1,89 +1,89 @@
1
1
  from typing import List
2
2
 
3
- from rich import print
4
- from rich.progress import BarColumn, Progress, SpinnerColumn, TextColumn, TimeElapsedColumn, track
5
- from rich.table import Column, Table
3
+ from rich.progress import track
4
+ from rich.table import Table
6
5
 
7
6
  from mpflash.mpremoteboard import MPRemoteBoard
8
7
  from mpflash.vendor.versions import clean_version
9
8
 
10
- from .config import config
11
9
  from .logger import console
12
10
 
13
- rp_spinner = SpinnerColumn(finished_text="✅")
14
- rp_text = TextColumn("{task.description} {task.fields[device]}", table_column=Column())
15
- rp_bar = BarColumn(bar_width=None, table_column=Column())
16
11
 
12
+ def show_mcus(
13
+ conn_mcus: List[MPRemoteBoard],
14
+ title: str = "Connected boards",
15
+ refresh: bool = True,
16
+ ):
17
+ console.print(mcu_table(conn_mcus, title, refresh))
17
18
 
18
- def list_mcus(bluetooth: bool = False):
19
- """
20
- Retrieves information about connected microcontroller boards.
21
-
22
- Returns:
23
- List[MPRemoteBoard]: A list of MPRemoteBoard instances with board information.
24
- Raises:
25
- ConnectionError: If there is an error connecting to a board.
26
- """
27
- conn_mcus = [MPRemoteBoard(sp) for sp in MPRemoteBoard.connected_boards(bluetooth) if sp not in config.ignore_ports]
28
19
 
29
- # a lot of boilerplate to show a progress bar with the comport currenlty scanned
30
- with Progress(rp_spinner, rp_text, rp_bar, TimeElapsedColumn()) as progress:
31
- tsk_scan = progress.add_task("[green]Scanning", visible=False, total=None)
32
- progress.tasks[tsk_scan].fields["device"] = "..."
33
- progress.tasks[tsk_scan].visible = True
34
- progress.start_task(tsk_scan)
35
- try:
36
- for mcu in conn_mcus:
37
- progress.update(tsk_scan, device=mcu.serialport.replace("/dev/", ""))
38
- try:
39
- mcu.get_mcu_info()
40
- except ConnectionError as e:
41
- print(f"Error: {e}")
42
- continue
43
- finally:
44
- # transient
45
- progress.stop_task(tsk_scan)
46
- progress.tasks[tsk_scan].visible = False
47
- return conn_mcus
20
+ def abbrv_family(family: str, is_wide: bool) -> str:
21
+ if not is_wide:
22
+ ABRV = {"micropython": "upy", "circuitpython": "cpy", "unknown": "?"}
23
+ return ABRV.get(family, family[:4])
24
+ return family
48
25
 
49
26
 
50
- def show_mcus(
27
+ def mcu_table(
51
28
  conn_mcus: List[MPRemoteBoard],
52
29
  title: str = "Connected boards",
53
30
  refresh: bool = True,
54
- ): # sourcery skip: extract-duplicate-method
55
- """Show the list of connected boards in a nice table"""
31
+ ):
32
+ """
33
+ builds a rich table with the connected boards information
34
+ The columns of the table are adjusted to the terminal width
35
+ the columns are :
36
+ Narrow Wide
37
+ - Serial Yes Yes
38
+ - Family abbrv. Yes
39
+ - Port - yes
40
+ - Board Yes Yes BOARD_ID and Description
41
+ - CPU - Yes
42
+ - Version Yes Yes
43
+ - Build * * only if any of the mcus have a build
44
+ """
56
45
  table = Table(
57
46
  title=title,
58
47
  title_style="magenta",
59
48
  header_style="bold magenta",
60
49
  collapse_padding=True,
61
- width=110,
50
+ padding=(0, 0),
62
51
  )
63
- table.add_column("Serial", overflow="fold")
64
- table.add_column("Family")
65
- table.add_column("Port")
52
+ # check if the terminal is wide enough to show all columns or if we need to collapse some
53
+ is_wide = console.width > 99
54
+ needs_build = any(mcu.build for mcu in conn_mcus)
55
+
56
+ table.add_column("Serial" if is_wide else "Ser.", overflow="fold")
57
+ table.add_column("Family" if is_wide else "Fam.", overflow="crop", max_width=None if is_wide else 4)
58
+ if is_wide:
59
+ table.add_column("Port")
66
60
  table.add_column("Board", overflow="fold")
67
61
  # table.add_column("Variant") # TODO: add variant
68
- table.add_column("CPU")
69
- table.add_column("Version")
70
- table.add_column("build", justify="right")
62
+ if is_wide:
63
+ table.add_column("CPU")
64
+ table.add_column("Version", overflow="fold", min_width=5, max_width=16)
65
+ if needs_build:
66
+ table.add_column("Build" if is_wide else "Bld", justify="right")
71
67
 
72
- for mcu in track(conn_mcus, description="Updating board info", transient=True, update_period=0.1):
68
+ for mcu in track(conn_mcus, description="Updating board info", transient=True, refresh_per_second=2):
73
69
  if refresh:
74
70
  try:
75
71
  mcu.get_mcu_info()
76
72
  except ConnectionError:
77
73
  continue
78
74
  description = f"[italic bright_cyan]{mcu.description}" if mcu.description else ""
79
- table.add_row(
75
+ row = [
80
76
  mcu.serialport.replace("/dev/", ""),
81
- mcu.family,
82
- mcu.port,
83
- f"{mcu.board}\n{description}".strip(),
84
- # mcu.variant,
85
- mcu.cpu,
86
- clean_version(mcu.version),
87
- mcu.build,
88
- )
89
- console.print(table)
77
+ abbrv_family(mcu.family, is_wide),
78
+ ]
79
+ if is_wide:
80
+ row.append(mcu.port)
81
+ row.append(f"{mcu.board}\n{description}".strip())
82
+ if is_wide:
83
+ row.append(mcu.cpu)
84
+ row.append(clean_version(mcu.version))
85
+ if needs_build:
86
+ row.append(mcu.build)
87
+
88
+ table.add_row(*row)
89
+ return table
@@ -4,53 +4,38 @@ that is included in the module.
4
4
 
5
5
  """
6
6
 
7
- import json
8
7
  from functools import lru_cache
9
- from pathlib import Path
10
- from typing import List, Optional, Tuple, TypedDict, Union
8
+ from typing import List, Optional, Tuple
11
9
 
12
10
  from mpflash.errors import MPFlashError
13
- from mpflash.common import PORT_FWTYPES
11
+ from mpflash.mpboard_id.board import Board
12
+ from mpflash.mpboard_id.store import read_known_boardinfo
14
13
  from mpflash.vendor.versions import clean_version
15
14
 
15
+ # KNOWN ports and boards are sourced from the micropython repo,
16
+ # this info is stored in the board_info.json file
16
17
 
17
- # Board based on the dataclass Board but changed to TypedDict
18
- # - source : get_boardnames.py
19
- class Board(TypedDict):
20
- """MicroPython Board definition"""
21
18
 
22
- description: str
23
- port: str
24
- board: str
25
- board_name: str
26
- mcu_name: str
27
- path: Union[Path, str]
28
- version: str
29
- cpu: str
30
-
31
-
32
- @lru_cache(maxsize=None)
33
- def read_stored_boardinfo() -> List[Board]:
34
- """Reads the board_info.json file and returns the data as a list of Board objects"""
35
- with open(Path(__file__).parent / "board_info.json", "r") as file:
36
- return json.load(file)
37
-
38
-
39
- def local_mp_ports() -> List[str]:
19
+ def get_known_ports() -> List[str]:
40
20
  # TODO: Filter for Version
41
- mp_boards = read_stored_boardinfo()
21
+ mp_boards = read_known_boardinfo()
42
22
  # select the unique ports from info
43
- ports = set({board["port"] for board in mp_boards if board["port"] in PORT_FWTYPES.keys()})
23
+ ports = set({board.port for board in mp_boards if board.port})
44
24
  return sorted(list(ports))
45
25
 
46
26
 
47
- def get_stored_boards_for_port(port: str, versions: Optional[List[str]] = None):
27
+ def get_known_boards_for_port(port: Optional[str] = "", versions: Optional[List[str]] = None) -> List[Board]:
48
28
  """
49
29
  Returns a list of boards for the given port and version(s)
50
30
 
51
- port : str : The Micropython port to filter for
52
- versions : List[str] : The Micropython versions to filter for (actual versions required)"""
53
- mp_boards = read_stored_boardinfo()
31
+ port: The Micropython port to filter for
32
+ versions: Optional, The Micropython versions to filter for (actual versions required)
33
+ """
34
+ mp_boards = read_known_boardinfo()
35
+ if versions:
36
+ preview_or_stable = "preview" in versions or "stable" in versions
37
+ else:
38
+ preview_or_stable = False
54
39
 
55
40
  # filter for 'preview' as they are not in the board_info.json
56
41
  # instead use stable version
@@ -62,9 +47,17 @@ def get_stored_boards_for_port(port: str, versions: Optional[List[str]] = None):
62
47
  # make sure of the v prefix
63
48
  versions = [clean_version(v) for v in versions]
64
49
  # filter for the version(s)
65
- mp_boards = [board for board in mp_boards if board["version"] in versions]
50
+ mp_boards = [board for board in mp_boards if board.version in versions]
51
+ if not mp_boards and preview_or_stable:
52
+ # nothing found - perhaps there is a newer version for which we do not have the board info yet
53
+ # use the latest known version from the board info
54
+ mp_boards = read_known_boardinfo()
55
+ last_known_version = sorted({b.version for b in mp_boards})[-1]
56
+ mp_boards = [board for board in mp_boards if board.version == last_known_version]
57
+
66
58
  # filter for the port
67
- mp_boards = [board for board in mp_boards if board["port"] == port]
59
+ if port:
60
+ mp_boards = [board for board in mp_boards if board.port == port]
68
61
  return mp_boards
69
62
 
70
63
 
@@ -75,22 +68,26 @@ def known_stored_boards(port: str, versions: Optional[List[str]] = None) -> List
75
68
  port : str : The Micropython port to filter for
76
69
  versions : List[str] : The Micropython versions to filter for (actual versions required)
77
70
  """
78
- mp_boards = get_stored_boards_for_port(port, versions)
71
+ mp_boards = get_known_boards_for_port(port, versions)
79
72
 
80
- boards = set({(f'{board["version"]} {board["description"]}', board["board"]) for board in mp_boards})
73
+ boards = set({(f"{board.version} {board.description}", board.board_id) for board in mp_boards})
81
74
  return sorted(list(boards))
82
75
 
83
76
 
84
77
  @lru_cache(maxsize=20)
85
- def find_stored_board(board_id: str) -> Board:
86
- """Find the board for the given board_ID or 'board description' and return the board info as a Board object"""
87
- info = read_stored_boardinfo()
78
+ def find_known_board(board_id: str) -> Board:
79
+ """Find the board for the given BOARD_ID or 'board description' and return the board info as a Board object"""
80
+ # FIXME : functional overlap with:
81
+ # mpboard_id\board_id.py _find_board_id_by_description
82
+ info = read_known_boardinfo()
88
83
  for board_info in info:
89
- if board_id in (board_info["board"], board_info["description"]):
90
- if "cpu" not in board_info or not board_info["cpu"]:
91
- if " with " in board_info["description"]:
92
- board_info["cpu"] = board_info["description"].split(" with ")[-1]
84
+ if board_id in (board_info.board_id, board_info.description):
85
+ if not board_info.cpu:
86
+ # safeguard for older board_info.json files
87
+ print(f"Board {board_id} has no CPU info, using port as CPU")
88
+ if " with " in board_info.description:
89
+ board_info.cpu = board_info.description.split(" with ")[-1]
93
90
  else:
94
- board_info["cpu"] = board_info["port"]
91
+ board_info.cpu = board_info.port
95
92
  return board_info
96
93
  raise MPFlashError(f"Board {board_id} not found")
@@ -0,0 +1,255 @@
1
+ """
2
+ Collects board name and description information from MicroPython and writes it to JSON and CSV files.
3
+ """
4
+
5
+ import re
6
+ from pathlib import Path
7
+ from typing import List, Optional
8
+
9
+ import inquirer
10
+ import rich
11
+ import rich.table
12
+ from rich.console import Console
13
+ from rich.progress import track
14
+
15
+ import mpflash.vendor.basicgit as git
16
+ from mpflash.logger import log
17
+ from mpflash.mpboard_id import Board
18
+ from mpflash.mpboard_id.store import write_boardinfo_json
19
+ from mpflash.vendor.versions import micropython_versions
20
+
21
+ # look for all mpconfigboard.h files and extract the board name
22
+ # from the #define MICROPY_HW_BOARD_NAME "PYBD_SF6"
23
+ # and the #define MICROPY_HW_MCU_NAME "STM32F767xx"
24
+ RE_H_MICROPY_HW_BOARD_NAME = re.compile(r"#define\s+MICROPY_HW_BOARD_NAME\s+\"(.+)\"")
25
+ RE_H_MICROPY_HW_MCU_NAME = re.compile(r"#define\s+MICROPY_HW_MCU_NAME\s+\"(.+)\"")
26
+ # find in the mpconfigboard.cmake files
27
+
28
+ RE_CMAKE_MICROPY_HW_BOARD_NAME = re.compile(r"MICROPY_HW_BOARD_NAME\s?=\s?\"(?P<variant>[\w\s\S]*)\"")
29
+ RE_CMAKE_MICROPY_HW_MCU_NAME = re.compile(r"MICROPY_HW_MCU_NAME\s?=\s?\"(?P<variant>[\w\s\S]*)\"")
30
+ # TODO: normal make files
31
+
32
+
33
+ def boards_from_repo(mpy_path: Path, version: str, family: Optional[str] = None) -> List[Board]:
34
+ """Collects board name and decriptions from mpconfigboard.h files.
35
+
36
+ Args:
37
+ mpy_path (Path): The path to the MicroPython repository.
38
+ version (str): The version of MicroPython.
39
+
40
+ Returns:
41
+ List[Board]: A list of Board objects containing the board information.
42
+ """
43
+ if not mpy_path.exists() or not mpy_path.is_dir():
44
+ raise FileNotFoundError(f"MicroPython path {mpy_path} does not exist.")
45
+ if not family:
46
+ family = "micropython"
47
+ if not version:
48
+ version = git.get_local_tag() # type: ignore
49
+ if not version:
50
+ raise ValueError("No version provided and no local tag found.")
51
+
52
+ board_list: List[Board] = []
53
+ # look in mpconfigboard.h files
54
+ board_list = boards_from_cmake(mpy_path, version, family)
55
+
56
+ # look for variants in the .cmake files
57
+ board_list.extend(boards_from_headers(mpy_path, version, family))
58
+ # TODO:? look for variants in the Makefile files
59
+
60
+ return board_list
61
+
62
+
63
+ def boards_from_cmake(mpy_path: Path, version: str, family: str):
64
+ """Get boards from the mpconfigboard.cmake files to the board_list."""
65
+ board_list = []
66
+ for path in mpy_path.glob("ports/**/mpconfigboard.cmake"):
67
+ board = path.parent.name
68
+ port = path.parent.parent.parent.name
69
+ with open(path, "r") as f:
70
+ board_name = mcu_name = "-"
71
+ for line in f:
72
+ line = line.strip()
73
+ if match := RE_CMAKE_MICROPY_HW_BOARD_NAME.match(line):
74
+ description = match["variant"]
75
+ board_list.append(
76
+ Board(
77
+ board_id=board,
78
+ port=port,
79
+ board_name=board_name,
80
+ mcu_name=mcu_name,
81
+ description=description,
82
+ path=path.relative_to(mpy_path),
83
+ version=version,
84
+ family=family,
85
+ )
86
+ )
87
+ elif match := RE_CMAKE_MICROPY_HW_MCU_NAME.match(line):
88
+ description = match["variant"]
89
+ board_list.append(
90
+ Board(
91
+ board_id=board,
92
+ port=port,
93
+ board_name=board_name,
94
+ mcu_name=mcu_name,
95
+ description=description,
96
+ path=path.relative_to(mpy_path),
97
+ version=version,
98
+ family=family,
99
+ )
100
+ )
101
+ return board_list
102
+
103
+
104
+ def boards_from_headers(mpy_path: Path, version: str, family: str):
105
+ """Get boards from the mpconfigboard.h files to the board_list."""
106
+ board_list = []
107
+ for path in mpy_path.glob("ports/**/mpconfigboard.h"):
108
+ board = path.parent.name
109
+ port = path.parent.parent.parent.name
110
+ with open(path, "r") as f:
111
+ board_name = mcu_name = "-"
112
+ found = 0
113
+ for line in f:
114
+ if match := RE_H_MICROPY_HW_BOARD_NAME.match(line):
115
+ board_name = match[1]
116
+ found += 1
117
+ elif match := RE_H_MICROPY_HW_MCU_NAME.match(line):
118
+ mcu_name = match[1]
119
+ found += 1
120
+ if found == 2:
121
+ description = f"{board_name} with {mcu_name}" if mcu_name != "-" else board_name
122
+ board_list.append(
123
+ Board(
124
+ board_id=board,
125
+ port=port,
126
+ board_name=board_name,
127
+ mcu_name=mcu_name,
128
+ description=description,
129
+ path=path.relative_to(mpy_path),
130
+ version=version,
131
+ family=family,
132
+ )
133
+ )
134
+ found = 0
135
+ if found == 1:
136
+ description = board_name
137
+ board_list.append(
138
+ Board(
139
+ board_id=board,
140
+ port=port,
141
+ board_name=board_name,
142
+ mcu_name=mcu_name,
143
+ description=description,
144
+ path=path.relative_to(mpy_path),
145
+ version=version,
146
+ family=family,
147
+ )
148
+ )
149
+ return board_list
150
+
151
+
152
+ def boards_for_versions(versions: List[str], mpy_path: Path):
153
+ """Gets the list of boards for multiple versions of MicroPython.
154
+
155
+ Args:
156
+ versions (List[str]): The list of MicroPython versions.
157
+ mpy_path (Path): The path to the MicroPython repository.
158
+
159
+ Returns:
160
+ List[Board]: The list of Board objects.
161
+ """
162
+ board_list: List[Board] = []
163
+ for version in track(versions, description="Searching MicroPython versions"):
164
+ if git.checkout_tag(tag=version, repo=mpy_path):
165
+ new_ones = boards_from_repo(mpy_path, version, family="micropython")
166
+ print(f"Found {len(new_ones)} board definitions for {version}.")
167
+ board_list += new_ones
168
+ else:
169
+ print(f"Could not checkout version {version}.")
170
+
171
+ # sort the board_list by description and board
172
+ print("Total number of boards found:", len(board_list))
173
+
174
+ board_list = unique_boards(board_list)
175
+ print("Unique board descriptions found:", len(board_list))
176
+ return board_list
177
+
178
+
179
+ def unique_boards(board_list: List[Board], *, key_version: bool = True):
180
+ """Remove duplicate boards by 'BOARD_ID description' from the list."""
181
+ seen = set()
182
+ result = []
183
+ for x in board_list:
184
+ if key_version:
185
+ key = f"{x.board_id}|{x.version}|{x.description}"
186
+ else:
187
+ key = f"{x.board_id}|{x.description}"
188
+ if key not in seen:
189
+ result.append(x)
190
+ seen.add(key)
191
+ result.sort(key=lambda x: x.description.lower())
192
+ return result
193
+
194
+
195
+ def make_table(board_list: List[Board]) -> rich.table.Table:
196
+ """Creates a rich table with board information."""
197
+ is_wide = True
198
+
199
+ table = rich.table.Table(title="MicroPython Board Information")
200
+ table.add_column("BOARD_ID", justify="left", style="green")
201
+ table.add_column("Description", justify="left", style="cyan")
202
+ table.add_column("Port", justify="left", style="magenta")
203
+ table.add_column("Board Name", justify="left", style="blue")
204
+ if is_wide:
205
+ table.add_column("MCU Name", justify="left", style="blue")
206
+ table.add_column("Detection", justify="left", style="yellow")
207
+ table.add_column("Version", justify="left", style="blue")
208
+ if is_wide:
209
+ table.add_column("Family", justify="left", style="blue")
210
+
211
+ for board in board_list:
212
+ row = [board.board_id, board.description, *(board.port, board.board_name)]
213
+ if is_wide:
214
+ row.append(board.mcu_name)
215
+ row.extend((str(Path(board.path).suffix), board.version))
216
+ if is_wide:
217
+ row.append(board.family)
218
+ table.add_row(*row)
219
+
220
+ return table
221
+
222
+
223
+ def ask_mpy_path():
224
+ """Ask the user for the path to the MicroPython repository."""
225
+ questions = [
226
+ inquirer.Text(
227
+ "mpy_path", message="Enter the path to the MicroPython repository", default=".\\repos\\micropython"
228
+ )
229
+ ]
230
+ if answers := inquirer.prompt(questions):
231
+ return Path(answers["mpy_path"])
232
+ else:
233
+ raise ValueError("No path provided.")
234
+
235
+
236
+ def main():
237
+ """Main function to collect and write board information."""
238
+
239
+ console = Console()
240
+
241
+ mpy_path = ask_mpy_path()
242
+ versions = micropython_versions(minver="v1.10") + ["master"]
243
+ board_list = boards_for_versions(versions, mpy_path)
244
+
245
+ here = Path(__file__).parent
246
+ log.info(write_boardinfo_json(board_list, folder=here))
247
+ # write_files(board_list, folder=CONFIG.board_path)
248
+
249
+ # table of when the board was added
250
+ table = make_table(unique_boards(board_list, key_version=False))
251
+ console.print(table)
252
+
253
+
254
+ if __name__ == "__main__":
255
+ main()
@@ -0,0 +1,37 @@
1
+ from dataclasses import dataclass, field
2
+ from pathlib import Path
3
+ from typing import Union
4
+
5
+
6
+ # - source : get_boardnames.py
7
+ @dataclass
8
+ class Board:
9
+ """
10
+ MicroPython Board definitions, parsed from the make and header files
11
+ """
12
+
13
+ port: str # micropython port
14
+ board_id: str # BOARD_ID (Foldername) as used in the make files
15
+ board_name: str # Short board description
16
+ description: str # Long board description
17
+ path: Union[Path, str]
18
+ version: str = field(default="") # version of MicroPython""
19
+ # versions: List[str] = field(default=[]) # version of MicroPython""
20
+ family: str = field(default="micropython")
21
+ mcu_name: str = field(default="")
22
+ cpu: str = field(default="")
23
+ # TODO: add variant
24
+
25
+ def __post_init__(self):
26
+ if not self.cpu:
27
+ if " with " in self.description:
28
+ self.cpu = self.description.split(" with ")[-1]
29
+ else:
30
+ self.cpu = self.port
31
+
32
+ @staticmethod
33
+ def from_dict(data: dict) -> "Board":
34
+ return Board(**data)
35
+
36
+ def to_dict(self) -> dict:
37
+ return self.__dict__