tools/mpremote: Allow user configuration on Windows.

Signed-off-by: Jos Verlinde <jos_verlinde@hotmail.com>
pull/9573/head
Jos Verlinde 2023-11-27 18:07:43 +01:00
rodzic 2db0d9a4ae
commit b52cf9e277
2 zmienionych plików z 43 dodań i 26 usunięć

Wyświetl plik

@ -107,7 +107,7 @@ The full list of supported commands are:
**Note:** Instead of using the ``connect`` command, there are several
:ref:`pre-defined shortcuts <mpremote_shortcuts>` for common device paths. For
example the ``a0`` shortcut command is equivalent to
``connect /dev/ttyACM0`` (Linux), or ``c0`` for ``COM0`` (Windows).
``connect /dev/ttyACM0`` (Linux), or ``c1`` for ``COM1`` (Windows).
**Note:** The ``auto`` option will only detect USB serial ports, i.e. a serial
port that has an associated USB VID/PID (i.e. CDC/ACM or FTDI-style
@ -429,12 +429,14 @@ Shortcuts can be defined using the macro system. Built-in shortcuts are:
- ``cat``, ``edit``, ``ls``, ``cp``, ``rm``, ``mkdir``, ``rmdir``, ``touch``: Aliases for ``fs <sub-command>``
Additional shortcuts can be defined by in user-configuration files, which is
located at ``.config/mpremote/config.py`` relative to the ``XDG_CONFIG_HOME`` or ``HOME`` environment variable on unix systems
, or on Windows relative to ``HOME``, ``USERPROFILE`` or ``APPDATA``.
Additional shortcuts can be defined by in the user configuration file ``mpremote/config.py``, located in:
# ``$XDG_CONFIG_HOME/mpremote/config.py``
# ``$HOME/.config/mpremote/config.py``
# ``%APPDATA%/mpremote/config.py``
# ``%USERPROFILE%/mpremote/config.py``
searched in that order on all platforms.
For example:
This file should define a dictionary named ``commands``. The keys of this dictionary are the shortcuts
This file should define a dictionary named ``commands``. The keys of this dictionary are the shortcuts
and the values are either a string or a list-of-strings:
.. code-block:: python3

Wyświetl plik

@ -61,7 +61,9 @@ def do_help(state, _args=None):
print("See https://docs.micropython.org/en/latest/reference/mpremote.html")
print("\nList of commands:")
print_commands_help(_COMMANDS, lambda x: x[1]().description) # extract description from argparse
print_commands_help(
_COMMANDS, lambda x: x[1]().description
) # extract description from argparse
print("\nList of shortcuts:")
print_commands_help(_command_expansions, lambda x: x[2]) # (args, sub, help_message)
@ -95,7 +97,9 @@ def _bool_flag(cmd_parser, name, short_name, default, description):
def argparse_connect():
cmd_parser = argparse.ArgumentParser(description="connect to given device")
cmd_parser.add_argument("device", nargs=1, help="Either list, auto, id:x, port:x, or any valid device name/path")
cmd_parser.add_argument(
"device", nargs=1, help="Either list, auto, id:x, port:x, or any valid device name/path"
)
return cmd_parser
@ -133,7 +137,9 @@ def argparse_repl():
required=False,
help="saves a copy of the REPL session to the specified path",
)
cmd_parser.add_argument("--inject-code", type=str, required=False, help="code to be run when Ctrl-J is pressed")
cmd_parser.add_argument(
"--inject-code", type=str, required=False, help="code to be run when Ctrl-J is pressed"
)
cmd_parser.add_argument(
"--inject-file",
type=str,
@ -151,14 +157,18 @@ def argparse_eval():
def argparse_exec():
cmd_parser = argparse.ArgumentParser(description="execute the string")
_bool_flag(cmd_parser, "follow", "f", True, "follow output until the expression completes (default)")
_bool_flag(
cmd_parser, "follow", "f", True, "follow output until the expression completes (default)"
)
cmd_parser.add_argument("expr", nargs=1, help="expression to execute")
return cmd_parser
def argparse_run():
cmd_parser = argparse.ArgumentParser(description="run the given local script")
_bool_flag(cmd_parser, "follow", "f", True, "follow output until the script completes (default)")
_bool_flag(
cmd_parser, "follow", "f", True, "follow output until the script completes (default)"
)
cmd_parser.add_argument("path", nargs=1, help="path to script to execute")
return cmd_parser
@ -179,15 +189,21 @@ def argparse_filesystem():
None,
"enable verbose output (defaults to True for all commands except cat)",
)
cmd_parser.add_argument("command", nargs=1, help="filesystem command (e.g. cat, cp, ls, rm, touch)")
cmd_parser.add_argument(
"command", nargs=1, help="filesystem command (e.g. cat, cp, ls, rm, touch)"
)
cmd_parser.add_argument("path", nargs="+", help="local and remote paths")
return cmd_parser
def argparse_mip():
cmd_parser = argparse.ArgumentParser(description="install packages from micropython-lib or third-party sources")
cmd_parser = argparse.ArgumentParser(
description="install packages from micropython-lib or third-party sources"
)
_bool_flag(cmd_parser, "mpy", "m", True, "download as compiled .mpy files (default)")
cmd_parser.add_argument("--target", type=str, required=False, help="destination direction on the device")
cmd_parser.add_argument(
"--target", type=str, required=False, help="destination direction on the device"
)
cmd_parser.add_argument(
"--index",
type=str,
@ -330,10 +346,10 @@ _BUILTIN_COMMAND_EXPANSIONS = {
for port_num in range(4):
for prefix, port in [("a", "/dev/ttyACM"), ("u", "/dev/ttyUSB"), ("c", "COM")]:
if port_num == 0 and port == "COM":
continue # skip COM0 as it does not exist
_BUILTIN_COMMAND_EXPANSIONS[f"{prefix}{port_num}"] = {
"command": f"connect {port}{port_num}",
"help": f'connect to serial port "{port}{port_num}"',
continue # skip COM0 as it does not exist on Windows
_BUILTIN_COMMAND_EXPANSIONS["{}{}".format(prefix, port_num)] = {
"command": "connect {}{}".format(port, port_num),
"help": 'connect to serial port "{}{}"'.format(port, port_num),
}
@ -341,25 +357,22 @@ def load_user_config():
# Create empty config object.
config = __build_class__(lambda: None, "Config")()
config.commands = {}
# use $XDG_CONFIG_HOME,$HOME $env:USERPROFILE% or $env:APPDATA
path = None
for env_var in ("XDG_CONFIG_HOME", "HOME", "USERPROFILE", "APPDATA"):
for env_var in ("XDG_CONFIG_HOME", "HOME", "APPDATA", "USERPROFILE"):
path = os.getenv(env_var)
if not path:
continue
if os.path.exists(os.path.join(path, ".config", _PROG, "config.py")):
if env_var == "HOME" and os.path.exists(os.path.join(path, ".config", _PROG, "config.py")):
# Unix style
path = os.path.join(path, ".config", _PROG, "config.py")
path = os.path.join(path, ".config", _PROG)
break
elif os.path.exists(os.path.join(path, _PROG, "config.py")):
# Windows style
path = os.path.join(path, _PROG, "config.py")
path = os.path.join(path, _PROG)
break
if not path:
return config
config_file = os.path.join(path, "config.py")
# Check if config file exists.
if not os.path.exists(config_file):
return config
@ -514,7 +527,9 @@ def main():
cmd_parser = parser_func()
cmd_parser.prog = cmd
# Catch all for unhandled positional arguments (this is the next command).
cmd_parser.add_argument("next_command", nargs=argparse.REMAINDER, help=f"Next {_PROG} command")
cmd_parser.add_argument(
"next_command", nargs=argparse.REMAINDER, help=f"Next {_PROG} command"
)
args = cmd_parser.parse_args(command_args)
# Execute command.