mpflash 0.7.5__py3-none-any.whl → 0.7.6__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.
mpflash/ask_input.py CHANGED
@@ -45,7 +45,7 @@ ParamType = Union[DownloadParams, FlashParams]
45
45
 
46
46
  def ask_missing_params(
47
47
  params: ParamType,
48
- action: str = "download",
48
+ # action: str = "download",
49
49
  ) -> ParamType:
50
50
  """
51
51
  Asks the user for parameters that have not been supplied on the commandline and returns the updated params.
@@ -57,6 +57,10 @@ def ask_missing_params(
57
57
  Returns:
58
58
  ParamType: The updated parameters.
59
59
  """
60
+ # if action flash, single input
61
+ # if action download, multiple input
62
+ multi_select = isinstance(params, DownloadParams)
63
+ action = "download" if isinstance(params, DownloadParams) else "flash"
60
64
  if not config.interactive:
61
65
  # no interactivity allowed
62
66
  return params
@@ -64,21 +68,21 @@ def ask_missing_params(
64
68
  import inquirer
65
69
 
66
70
  questions = []
67
- answers = {"action": action}
68
- if isinstance(params, FlashParams):
71
+ answers = {"action": "download" if isinstance(params, DownloadParams) else "flash"}
72
+ if not multi_select:
69
73
  if not params.serial or "?" in params.serial:
70
- ask_serialport(questions, action=action)
74
+ ask_serialport(questions)
71
75
  else:
72
76
  answers["serial"] = params.serial
73
77
 
74
78
  if not params.versions or "?" in params.versions:
75
- ask_versions(questions, action=action)
79
+ ask_versions(questions, multi_select=multi_select, action=action)
76
80
  else:
77
81
  # versions is used to show only the boards for the selected versions
78
82
  answers["versions"] = params.versions # type: ignore
79
83
 
80
84
  if not params.boards or "?" in params.boards:
81
- ask_port_board(questions, action=action)
85
+ ask_port_board(questions, multi_select=multi_select, action=action)
82
86
  if questions:
83
87
  answers = inquirer.prompt(questions, answers=answers)
84
88
  if not answers:
@@ -86,10 +90,10 @@ def ask_missing_params(
86
90
  return [] # type: ignore
87
91
  # print(repr(answers))
88
92
  if isinstance(params, FlashParams) and "serial" in answers:
89
- params.serial = answers["serial"]
93
+ params.serial = answers["serial"].split()[0] # split to remove the description
90
94
  if "port" in answers:
91
95
  params.ports = [p for p in params.ports if p != "?"] # remove the "?" if present
92
- params.ports.extend(answers["port"])
96
+ params.ports.append(answers["port"])
93
97
  if "boards" in answers:
94
98
  params.boards = [b for b in params.boards if b != "?"] # remove the "?" if present
95
99
  params.boards.extend(answers["boards"] if isinstance(answers["boards"], list) else [answers["boards"]])
@@ -144,7 +148,7 @@ def filter_matching_boards(answers: dict) -> Sequence[Tuple[str, str]]:
144
148
  return some_boards
145
149
 
146
150
 
147
- def ask_port_board(questions: list, *, action: str):
151
+ def ask_port_board(questions: list, *, multi_select: bool, action: str):
148
152
  """
149
153
  Asks the user for the port and board selection.
150
154
 
@@ -160,7 +164,7 @@ def ask_port_board(questions: list, *, action: str):
160
164
 
161
165
  # if action flash, single input
162
166
  # if action download, multiple input
163
- inquirer_ux = inquirer.Checkbox if action == "download" else inquirer.List
167
+ inquirer_ux = inquirer.Checkbox if multi_select else inquirer.List
164
168
  questions.extend(
165
169
  (
166
170
  inquirer.List(
@@ -183,7 +187,7 @@ def ask_port_board(questions: list, *, action: str):
183
187
  )
184
188
 
185
189
 
186
- def ask_versions(questions: list, *, action: str):
190
+ def ask_versions(questions: list, *, multi_select: bool, action: str):
187
191
  """
188
192
  Asks the user for the version selection.
189
193
 
@@ -198,7 +202,7 @@ def ask_versions(questions: list, *, action: str):
198
202
  import inquirer
199
203
  import inquirer.errors
200
204
 
201
- input_ux = inquirer.Checkbox if action == "download" else inquirer.List
205
+ input_ux = inquirer.Checkbox if multi_select else inquirer.List
202
206
  mp_versions: List[str] = micropython_versions()
203
207
  mp_versions = [v for v in mp_versions if "preview" not in v]
204
208
 
@@ -226,12 +230,12 @@ def ask_versions(questions: list, *, action: str):
226
230
  # hints=["Use space to select multiple options"],
227
231
  choices=mp_versions,
228
232
  autocomplete=True,
229
- validate=at_least_one_validation,
233
+ validate=at_least_one_validation, # type: ignore
230
234
  )
231
235
  )
232
236
 
233
237
 
234
- def ask_serialport(questions: list, *, action: str):
238
+ def ask_serialport(questions: list, *, multi_select: bool = False, bluetooth: bool = False):
235
239
  """
236
240
  Asks the user for the serial port selection.
237
241
 
@@ -245,12 +249,12 @@ def ask_serialport(questions: list, *, action: str):
245
249
  # import only when needed to reduce load time
246
250
  import inquirer
247
251
 
248
- serialports = MPRemoteBoard.connected_boards()
252
+ comports = MPRemoteBoard.connected_boards(bluetooth=bluetooth, description=True)
249
253
  questions.append(
250
254
  inquirer.List(
251
255
  "serial",
252
256
  message="Which serial port do you want to {action} ?",
253
- choices=serialports,
257
+ choices=comports,
254
258
  other=True,
255
259
  validate=lambda _, x: True if x else "Please select or enter a serial port", # type: ignore
256
260
  )
mpflash/cli_download.py CHANGED
@@ -81,7 +81,7 @@ def cli_download(**kwargs) -> int:
81
81
  # no boards specified - detect connected ports and boards
82
82
  params.ports, params.boards = connected_ports_boards()
83
83
 
84
- params = ask_missing_params(params, action="download")
84
+ params = ask_missing_params(params)
85
85
  if not params: # Cancelled by user
86
86
  return 2
87
87
  params.versions = [clean_version(v, drop_v=True) for v in params.versions]
mpflash/cli_flash.py CHANGED
@@ -101,6 +101,14 @@ def cli_flash_board(**kwargs) -> int:
101
101
  kwargs["boards"] = [kwargs.pop("board")]
102
102
 
103
103
  params = FlashParams(**kwargs)
104
+
105
+ # make it simple for the user to flash one board
106
+ # by asking for the serial port if not specified
107
+ if params.boards == ["?"] and params.serial == "auto":
108
+ params.serial = "?"
109
+
110
+ # Detect connected boards if not specified,
111
+ # and ask for input if boards cannot be detected
104
112
  if not params.boards or params.boards == []:
105
113
  # nothing specified - detect connected boards
106
114
  params.ports, params.boards = connected_ports_boards()
@@ -125,7 +133,7 @@ def cli_flash_board(**kwargs) -> int:
125
133
  log.warning(f"unable to resolve board description: {e}")
126
134
 
127
135
  # Ask for missing input if needed
128
- params = ask_missing_params(params, action="flash")
136
+ params = ask_missing_params(params)
129
137
  if not params: # Cancelled by user
130
138
  return 2
131
139
  # TODO: Just in time Download of firmware
mpflash/cli_main.py CHANGED
@@ -3,6 +3,7 @@
3
3
  # import rich_click as click
4
4
 
5
5
  import click
6
+ from loguru import logger as log
6
7
 
7
8
  from .cli_download import cli_download
8
9
  from .cli_flash import cli_flash_board
@@ -19,8 +20,11 @@ def mpflash():
19
20
  result = cli(standalone_mode=False)
20
21
  exit(result)
21
22
  except AttributeError as e:
22
- print(f"Error: {e}")
23
+ log.error(f"Error: {e}")
23
24
  exit(-1)
25
+ except click.exceptions.ClickException as e:
26
+ log.error(f"Error: {e}")
27
+ exit(-2)
24
28
 
25
29
 
26
30
  if __name__ == "__main__":
@@ -64,7 +64,7 @@ class MPRemoteBoard:
64
64
  return f"MPRemoteBoard({self.serialport}, {self.family} {self.port}, {self.board}, {self.version})"
65
65
 
66
66
  @staticmethod
67
- def connected_boards(bluetooth: bool = False) -> List[str]:
67
+ def connected_boards(bluetooth: bool = False, description: bool = False) -> List[str]:
68
68
  # TODO: rename to connected_comports
69
69
  """
70
70
  Get a list of connected comports.
@@ -81,8 +81,19 @@ class MPRemoteBoard:
81
81
  # filter out bluetooth ports
82
82
  comports = [p for p in comports if "bluetooth" not in p.description.lower()]
83
83
  comports = [p for p in comports if "BTHENUM" not in p.hwid]
84
-
85
- return sorted([p.device for p in comports])
84
+ if description:
85
+ output = [
86
+ f"{p.device} {(p.manufacturer + ' ') if p.manufacturer and not p.description.startswith(p.manufacturer) else ''}{p.description}"
87
+ for p in comports
88
+ ]
89
+ else:
90
+ output = [p.device for p in comports]
91
+
92
+ if sys.platform == "win32":
93
+ # Windows sort of comports by number - but fallback to device name
94
+ return sorted(output, key=lambda x: int(x.split()[0][3:]) if x.split()[0][3:].isdigit() else x)
95
+ # sort by device name
96
+ return sorted(output)
86
97
 
87
98
  @retry(stop=stop_after_attempt(RETRIES), wait=wait_fixed(1), reraise=True) # type: ignore ## retry_error_cls=ConnectionError,
88
99
  def get_mcu_info(self, timeout: int = 2):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: mpflash
3
- Version: 0.7.5
3
+ Version: 0.7.6
4
4
  Summary: Flash and download tool for MicroPython firmwares
5
5
  Home-page: https://github.com/Josverl/micropython-stubber/blob/main/src/mpflash/README.md
6
6
  License: MIT
@@ -1,10 +1,10 @@
1
1
  mpflash/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- mpflash/ask_input.py,sha256=vK0G6q-Spd-m34bdBQVzERFjDib6Wen9eJ-mPqImCr8,9010
3
- mpflash/cli_download.py,sha256=0mG2c5SJxe53m_hVbne_jzrq9gm0jAFnvAhiIEtA1GA,3642
4
- mpflash/cli_flash.py,sha256=9wUdD17VISJ4vkgYfCbG_loDkkWkG-HOUHzumZwMGGw,5845
2
+ mpflash/ask_input.py,sha256=XxYbO2DwB59pyv1uec9fN7nDxQcHLPnp55LSU8eOMg8,9459
3
+ mpflash/cli_download.py,sha256=YHoQOaY5Cg0-jKkEHNa9jvlTr9AfVw9xNm33eWahfdI,3623
4
+ mpflash/cli_flash.py,sha256=yh8JH88LduSRW0gUvCpTUVmY6PaojciPZeEdHqtxq6M,6133
5
5
  mpflash/cli_group.py,sha256=nL3H06PHm_XUDlMuRyjgmTYeLnkrLa9mKDdahYw-KRo,1967
6
6
  mpflash/cli_list.py,sha256=KIlEeqcIIBf0g-emS43fzKspUy6fn9TUuFl0u00XaK8,1024
7
- mpflash/cli_main.py,sha256=BgqkDeEV0LBdT_Xn_Ay3zQOVJ-73pWSA4ngRf9KxGpw,656
7
+ mpflash/cli_main.py,sha256=GJzA4_WTiwAzQP0b2tCXwfyNId1TeBnrzU1GP5xZans,796
8
8
  mpflash/common.py,sha256=lucFGMLl03qz-5Ic2XVv4g5XVt6hloUU6N5v0tSaUYE,1049
9
9
  mpflash/config.py,sha256=G6TxliEGxoYXy1SHQYBKgywnKccz9QzD3mGq_Vv1frg,419
10
10
  mpflash/download.py,sha256=HMYpLVIcy_FaZGHIuucsmJ4fceYhf5DFJgG8f7r-mcA,11120
@@ -25,7 +25,7 @@ mpflash/mpboard_id/__init__.py,sha256=LT52MV3tIHgBu_bFdvae2csahzonsCwno2ardU5ivs
25
25
  mpflash/mpboard_id/board_id.py,sha256=vGPfxMVmQCBRlsZJAhsbhZStlDl21zLC0sqXcaBrSXc,2592
26
26
  mpflash/mpboard_id/board_info.csv,sha256=KPWDo-zHWfrPGQn9oInsDH-5IdCzhBCs6K_YAmqqSpQ,96983
27
27
  mpflash/mpboard_id/board_info.json,sha256=JtVyOMIO1O7vLKzJ0hyXQ4JSxXiQBJyay2hjdNLnZM0,674442
28
- mpflash/mpremoteboard/__init__.py,sha256=FAVt8eEqNzEvVCDsEMZEarusJR6Rs-Y_N5kR5gUIeCM,7110
28
+ mpflash/mpremoteboard/__init__.py,sha256=fJ_N1F6R3CfP9F7pmocb5l8yRvzmSmtHi4u_uTQHR1w,7683
29
29
  mpflash/mpremoteboard/mpy_fw_info.py,sha256=6AQbN3jtQgllqWQYl4e-63KeEtV08EXk8_JnM6XBkvo,4554
30
30
  mpflash/mpremoteboard/runner.py,sha256=-PgzAeBGbyXaAUlwyiw4mcINsP2U1XRRjP1_QdBrxpg,4786
31
31
  mpflash/vendor/dfu.py,sha256=oK_MRSOyDJrUuS6D24IMIsfL7oLcrvUq0yp_h4WIY2U,5739
@@ -33,8 +33,8 @@ mpflash/vendor/pydfu.py,sha256=_MdBRo1EeNeKDqFPSTB5tNL1jGSBJgsVeVjE5e7Pb8s,20542
33
33
  mpflash/vendor/readme.md,sha256=iIIZxuLUIGHQ0KODzYVtMezsztvyxCXcNJp_AzwTIPk,86
34
34
  mpflash/vendor/versions.py,sha256=ooRZjeeYepQHwp12hMu2m0p8nZXQ5s942w5mGkKmgeI,3629
35
35
  mpflash/worklist.py,sha256=izHCPR39OYMXydXpLjtjsgaYlNAfrlQz0_joDPmhDJM,5297
36
- mpflash-0.7.5.dist-info/entry_points.txt,sha256=Jk_visOhYOsZIcSP2Ms9hKqfKy1iorR-6dYltSoWCpY,52
37
- mpflash-0.7.5.dist-info/LICENSE,sha256=mWpNhsIxWzetYNnTpr4eb3HtgsxGIC8KcYWxXEcxQvE,1077
38
- mpflash-0.7.5.dist-info/METADATA,sha256=vPNDK5oPA8PBmyrBnxn_gO6oFS1js4ks6qOCfOfWpIM,14633
39
- mpflash-0.7.5.dist-info/WHEEL,sha256=d2fvjOD7sXsVzChCqf0Ty0JbHKBaLYwDbGQDwQTnJ50,88
40
- mpflash-0.7.5.dist-info/RECORD,,
36
+ mpflash-0.7.6.dist-info/entry_points.txt,sha256=Jk_visOhYOsZIcSP2Ms9hKqfKy1iorR-6dYltSoWCpY,52
37
+ mpflash-0.7.6.dist-info/LICENSE,sha256=mWpNhsIxWzetYNnTpr4eb3HtgsxGIC8KcYWxXEcxQvE,1077
38
+ mpflash-0.7.6.dist-info/METADATA,sha256=ci7Uf09buIB9AfiBv5NVsO-LFb__tlkF295aZhTtjyU,14633
39
+ mpflash-0.7.6.dist-info/WHEEL,sha256=d2fvjOD7sXsVzChCqf0Ty0JbHKBaLYwDbGQDwQTnJ50,88
40
+ mpflash-0.7.6.dist-info/RECORD,,