mpflash 1.24.7__py3-none-any.whl → 1.24.8__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 +7 -7
- mpflash/basicgit.py +23 -57
- mpflash/bootloader/__init__.py +0 -2
- mpflash/bootloader/detect.py +1 -2
- mpflash/bootloader/manual.py +0 -1
- mpflash/bootloader/touch1200.py +2 -2
- mpflash/cli_flash.py +28 -5
- mpflash/cli_group.py +1 -0
- mpflash/cli_list.py +2 -2
- mpflash/cli_main.py +1 -1
- mpflash/common.py +6 -14
- mpflash/config.py +26 -7
- mpflash/connected.py +6 -14
- mpflash/download.py +56 -23
- mpflash/downloaded.py +1 -5
- mpflash/flash/__init__.py +33 -18
- mpflash/flash/esp.py +39 -8
- mpflash/flash/uf2/linux.py +4 -9
- mpflash/flash/uf2/macos.py +1 -1
- mpflash/flash/uf2/windows.py +1 -1
- mpflash/flash/worklist.py +7 -2
- mpflash/list.py +17 -6
- mpflash/logger.py +1 -3
- mpflash/mpboard_id/__init__.py +6 -87
- mpflash/mpboard_id/add_boards.py +3 -8
- mpflash/mpboard_id/board_id.py +0 -1
- mpflash/mpboard_id/board_info.json +30974 -0
- mpflash/mpboard_id/known.py +94 -0
- mpflash/mpboard_id/store.py +0 -2
- mpflash/mpremoteboard/__init__.py +13 -9
- mpflash/mpremoteboard/mpy_fw_info.py +14 -17
- mpflash/py.typed +0 -0
- mpflash/vendor/click_aliases.py +64 -0
- mpflash/vendor/dfu.py +2 -8
- mpflash/vendor/pydfu.py +3 -14
- mpflash/versions.py +9 -6
- {mpflash-1.24.7.dist-info → mpflash-1.24.8.dist-info}/METADATA +71 -13
- mpflash-1.24.8.dist-info/RECORD +59 -0
- {mpflash-1.24.7.dist-info → mpflash-1.24.8.dist-info}/WHEEL +1 -1
- mpflash-1.24.7.dist-info/RECORD +0 -56
- {mpflash-1.24.7.dist-info → mpflash-1.24.8.dist-info}/LICENSE +0 -0
- {mpflash-1.24.7.dist-info → mpflash-1.24.8.dist-info}/entry_points.txt +0 -0
mpflash/ask_input.py
CHANGED
@@ -11,8 +11,7 @@ from loguru import logger as log
|
|
11
11
|
|
12
12
|
from .common import DownloadParams, FlashParams, ParamType
|
13
13
|
from .config import config
|
14
|
-
from .mpboard_id import
|
15
|
-
known_stored_boards)
|
14
|
+
from .mpboard_id import get_known_boards_for_port, get_known_ports, known_stored_boards
|
16
15
|
from .mpremoteboard import MPRemoteBoard
|
17
16
|
from .versions import micropython_versions
|
18
17
|
|
@@ -73,11 +72,11 @@ def ask_missing_params(
|
|
73
72
|
# params.ports = [p for p in params.ports if p != "?"] # remove the "?" if present
|
74
73
|
if isinstance(answers["port"], str):
|
75
74
|
params.ports.append(answers["port"])
|
76
|
-
elif isinstance(answers["port"], list):
|
75
|
+
elif isinstance(answers["port"], list): # type: ignore
|
77
76
|
params.ports.extend(answers["port"])
|
78
77
|
else:
|
79
78
|
raise ValueError(f"Unexpected type for answers['port']: {type(answers['port'])}")
|
80
|
-
|
79
|
+
|
81
80
|
if "boards" in answers:
|
82
81
|
params.boards = [b for b in params.boards if b != "?"] # remove the "?" if present
|
83
82
|
params.boards.extend(answers["boards"] if isinstance(answers["boards"], list) else [answers["boards"]])
|
@@ -157,23 +156,24 @@ def ask_port_board(*, multi_select: bool, action: str):
|
|
157
156
|
),
|
158
157
|
inquirer_ux(
|
159
158
|
"boards",
|
160
|
-
message=(
|
161
|
-
"Which {port} board firmware do you want to {action} " + "to {serial} ?" if action == "flash" else "?"
|
162
|
-
),
|
159
|
+
message=("Which {port} board firmware do you want to {action} " + "to {serial} ?" if action == "flash" else "?"),
|
163
160
|
choices=filter_matching_boards,
|
164
161
|
validate=at_least_one_validation, # type: ignore
|
165
162
|
# validate=lambda _, x: True if x else "Please select at least one board", # type: ignore
|
166
163
|
),
|
167
164
|
]
|
168
165
|
|
166
|
+
|
169
167
|
def at_least_one_validation(answers, current) -> bool:
|
170
168
|
import inquirer.errors
|
169
|
+
|
171
170
|
if not current:
|
172
171
|
raise inquirer.errors.ValidationError("", reason="Please select at least one item.")
|
173
172
|
if isinstance(current, list) and not any(current):
|
174
173
|
raise inquirer.errors.ValidationError("", reason="Please select at least one item.")
|
175
174
|
return True
|
176
175
|
|
176
|
+
|
177
177
|
def ask_mp_version(multi_select: bool, action: str):
|
178
178
|
"""
|
179
179
|
Asks the user for the version selection.
|
mpflash/basicgit.py
CHANGED
@@ -4,28 +4,25 @@ Simple Git module, where needed via powershell
|
|
4
4
|
Some of the functions are based on the PyGithub module
|
5
5
|
"""
|
6
6
|
|
7
|
-
import os
|
8
7
|
import subprocess
|
9
8
|
from pathlib import Path
|
10
9
|
from typing import List, Optional, Union
|
11
10
|
|
12
11
|
import cachetools.func
|
13
|
-
from github import Auth, BadCredentialsException, Github
|
14
12
|
from loguru import logger as log
|
15
|
-
from packaging.version import parse
|
16
13
|
|
17
|
-
|
14
|
+
from mpflash.config import config
|
18
15
|
|
19
|
-
#
|
20
|
-
# https://docs.github.com/en/rest/using-the-rest-api/rate-limits-for-the-rest-api?apiVersion=2022-11-28#getting-a-higher-rate-limit
|
21
|
-
PAT_NO_ACCESS = (
|
22
|
-
"github_pat_"
|
23
|
-
+ "11AAHPVFQ0G4NTaQ73Bw5J"
|
24
|
-
+ "_fAp7K9sZ1qL8VFnI9g78eUlCdmOXHB3WzSdj2jtEYb4XF3N7PDJBl32qIxq"
|
25
|
-
)
|
26
|
-
PAT = os.environ.get("GITHUB_TOKEN") or PAT_NO_ACCESS
|
27
|
-
GH_CLIENT = Github(auth=Auth.Token(PAT))
|
16
|
+
# from github import Auth, BadCredentialsException, Github
|
28
17
|
|
18
|
+
# # Token with no permissions to avoid throttling
|
19
|
+
# # https://docs.github.com/en/rest/using-the-rest-api/rate-limits-for-the-rest-api?apiVersion=2022-11-28#getting-a-higher-rate-limit
|
20
|
+
# PAT_NO_ACCESS = "github_pat_" + "11AAHPVFQ0G4NTaQ73Bw5J" + "_fAp7K9sZ1qL8VFnI9g78eUlCdmOXHB3WzSdj2jtEYb4XF3N7PDJBl32qIxq"
|
21
|
+
# PAT = os.environ.get("GITHUB_TOKEN") or PAT_NO_ACCESS
|
22
|
+
|
23
|
+
# # GH_CLIENT = Github(auth=Auth.Token(PAT))
|
24
|
+
|
25
|
+
# GH_CLIENT = None
|
29
26
|
|
30
27
|
def _run_local_git(
|
31
28
|
cmd: List[str],
|
@@ -47,10 +44,9 @@ def _run_local_git(
|
|
47
44
|
encoding="utf-8",
|
48
45
|
)
|
49
46
|
else:
|
50
|
-
result = subprocess.run(
|
51
|
-
cmd, capture_output=capture_output, check=True, encoding="utf-8"
|
52
|
-
)
|
47
|
+
result = subprocess.run(cmd, capture_output=capture_output, check=True, encoding="utf-8")
|
53
48
|
except (NotADirectoryError, FileNotFoundError) as e: # pragma: no cover
|
49
|
+
log.error(f"Not a directory: {e}")
|
54
50
|
return None
|
55
51
|
except subprocess.CalledProcessError as e: # pragma: no cover
|
56
52
|
# add some logging for github actions
|
@@ -88,9 +84,7 @@ def clone(remote_repo: str, path: Path, shallow: bool = False, tag: Optional[str
|
|
88
84
|
return False
|
89
85
|
|
90
86
|
|
91
|
-
def get_local_tag(
|
92
|
-
repo: Optional[Union[str, Path]] = None, abbreviate: bool = True
|
93
|
-
) -> Union[str, None]:
|
87
|
+
def get_local_tag(repo: Optional[Union[str, Path]] = None, abbreviate: bool = True) -> Union[str, None]:
|
94
88
|
"""
|
95
89
|
get the most recent git version tag of a local repo
|
96
90
|
repo Path should be in the form of : repo = "./repo/micropython"
|
@@ -123,6 +117,9 @@ def get_local_tags(repo: Optional[Path] = None, minver: Optional[str] = None) ->
|
|
123
117
|
"""
|
124
118
|
get list of all tags of a local repo
|
125
119
|
"""
|
120
|
+
# Just in time import
|
121
|
+
from packaging.version import parse
|
122
|
+
|
126
123
|
if not repo:
|
127
124
|
repo = Path(".")
|
128
125
|
|
@@ -136,19 +133,22 @@ def get_local_tags(repo: Optional[Path] = None, minver: Optional[str] = None) ->
|
|
136
133
|
return sorted(tags)
|
137
134
|
|
138
135
|
|
139
|
-
from github.GithubException import BadCredentialsException
|
140
|
-
|
141
|
-
|
142
136
|
@cachetools.func.ttl_cache(maxsize=16, ttl=60) # 60 seconds
|
143
137
|
def get_tags(repo: str, minver: Optional[str] = None) -> List[str]:
|
144
138
|
"""
|
145
139
|
Get list of tag of a repote github repo.
|
146
140
|
only the last -preview tag is kept
|
147
141
|
"""
|
142
|
+
# Just in time import
|
143
|
+
from github import BadCredentialsException
|
144
|
+
from packaging.version import parse
|
145
|
+
|
148
146
|
if not repo or not isinstance(repo, str) or "/" not in repo: # type: ignore
|
149
147
|
return []
|
148
|
+
|
149
|
+
gh_client = config.gh_client
|
150
150
|
try:
|
151
|
-
gh_repo =
|
151
|
+
gh_repo = gh_client.get_repo(repo)
|
152
152
|
except BadCredentialsException as e:
|
153
153
|
log.error(f"Github authentication error - {e}")
|
154
154
|
return []
|
@@ -179,40 +179,6 @@ def checkout_tag(tag: str, repo: Optional[Union[str, Path]] = None) -> bool:
|
|
179
179
|
return True
|
180
180
|
|
181
181
|
|
182
|
-
def sync_submodules(repo: Union[Path, str]) -> bool:
|
183
|
-
"""
|
184
|
-
make sure any submodules are in sync
|
185
|
-
"""
|
186
|
-
cmds = [
|
187
|
-
["git", "submodule", "sync", "--quiet"],
|
188
|
-
# ["git", "submodule", "update", "--quiet"],
|
189
|
-
["git", "submodule", "update", "--init", "lib/micropython-lib"],
|
190
|
-
]
|
191
|
-
for cmd in cmds:
|
192
|
-
if result := _run_local_git(cmd, repo=repo, expect_stderr=True):
|
193
|
-
# actually a good result
|
194
|
-
log.debug(result.stderr)
|
195
|
-
else:
|
196
|
-
return False
|
197
|
-
checkout_arduino_lib(Path(repo))
|
198
|
-
return True
|
199
|
-
|
200
|
-
|
201
|
-
def checkout_arduino_lib(mpy_path: Path):
|
202
|
-
"""
|
203
|
-
Checkout the arduino-lib submodule repo if it exists
|
204
|
-
|
205
|
-
This is needed as some of the arduino boards freeze modules originationg from the arduino-lib
|
206
|
-
"""
|
207
|
-
# arduino_lib_path = mpy_path / "lib/arduino-lib"
|
208
|
-
if (mpy_path / "lib/arduino-lib").exists():
|
209
|
-
cmd = ["git", "submodule", "update", "--init", "lib/arduino-lib"]
|
210
|
-
try:
|
211
|
-
result = subprocess.run(cmd, cwd=mpy_path, check=True)
|
212
|
-
log.info(f"checkout arduino-lib: {result.returncode}")
|
213
|
-
except subprocess.CalledProcessError as e:
|
214
|
-
log.warning("Could not check out arduino-lib, error: ", e)
|
215
|
-
|
216
182
|
|
217
183
|
def checkout_commit(commit_hash: str, repo: Optional[Union[Path, str]] = None) -> bool:
|
218
184
|
"""
|
mpflash/bootloader/__init__.py
CHANGED
mpflash/bootloader/detect.py
CHANGED
mpflash/bootloader/manual.py
CHANGED
mpflash/bootloader/touch1200.py
CHANGED
@@ -27,10 +27,10 @@ def enter_bootloader_touch_1200bps(mcu: MPRemoteBoard, timeout: int = 10):
|
|
27
27
|
|
28
28
|
except serial.SerialException as e:
|
29
29
|
log.exception(e)
|
30
|
-
raise MPFlashError("pySerial error:
|
30
|
+
raise MPFlashError(f"pySerial error: {str(e)}") from e
|
31
31
|
except Exception as e:
|
32
32
|
log.exception(e)
|
33
|
-
raise MPFlashError("Error:
|
33
|
+
raise MPFlashError(f"Error: {str(e)}") from e
|
34
34
|
|
35
35
|
# be optimistic
|
36
36
|
return True
|
mpflash/cli_flash.py
CHANGED
@@ -92,6 +92,14 @@ from mpflash.versions import clean_version
|
|
92
92
|
help="The MicroPython board ID to flash. If not specified will try to read the BOARD_ID from the connected MCU.",
|
93
93
|
metavar="BOARD_ID or ?",
|
94
94
|
)
|
95
|
+
@click.option(
|
96
|
+
"--variant",
|
97
|
+
"-var",
|
98
|
+
"variant", # single board
|
99
|
+
multiple=False,
|
100
|
+
help="The board VARIANT to flash or '-'. If not specified will try to read the variant from the connected MCU.",
|
101
|
+
metavar="VARIANT",
|
102
|
+
)
|
95
103
|
@click.option(
|
96
104
|
"--cpu",
|
97
105
|
"--chip",
|
@@ -102,9 +110,9 @@ from mpflash.versions import clean_version
|
|
102
110
|
)
|
103
111
|
@click.option(
|
104
112
|
"--erase/--no-erase",
|
105
|
-
default=
|
113
|
+
default=False,
|
106
114
|
show_default=True,
|
107
|
-
help="""Erase flash before writing new firmware.
|
115
|
+
help="""Erase flash before writing new firmware.""",
|
108
116
|
)
|
109
117
|
@click.option(
|
110
118
|
"--bootloader",
|
@@ -115,14 +123,21 @@ from mpflash.versions import clean_version
|
|
115
123
|
show_default=True,
|
116
124
|
help="""How to enter the (MicroPython) bootloader before flashing.""",
|
117
125
|
)
|
126
|
+
@click.option(
|
127
|
+
"--flash_mode", "-fm",
|
128
|
+
type=click.Choice(["keep", "qio", "qout", "dio", "dout"]),
|
129
|
+
default="keep",
|
130
|
+
show_default=True,
|
131
|
+
help="""Flash mode for ESP boards. (default: keep)""",
|
132
|
+
)
|
118
133
|
def cli_flash_board(**kwargs) -> int:
|
119
134
|
# version to versions, board to boards
|
120
|
-
kwargs["versions"] = [kwargs.pop("version")] if kwargs["version"]
|
135
|
+
kwargs["versions"] = [kwargs.pop("version")] if kwargs["version"] is not None else []
|
121
136
|
if kwargs["board"] is None:
|
122
137
|
kwargs["boards"] = []
|
123
138
|
kwargs.pop("board")
|
124
139
|
else:
|
125
|
-
kwargs["boards"] = [kwargs.pop("board")]
|
140
|
+
kwargs["boards"] = [kwargs.pop("board")]
|
126
141
|
|
127
142
|
params = FlashParams(**kwargs)
|
128
143
|
params.versions = list(params.versions)
|
@@ -141,7 +156,9 @@ def cli_flash_board(**kwargs) -> int:
|
|
141
156
|
all_boards: List[MPRemoteBoard] = []
|
142
157
|
if not params.boards:
|
143
158
|
# nothing specified - detect connected boards
|
144
|
-
params.ports, params.boards, all_boards = connected_ports_boards(
|
159
|
+
params.ports, params.boards, all_boards = connected_ports_boards(
|
160
|
+
include=params.ports, ignore=params.ignore, bluetooth=params.bluetooth
|
161
|
+
)
|
145
162
|
if params.boards == []:
|
146
163
|
# No MicroPython boards detected, but it could be unflashed or in bootloader mode
|
147
164
|
# Ask for serial port and board_id to flash
|
@@ -171,6 +188,11 @@ def cli_flash_board(**kwargs) -> int:
|
|
171
188
|
if not all_boards:
|
172
189
|
log.trace("No boards detected yet, scanning for connected boards")
|
173
190
|
_, _, all_boards = connected_ports_boards(include=params.ports, ignore=params.ignore)
|
191
|
+
# if variant id provided on the cmdline, treat is as an override
|
192
|
+
if params.variant:
|
193
|
+
for b in all_boards:
|
194
|
+
b.variant = params.variant if (params.variant != "-") else ""
|
195
|
+
|
174
196
|
worklist = full_auto_worklist(
|
175
197
|
all_boards=all_boards,
|
176
198
|
version=params.versions[0],
|
@@ -199,6 +221,7 @@ def cli_flash_board(**kwargs) -> int:
|
|
199
221
|
params.fw_folder,
|
200
222
|
params.erase,
|
201
223
|
params.bootloader,
|
224
|
+
flash_mode = params.flash_mode,
|
202
225
|
):
|
203
226
|
log.info(f"Flashed {len(flashed)} boards")
|
204
227
|
show_mcus(flashed, title="Updated boards after flashing")
|
mpflash/cli_group.py
CHANGED
mpflash/cli_list.py
CHANGED
@@ -73,8 +73,8 @@ def cli_list_mcus(serial: List[str], ignore: List[str], bluetooth: bool, as_json
|
|
73
73
|
# TODO? Ask user to select a serialport if [?] is given ?
|
74
74
|
|
75
75
|
conn_mcus = list_mcus(ignore=ignore, include=serial, bluetooth=bluetooth)
|
76
|
-
# ignore boards that have the [
|
77
|
-
conn_mcus = [item for item in conn_mcus if not (item.toml.get("mpflash", {}).get("ignore", False))]
|
76
|
+
# ignore boards that have the [mpflash] ignore flag set
|
77
|
+
conn_mcus = [item for item in conn_mcus if not (item.toml.get("mpflash", {}).get("ignore", False))]
|
78
78
|
if as_json:
|
79
79
|
# remove the path and firmware attibutes from the json output as they are always empty
|
80
80
|
for mcu in conn_mcus:
|
mpflash/cli_main.py
CHANGED
mpflash/common.py
CHANGED
@@ -10,12 +10,10 @@ from typing import List, Optional, Union
|
|
10
10
|
from serial.tools import list_ports
|
11
11
|
from serial.tools.list_ports_common import ListPortInfo
|
12
12
|
|
13
|
-
from mpflash.basicgit import GH_CLIENT as GH_CLIENT
|
14
13
|
|
14
|
+
# from mpflash.flash.esp import FlashMode
|
15
15
|
from .logger import log
|
16
16
|
|
17
|
-
# from mpflash.mpremoteboard import MPRemoteBoard
|
18
|
-
|
19
17
|
PORT_FWTYPES = {
|
20
18
|
"stm32": [".dfu"], # need .dfu for pydfu.py - .hex for cube cli/GUI
|
21
19
|
"esp32": [".bin"],
|
@@ -28,6 +26,7 @@ PORT_FWTYPES = {
|
|
28
26
|
"renesas-ra": [".hex"],
|
29
27
|
}
|
30
28
|
|
29
|
+
UF2_PORTS = [port for port, exts in PORT_FWTYPES.items() if ".uf2" in exts]
|
31
30
|
|
32
31
|
@dataclass
|
33
32
|
class FWInfo:
|
@@ -71,6 +70,7 @@ class Params:
|
|
71
70
|
|
72
71
|
ports: List[str] = field(default_factory=list)
|
73
72
|
boards: List[str] = field(default_factory=list)
|
73
|
+
variant: str = ""
|
74
74
|
versions: List[str] = field(default_factory=list)
|
75
75
|
fw_folder: Path = Path()
|
76
76
|
serial: List[str] = field(default_factory=list)
|
@@ -101,6 +101,7 @@ class FlashParams(Params):
|
|
101
101
|
erase: bool = True
|
102
102
|
bootloader: BootloaderMethod = BootloaderMethod.NONE
|
103
103
|
cpu: str = ""
|
104
|
+
flash_mode: str = "keep" # keep, qio, qout, dio, dout
|
104
105
|
|
105
106
|
def __post_init__(self):
|
106
107
|
if isinstance(self.bootloader, str):
|
@@ -137,14 +138,7 @@ def filtered_comports(
|
|
137
138
|
# remove ports that are to be ignored
|
138
139
|
log.trace(f"{include=}, {ignore=}, {bluetooth=}")
|
139
140
|
|
140
|
-
comports = [
|
141
|
-
p for p in list_ports.comports() if not any(fnmatch.fnmatch(p.device, i) for i in ignore)
|
142
|
-
]
|
143
|
-
|
144
|
-
if False:
|
145
|
-
import jsons
|
146
|
-
|
147
|
-
print(jsons.dumps(comports).replace('{"description":', '\n{"description":'))
|
141
|
+
comports = [p for p in list_ports.comports() if not any(fnmatch.fnmatch(p.device, i) for i in ignore)]
|
148
142
|
|
149
143
|
if platform.system() == "Linux":
|
150
144
|
# use p.location to filter out the bogus ports on newer Linux kernels
|
@@ -156,9 +150,7 @@ def filtered_comports(
|
|
156
150
|
|
157
151
|
if include != ["*"]:
|
158
152
|
# if there are explicit ports to include, add them to the list
|
159
|
-
explicit = [
|
160
|
-
p for p in list_ports.comports() if any(fnmatch.fnmatch(p.device, i) for i in include)
|
161
|
-
]
|
153
|
+
explicit = [p for p in list_ports.comports() if any(fnmatch.fnmatch(p.device, i) for i in include)]
|
162
154
|
log.trace(f"explicit: {[p.device for p in explicit]}")
|
163
155
|
if ignore == []:
|
164
156
|
# if nothing to ignore, just use the explicit list as a sinple sane default
|
mpflash/config.py
CHANGED
@@ -3,34 +3,34 @@
|
|
3
3
|
import os
|
4
4
|
from importlib.metadata import version
|
5
5
|
from pathlib import Path
|
6
|
-
from typing import List
|
6
|
+
from typing import List, Optional
|
7
7
|
|
8
8
|
import platformdirs
|
9
9
|
|
10
|
-
from mpflash.logger import log
|
11
|
-
|
12
10
|
|
13
11
|
def get_version():
|
14
12
|
name = __package__ or "mpflash"
|
15
13
|
return version(name)
|
16
14
|
|
17
15
|
|
18
|
-
class
|
16
|
+
class MPFlashConfig:
|
19
17
|
"""Centralized configuration for mpflash"""
|
20
18
|
|
21
19
|
quiet: bool = False
|
22
20
|
verbose: bool = False
|
23
21
|
usb: bool = False
|
24
22
|
ignore_ports: List[str] = []
|
25
|
-
|
23
|
+
_firmware_folder: Optional[Path] = None
|
26
24
|
# test options specified on the commandline
|
27
25
|
tests: List[str] = []
|
28
26
|
_interactive: bool = True
|
27
|
+
_gh_client = None
|
29
28
|
|
30
29
|
@property
|
31
30
|
def interactive(self):
|
32
31
|
# No interactions in CI
|
33
32
|
if os.getenv("GITHUB_ACTIONS") == "true":
|
33
|
+
from mpflash.logger import log
|
34
34
|
log.warning("Disabling interactive mode in CI")
|
35
35
|
return False
|
36
36
|
return self._interactive
|
@@ -39,6 +39,25 @@ class MPtoolConfig:
|
|
39
39
|
def interactive(self, value: bool):
|
40
40
|
self._interactive = value
|
41
41
|
|
42
|
-
|
43
|
-
|
42
|
+
@property
|
43
|
+
def firmware_folder(self) -> Path:
|
44
|
+
"""The folder where firmware files are stored"""
|
45
|
+
if not self._firmware_folder:
|
46
|
+
self._firmware_folder = platformdirs.user_downloads_path() / "firmware"
|
47
|
+
return self._firmware_folder
|
48
|
+
|
49
|
+
@property
|
50
|
+
def gh_client(self):
|
51
|
+
"""The gh client to use"""
|
52
|
+
if not self._gh_client:
|
53
|
+
from github import Auth, Github
|
54
|
+
# Token with no permissions to avoid throttling
|
55
|
+
# https://docs.github.com/en/rest/using-the-rest-api/rate-limits-for-the-rest-api?apiVersion=2022-11-28#getting-a-higher-rate-limit
|
56
|
+
PAT_NO_ACCESS = "github_pat_" + "11AAHPVFQ0G4NTaQ73Bw5J" + "_fAp7K9sZ1qL8VFnI9g78eUlCdmOXHB3WzSdj2jtEYb4XF3N7PDJBl32qIxq"
|
57
|
+
PAT = os.environ.get("GITHUB_TOKEN") or PAT_NO_ACCESS
|
58
|
+
self._gh_client = Github(auth=Auth.Token(PAT))
|
59
|
+
return self._gh_client
|
60
|
+
|
61
|
+
|
62
|
+
config = MPFlashConfig()
|
44
63
|
__version__ = get_version()
|
mpflash/connected.py
CHANGED
@@ -4,11 +4,9 @@ from rich import print
|
|
4
4
|
from rich.progress import BarColumn, Progress, SpinnerColumn, TextColumn, TimeElapsedColumn
|
5
5
|
from rich.table import Column
|
6
6
|
|
7
|
-
from mpflash.common import filtered_comports
|
7
|
+
from mpflash.common import filtered_comports, find_serial_by_path
|
8
8
|
from mpflash.mpremoteboard import MPRemoteBoard
|
9
9
|
|
10
|
-
from mpflash.common import find_serial_by_path
|
11
|
-
|
12
10
|
|
13
11
|
def connected_ports_boards(
|
14
12
|
*, include: List[str], ignore: List[str], bluetooth: bool = False
|
@@ -23,13 +21,9 @@ def connected_ports_boards(
|
|
23
21
|
- A list of unique board names of the connected MCUs.
|
24
22
|
- A list of MPRemoteBoard instances of the connected MCUs.
|
25
23
|
"""
|
26
|
-
conn_mcus = [
|
27
|
-
|
28
|
-
]
|
29
|
-
# ignore boards that have the [micropython-stubber] ignore flag set
|
30
|
-
conn_mcus = [
|
31
|
-
item for item in conn_mcus if not (item.toml.get("mpflash", {}).get("ignore", False))
|
32
|
-
]
|
24
|
+
conn_mcus = [b for b in list_mcus(include=include, ignore=ignore, bluetooth=bluetooth) if b.connected]
|
25
|
+
# ignore boards that have the [mpflash] ignore flag set
|
26
|
+
conn_mcus = [item for item in conn_mcus if not (item.toml.get("mpflash", {}).get("ignore", False))]
|
33
27
|
|
34
28
|
ports = list({b.port for b in conn_mcus})
|
35
29
|
boards = list({b.board for b in conn_mcus})
|
@@ -42,9 +36,7 @@ rp_text = TextColumn("{task.description} {task.fields[device]}", table_column=Co
|
|
42
36
|
rp_bar = BarColumn(bar_width=None, table_column=Column())
|
43
37
|
|
44
38
|
|
45
|
-
def list_mcus(
|
46
|
-
*, ignore: List[str], include: List[str], bluetooth: bool = False
|
47
|
-
) -> List[MPRemoteBoard]:
|
39
|
+
def list_mcus(*, ignore: List[str], include: List[str], bluetooth: bool = False) -> List[MPRemoteBoard]:
|
48
40
|
"""
|
49
41
|
Retrieves information about connected microcontroller boards.
|
50
42
|
|
@@ -63,7 +55,7 @@ def list_mcus(
|
|
63
55
|
connected_mcus = [
|
64
56
|
MPRemoteBoard(
|
65
57
|
c.device,
|
66
|
-
location=find_serial_by_path(c.device) or c.location or c.hwid or
|
58
|
+
location=find_serial_by_path(c.device) or c.location or c.hwid or "?",
|
67
59
|
)
|
68
60
|
for c in comports
|
69
61
|
]
|