mpflash 0.8.6__py3-none-any.whl → 0.8.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.
Files changed (51) hide show
  1. mpflash/add_firmware.py +98 -98
  2. mpflash/ask_input.py +236 -236
  3. mpflash/bootloader/__init__.py +37 -37
  4. mpflash/bootloader/manual.py +102 -102
  5. mpflash/bootloader/micropython.py +10 -10
  6. mpflash/bootloader/touch1200.py +45 -45
  7. mpflash/cli_download.py +129 -129
  8. mpflash/cli_flash.py +219 -219
  9. mpflash/cli_group.py +98 -98
  10. mpflash/cli_list.py +81 -81
  11. mpflash/cli_main.py +41 -41
  12. mpflash/common.py +164 -164
  13. mpflash/config.py +47 -47
  14. mpflash/connected.py +74 -74
  15. mpflash/download.py +360 -360
  16. mpflash/downloaded.py +130 -129
  17. mpflash/errors.py +9 -9
  18. mpflash/flash.py +52 -52
  19. mpflash/flash_esp.py +59 -59
  20. mpflash/flash_stm32.py +23 -24
  21. mpflash/flash_stm32_cube.py +111 -111
  22. mpflash/flash_stm32_dfu.py +104 -101
  23. mpflash/flash_uf2.py +67 -67
  24. mpflash/flash_uf2_boardid.py +15 -15
  25. mpflash/flash_uf2_linux.py +123 -123
  26. mpflash/flash_uf2_macos.py +34 -34
  27. mpflash/flash_uf2_windows.py +34 -34
  28. mpflash/list.py +89 -89
  29. mpflash/logger.py +41 -41
  30. mpflash/mpboard_id/__init__.py +93 -93
  31. mpflash/mpboard_id/add_boards.py +255 -255
  32. mpflash/mpboard_id/board.py +37 -37
  33. mpflash/mpboard_id/board_id.py +86 -86
  34. mpflash/mpboard_id/store.py +43 -43
  35. mpflash/mpremoteboard/__init__.py +221 -221
  36. mpflash/mpremoteboard/mpy_fw_info.py +141 -141
  37. mpflash/mpremoteboard/runner.py +140 -140
  38. mpflash/uf2disk.py +12 -12
  39. mpflash/vendor/basicgit.py +288 -288
  40. mpflash/vendor/click_aliases.py +91 -91
  41. mpflash/vendor/dfu.py +165 -165
  42. mpflash/vendor/pydfu.py +605 -605
  43. mpflash/vendor/readme.md +2 -2
  44. mpflash/vendor/versions.py +119 -117
  45. mpflash/worklist.py +171 -170
  46. {mpflash-0.8.6.dist-info → mpflash-0.8.8.dist-info}/LICENSE +20 -20
  47. {mpflash-0.8.6.dist-info → mpflash-0.8.8.dist-info}/METADATA +1 -1
  48. mpflash-0.8.8.dist-info/RECORD +52 -0
  49. mpflash-0.8.6.dist-info/RECORD +0 -52
  50. {mpflash-0.8.6.dist-info → mpflash-0.8.8.dist-info}/WHEEL +0 -0
  51. {mpflash-0.8.6.dist-info → mpflash-0.8.8.dist-info}/entry_points.txt +0 -0
mpflash/cli_list.py CHANGED
@@ -1,81 +1,81 @@
1
- import json
2
- from typing import List
3
-
4
- import rich_click as click
5
- from rich import print
6
-
7
- from .cli_group import cli
8
- from .connected import list_mcus
9
- from .list import show_mcus
10
- from .logger import make_quiet
11
-
12
-
13
- @cli.command(
14
- "list",
15
- help="List the connected MCU boards. alias: devs",
16
- aliases=["devs"],
17
- )
18
- @click.option(
19
- "--json",
20
- "-j",
21
- "as_json",
22
- is_flag=True,
23
- default=False,
24
- show_default=True,
25
- help="""Output in json format""",
26
- )
27
- @click.option(
28
- "--serial",
29
- "--serial-port",
30
- "-s",
31
- "serial",
32
- default=["*"],
33
- multiple=True,
34
- show_default=True,
35
- help="Which serial port(s) to list. ",
36
- metavar="SERIALPORT",
37
- )
38
- @click.option(
39
- "--ignore",
40
- "-i",
41
- is_eager=True,
42
- help="Serial port(s) to ignore. Defaults to MPFLASH_IGNORE.",
43
- multiple=True,
44
- default=[],
45
- envvar="MPFLASH_IGNORE",
46
- show_default=True,
47
- metavar="SERIALPORT",
48
- )
49
- @click.option(
50
- "--bluetooth/--no-bluetooth",
51
- "-b/-nb",
52
- is_flag=True,
53
- default=False,
54
- show_default=True,
55
- help="""Include bluetooth ports in the list""",
56
- )
57
- @click.option(
58
- "--progress/--no-progress",
59
- # "-p/-np", -p is already used for --port
60
- "progress",
61
- is_flag=True,
62
- default=True,
63
- show_default=True,
64
- help="""Show progress""",
65
- )
66
- def cli_list_mcus(serial: List[str], ignore: List[str], bluetooth: bool, as_json: bool, progress: bool = True) -> int:
67
- """List the connected MCU boards, and output in a nice table or json."""
68
- serial = list(serial)
69
- ignore = list(ignore)
70
- if as_json:
71
- # avoid noise in json output
72
- make_quiet()
73
- # TODO? Ask user to select a serialport if [?] is given ?
74
-
75
- conn_mcus = list_mcus(ignore=ignore, include=serial, bluetooth=bluetooth)
76
- if as_json:
77
- print(json.dumps([mcu.__dict__ for mcu in conn_mcus], indent=4))
78
- progress = False
79
- if progress:
80
- show_mcus(conn_mcus, refresh=False)
81
- return 0 if conn_mcus else 1
1
+ import json
2
+ from typing import List
3
+
4
+ import rich_click as click
5
+ from rich import print
6
+
7
+ from .cli_group import cli
8
+ from .connected import list_mcus
9
+ from .list import show_mcus
10
+ from .logger import make_quiet
11
+
12
+
13
+ @cli.command(
14
+ "list",
15
+ help="List the connected MCU boards. alias: devs",
16
+ aliases=["devs"],
17
+ )
18
+ @click.option(
19
+ "--json",
20
+ "-j",
21
+ "as_json",
22
+ is_flag=True,
23
+ default=False,
24
+ show_default=True,
25
+ help="""Output in json format""",
26
+ )
27
+ @click.option(
28
+ "--serial",
29
+ "--serial-port",
30
+ "-s",
31
+ "serial",
32
+ default=["*"],
33
+ multiple=True,
34
+ show_default=True,
35
+ help="Which serial port(s) to list. ",
36
+ metavar="SERIALPORT",
37
+ )
38
+ @click.option(
39
+ "--ignore",
40
+ "-i",
41
+ is_eager=True,
42
+ help="Serial port(s) to ignore. Defaults to MPFLASH_IGNORE.",
43
+ multiple=True,
44
+ default=[],
45
+ envvar="MPFLASH_IGNORE",
46
+ show_default=True,
47
+ metavar="SERIALPORT",
48
+ )
49
+ @click.option(
50
+ "--bluetooth/--no-bluetooth",
51
+ "-b/-nb",
52
+ is_flag=True,
53
+ default=False,
54
+ show_default=True,
55
+ help="""Include bluetooth ports in the list""",
56
+ )
57
+ @click.option(
58
+ "--progress/--no-progress",
59
+ # "-p/-np", -p is already used for --port
60
+ "progress",
61
+ is_flag=True,
62
+ default=True,
63
+ show_default=True,
64
+ help="""Show progress""",
65
+ )
66
+ def cli_list_mcus(serial: List[str], ignore: List[str], bluetooth: bool, as_json: bool, progress: bool = True) -> int:
67
+ """List the connected MCU boards, and output in a nice table or json."""
68
+ serial = list(serial)
69
+ ignore = list(ignore)
70
+ if as_json:
71
+ # avoid noise in json output
72
+ make_quiet()
73
+ # TODO? Ask user to select a serialport if [?] is given ?
74
+
75
+ conn_mcus = list_mcus(ignore=ignore, include=serial, bluetooth=bluetooth)
76
+ if as_json:
77
+ print(json.dumps([mcu.__dict__ for mcu in conn_mcus], indent=4))
78
+ progress = False
79
+ if progress:
80
+ show_mcus(conn_mcus, refresh=False)
81
+ return 0 if conn_mcus else 1
mpflash/cli_main.py CHANGED
@@ -1,41 +1,41 @@
1
- """mpflash is a CLI to download and flash MicroPython firmware to various boards."""
2
-
3
- # import rich_click as click
4
-
5
- import os
6
-
7
- import click
8
- from loguru import logger as log
9
-
10
- from .cli_download import cli_download
11
- from .cli_flash import cli_flash_board
12
- from .cli_group import cli
13
- from .cli_list import cli_list_mcus
14
-
15
-
16
- def mpflash():
17
- cli.add_command(cli_list_mcus)
18
- cli.add_command(cli_download)
19
- cli.add_command(cli_flash_board)
20
-
21
- # cli(auto_envvar_prefix="MPFLASH")
22
- if False and os.environ.get("COMPUTERNAME").startswith("JOSVERL"):
23
- # intentional less error suppression on dev machine
24
- result = cli(standalone_mode=False)
25
- else:
26
- try:
27
- result = cli(standalone_mode=True)
28
- exit(result)
29
- except AttributeError as e:
30
- log.error(f"Error: {e}")
31
- exit(-1)
32
- except click.exceptions.ClickException as e:
33
- log.error(f"Error: {e}")
34
- exit(-2)
35
- except click.exceptions.Abort as e:
36
- # Aborted - Ctrl-C
37
- exit(-3)
38
-
39
-
40
- if __name__ == "__main__":
41
- mpflash()
1
+ """mpflash is a CLI to download and flash MicroPython firmware to various boards."""
2
+
3
+ # import rich_click as click
4
+
5
+ import os
6
+
7
+ import click
8
+ from loguru import logger as log
9
+
10
+ from .cli_download import cli_download
11
+ from .cli_flash import cli_flash_board
12
+ from .cli_group import cli
13
+ from .cli_list import cli_list_mcus
14
+
15
+
16
+ def mpflash():
17
+ cli.add_command(cli_list_mcus)
18
+ cli.add_command(cli_download)
19
+ cli.add_command(cli_flash_board)
20
+
21
+ # cli(auto_envvar_prefix="MPFLASH")
22
+ if False and os.environ.get("COMPUTERNAME").startswith("JOSVERL"):
23
+ # intentional less error suppression on dev machine
24
+ result = cli(standalone_mode=False)
25
+ else:
26
+ try:
27
+ result = cli(standalone_mode=True)
28
+ exit(result)
29
+ except AttributeError as e:
30
+ log.error(f"Error: {e}")
31
+ exit(-1)
32
+ except click.exceptions.ClickException as e:
33
+ log.error(f"Error: {e}")
34
+ exit(-2)
35
+ except click.exceptions.Abort as e:
36
+ # Aborted - Ctrl-C
37
+ exit(-3)
38
+
39
+
40
+ if __name__ == "__main__":
41
+ mpflash()
mpflash/common.py CHANGED
@@ -1,164 +1,164 @@
1
- import fnmatch
2
- import os
3
- import sys
4
- from dataclasses import dataclass, field
5
- from enum import Enum
6
- from pathlib import Path
7
- from typing import List, Optional, Union
8
-
9
- from github import Auth, Github
10
- from serial.tools import list_ports
11
- from serial.tools.list_ports_common import ListPortInfo
12
-
13
- from .logger import log
14
-
15
- # from mpflash.mpremoteboard import MPRemoteBoard
16
-
17
- PORT_FWTYPES = {
18
- "stm32": [".dfu"], # need .dfu for pydfu.py - .hex for cube cli/GUI
19
- "esp32": [".bin"],
20
- "esp8266": [".bin"],
21
- "rp2": [".uf2"],
22
- "samd": [".uf2"],
23
- # below this not yet implemented / tested
24
- "mimxrt": [".hex"],
25
- "nrf": [".uf2"],
26
- "renesas-ra": [".hex"],
27
- }
28
-
29
- # Token with no permissions to avoid throttling
30
- # 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
31
- PAT_NO_ACCESS = (
32
- "github_pat" + "_11AAHPVFQ0qAkDnSUaMKSp" + "_ZkDl5NRRwBsUN6EYg9ahp1Dvj4FDDONnXVgimxC2EtpY7Q7BUKBoQ0Jq72X"
33
- )
34
- PAT = os.environ.get("GITHUB_TOKEN") or PAT_NO_ACCESS
35
- GH_CLIENT = Github(auth=Auth.Token(PAT))
36
-
37
-
38
- @dataclass
39
- class FWInfo:
40
- """
41
- Downloaded Firmware information
42
- is somewhat related to the BOARD class in the mpboard_id module
43
- """
44
-
45
- port: str # MicroPython port
46
- board: str # MicroPython board
47
- filename: str = field(default="") # relative filename of the firmware image
48
- firmware: str = field(default="") # url or path to original firmware image
49
- variant: str = field(default="") # MicroPython variant
50
- preview: bool = field(default=False) # True if the firmware is a preview version
51
- version: str = field(default="") # MicroPython version (NO v prefix)
52
- url: str = field(default="") # url to the firmware image download folder
53
- build: str = field(default="0") # The build = number of commits since the last release
54
- ext: str = field(default="") # the file extension of the firmware
55
- family: str = field(default="micropython") # The family of the firmware
56
- custom: bool = field(default=False) # True if the firmware is a custom build
57
- description: str = field(default="") # Description used by this firmware (custom only)
58
-
59
- def to_dict(self) -> dict:
60
- """Convert the object to a dictionary"""
61
- return self.__dict__
62
-
63
- @classmethod
64
- def from_dict(cls, data: dict) -> "FWInfo":
65
- """Create a FWInfo object from a dictionary"""
66
- # add missing keys
67
- if "ext" not in data:
68
- data["ext"] = Path(data["firmware"]).suffix
69
- if "family" not in data:
70
- data["family"] = "micropython"
71
- return cls(**data)
72
-
73
-
74
- @dataclass
75
- class Params:
76
- """Common parameters for downloading and flashing firmware"""
77
-
78
- ports: List[str] = field(default_factory=list)
79
- boards: List[str] = field(default_factory=list)
80
- versions: List[str] = field(default_factory=list)
81
- fw_folder: Path = Path()
82
- serial: List[str] = field(default_factory=list)
83
- ignore: List[str] = field(default_factory=list)
84
-
85
-
86
- @dataclass
87
- class DownloadParams(Params):
88
- """Parameters for downloading firmware"""
89
-
90
- clean: bool = False
91
- force: bool = False
92
-
93
-
94
- class BootloaderMethod(Enum):
95
- MANUAL = "manual"
96
- MPY = "mpy"
97
- TOUCH_1200 = "touch1200"
98
- NONE = "none"
99
-
100
-
101
-
102
- @dataclass
103
- class FlashParams(Params):
104
- """Parameters for flashing a board"""
105
-
106
- erase: bool = True
107
- bootloader: BootloaderMethod = BootloaderMethod.NONE
108
- cpu: str = ""
109
-
110
- def __post_init__(self):
111
- if isinstance(self.bootloader, str):
112
- self.bootloader = BootloaderMethod(self.bootloader)
113
-
114
-
115
- ParamType = Union[DownloadParams, FlashParams]
116
-
117
-
118
- def filtered_comports(
119
- ignore: Optional[List[str]] = None,
120
- include: Optional[List[str]] = None,
121
- bluetooth: bool = False,
122
- ) -> List[ListPortInfo]: # sourcery skip: assign-if-exp
123
- """
124
- Get a list of filtered comports.
125
- """
126
- if not ignore:
127
- ignore = []
128
- elif not isinstance(ignore, list): # type: ignore
129
- ignore = list(ignore)
130
- if not include:
131
- include = ["*"]
132
- elif not isinstance(include, list): # type: ignore
133
- include = list(include)
134
-
135
- # remove ports that are to be ignored
136
- log.trace(f"{include=}, {ignore=}, {bluetooth=}")
137
- comports = [p for p in list_ports.comports() if not any(fnmatch.fnmatch(p.device, i) for i in ignore)]
138
- log.trace(f"comports: {[p.device for p in comports]}")
139
- # remove bluetooth ports
140
-
141
- if include != ["*"]:
142
- # if there are explicit ports to include, add them to the list
143
- explicit = [p for p in list_ports.comports() if any(fnmatch.fnmatch(p.device, i) for i in include)]
144
- log.trace(f"explicit: {[p.device for p in explicit]}")
145
- if ignore == []:
146
- # if nothing to ignore, just use the explicit list as a sinple sane default
147
- comports = explicit
148
- else:
149
- # if there are ports to ignore, add the explicit list to the filtered list
150
- comports = list(set(explicit) | set(comports))
151
- if not bluetooth:
152
- # filter out bluetooth ports
153
- comports = [p for p in comports if "bluetooth" not in p.description.lower()]
154
- comports = [p for p in comports if "BTHENUM" not in p.hwid]
155
- if sys.platform == "darwin":
156
- comports = [p for p in comports if ".Bluetooth" not in p.device]
157
- log.trace(f"no Bluetooth: {[p.device for p in comports]}")
158
- log.debug(f"filtered_comports: {[p.device for p in comports]}")
159
- # sort
160
- if sys.platform == "win32":
161
- # Windows sort of comports by number - but fallback to device name
162
- return sorted(comports, key=lambda x: int(x.device.split()[0][3:]) if x.device.split()[0][3:].isdigit() else x)
163
- # sort by device name
164
- return sorted(comports, key=lambda x: x.device)
1
+ import fnmatch
2
+ import os
3
+ import sys
4
+ from dataclasses import dataclass, field
5
+ from enum import Enum
6
+ from pathlib import Path
7
+ from typing import List, Optional, Union
8
+
9
+ from github import Auth, Github
10
+ from serial.tools import list_ports
11
+ from serial.tools.list_ports_common import ListPortInfo
12
+
13
+ from .logger import log
14
+
15
+ # from mpflash.mpremoteboard import MPRemoteBoard
16
+
17
+ PORT_FWTYPES = {
18
+ "stm32": [".dfu"], # need .dfu for pydfu.py - .hex for cube cli/GUI
19
+ "esp32": [".bin"],
20
+ "esp8266": [".bin"],
21
+ "rp2": [".uf2"],
22
+ "samd": [".uf2"],
23
+ # below this not yet implemented / tested
24
+ "mimxrt": [".hex"],
25
+ "nrf": [".uf2"],
26
+ "renesas-ra": [".hex"],
27
+ }
28
+
29
+ # Token with no permissions to avoid throttling
30
+ # 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
31
+ PAT_NO_ACCESS = (
32
+ "github_pat" + "_11AAHPVFQ0qAkDnSUaMKSp" + "_ZkDl5NRRwBsUN6EYg9ahp1Dvj4FDDONnXVgimxC2EtpY7Q7BUKBoQ0Jq72X"
33
+ )
34
+ PAT = os.environ.get("GITHUB_TOKEN") or PAT_NO_ACCESS
35
+ GH_CLIENT = Github(auth=Auth.Token(PAT))
36
+
37
+
38
+ @dataclass
39
+ class FWInfo:
40
+ """
41
+ Downloaded Firmware information
42
+ is somewhat related to the BOARD class in the mpboard_id module
43
+ """
44
+
45
+ port: str # MicroPython port
46
+ board: str # MicroPython board
47
+ filename: str = field(default="") # relative filename of the firmware image
48
+ firmware: str = field(default="") # url or path to original firmware image
49
+ variant: str = field(default="") # MicroPython variant
50
+ preview: bool = field(default=False) # True if the firmware is a preview version
51
+ version: str = field(default="") # MicroPython version (NO v prefix)
52
+ url: str = field(default="") # url to the firmware image download folder
53
+ build: str = field(default="0") # The build = number of commits since the last release
54
+ ext: str = field(default="") # the file extension of the firmware
55
+ family: str = field(default="micropython") # The family of the firmware
56
+ custom: bool = field(default=False) # True if the firmware is a custom build
57
+ description: str = field(default="") # Description used by this firmware (custom only)
58
+
59
+ def to_dict(self) -> dict:
60
+ """Convert the object to a dictionary"""
61
+ return self.__dict__
62
+
63
+ @classmethod
64
+ def from_dict(cls, data: dict) -> "FWInfo":
65
+ """Create a FWInfo object from a dictionary"""
66
+ # add missing keys
67
+ if "ext" not in data:
68
+ data["ext"] = Path(data["firmware"]).suffix
69
+ if "family" not in data:
70
+ data["family"] = "micropython"
71
+ return cls(**data)
72
+
73
+
74
+ @dataclass
75
+ class Params:
76
+ """Common parameters for downloading and flashing firmware"""
77
+
78
+ ports: List[str] = field(default_factory=list)
79
+ boards: List[str] = field(default_factory=list)
80
+ versions: List[str] = field(default_factory=list)
81
+ fw_folder: Path = Path()
82
+ serial: List[str] = field(default_factory=list)
83
+ ignore: List[str] = field(default_factory=list)
84
+
85
+
86
+ @dataclass
87
+ class DownloadParams(Params):
88
+ """Parameters for downloading firmware"""
89
+
90
+ clean: bool = False
91
+ force: bool = False
92
+
93
+
94
+ class BootloaderMethod(Enum):
95
+ MANUAL = "manual"
96
+ MPY = "mpy"
97
+ TOUCH_1200 = "touch1200"
98
+ NONE = "none"
99
+
100
+
101
+
102
+ @dataclass
103
+ class FlashParams(Params):
104
+ """Parameters for flashing a board"""
105
+
106
+ erase: bool = True
107
+ bootloader: BootloaderMethod = BootloaderMethod.NONE
108
+ cpu: str = ""
109
+
110
+ def __post_init__(self):
111
+ if isinstance(self.bootloader, str):
112
+ self.bootloader = BootloaderMethod(self.bootloader)
113
+
114
+
115
+ ParamType = Union[DownloadParams, FlashParams]
116
+
117
+
118
+ def filtered_comports(
119
+ ignore: Optional[List[str]] = None,
120
+ include: Optional[List[str]] = None,
121
+ bluetooth: bool = False,
122
+ ) -> List[ListPortInfo]: # sourcery skip: assign-if-exp
123
+ """
124
+ Get a list of filtered comports.
125
+ """
126
+ if not ignore:
127
+ ignore = []
128
+ elif not isinstance(ignore, list): # type: ignore
129
+ ignore = list(ignore)
130
+ if not include:
131
+ include = ["*"]
132
+ elif not isinstance(include, list): # type: ignore
133
+ include = list(include)
134
+
135
+ # remove ports that are to be ignored
136
+ log.trace(f"{include=}, {ignore=}, {bluetooth=}")
137
+ comports = [p for p in list_ports.comports() if not any(fnmatch.fnmatch(p.device, i) for i in ignore)]
138
+ log.trace(f"comports: {[p.device for p in comports]}")
139
+ # remove bluetooth ports
140
+
141
+ if include != ["*"]:
142
+ # if there are explicit ports to include, add them to the list
143
+ explicit = [p for p in list_ports.comports() if any(fnmatch.fnmatch(p.device, i) for i in include)]
144
+ log.trace(f"explicit: {[p.device for p in explicit]}")
145
+ if ignore == []:
146
+ # if nothing to ignore, just use the explicit list as a sinple sane default
147
+ comports = explicit
148
+ else:
149
+ # if there are ports to ignore, add the explicit list to the filtered list
150
+ comports = list(set(explicit) | set(comports))
151
+ if not bluetooth:
152
+ # filter out bluetooth ports
153
+ comports = [p for p in comports if "bluetooth" not in p.description.lower()]
154
+ comports = [p for p in comports if "BTHENUM" not in p.hwid]
155
+ if sys.platform == "darwin":
156
+ comports = [p for p in comports if ".Bluetooth" not in p.device]
157
+ log.trace(f"no Bluetooth: {[p.device for p in comports]}")
158
+ log.debug(f"filtered_comports: {[p.device for p in comports]}")
159
+ # sort
160
+ if sys.platform == "win32":
161
+ # Windows sort of comports by number - but fallback to device name
162
+ return sorted(comports, key=lambda x: int(x.device.split()[0][3:]) if x.device.split()[0][3:].isdigit() else x)
163
+ # sort by device name
164
+ return sorted(comports, key=lambda x: x.device)
mpflash/config.py CHANGED
@@ -1,47 +1,47 @@
1
- """centralized configuration for mpflash"""
2
-
3
- import os
4
- from pathlib import Path
5
- from typing import List
6
-
7
- import pkg_resources
8
- import platformdirs
9
-
10
- from mpflash.logger import log
11
-
12
-
13
- def get_version():
14
- name = __package__ or "mpflash"
15
- try:
16
- return pkg_resources.get_distribution(name).version
17
- except pkg_resources.DistributionNotFound:
18
- return "Package not found"
19
-
20
-
21
- class MPtoolConfig:
22
- """Centralized configuration for mpflash"""
23
-
24
- quiet: bool = False
25
- verbose: bool = False
26
- ignore_ports: List[str] = []
27
- firmware_folder: Path = platformdirs.user_downloads_path() / "firmware"
28
- # test options specified on the commandline
29
- tests: List[str] = []
30
- _interactive: bool = True
31
-
32
- @property
33
- def interactive(self):
34
- # No interactions in CI
35
- if os.getenv('GITHUB_ACTIONS') == 'true':
36
- log.warning("Disabling interactive mode in CI")
37
- return False
38
- return self._interactive
39
-
40
- @interactive.setter
41
- def interactive(self, value:bool):
42
- self._interactive = value
43
-
44
-
45
-
46
- config = MPtoolConfig()
47
- __version__ = get_version()
1
+ """centralized configuration for mpflash"""
2
+
3
+ import os
4
+ from pathlib import Path
5
+ from typing import List
6
+
7
+ import pkg_resources
8
+ import platformdirs
9
+
10
+ from mpflash.logger import log
11
+
12
+
13
+ def get_version():
14
+ name = __package__ or "mpflash"
15
+ try:
16
+ return pkg_resources.get_distribution(name).version
17
+ except pkg_resources.DistributionNotFound:
18
+ return "Package not found"
19
+
20
+
21
+ class MPtoolConfig:
22
+ """Centralized configuration for mpflash"""
23
+
24
+ quiet: bool = False
25
+ verbose: bool = False
26
+ ignore_ports: List[str] = []
27
+ firmware_folder: Path = platformdirs.user_downloads_path() / "firmware"
28
+ # test options specified on the commandline
29
+ tests: List[str] = []
30
+ _interactive: bool = True
31
+
32
+ @property
33
+ def interactive(self):
34
+ # No interactions in CI
35
+ if os.getenv('GITHUB_ACTIONS') == 'true':
36
+ log.warning("Disabling interactive mode in CI")
37
+ return False
38
+ return self._interactive
39
+
40
+ @interactive.setter
41
+ def interactive(self, value:bool):
42
+ self._interactive = value
43
+
44
+
45
+
46
+ config = MPtoolConfig()
47
+ __version__ = get_version()