mposcli 0.1.0__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.
- mposcli/__init__.py +8 -0
- mposcli/__main__.py +10 -0
- mposcli/cli_app/__init__.py +41 -0
- mposcli/cli_app/build.py +46 -0
- mposcli/cli_app/run_deskop.py +105 -0
- mposcli/cli_app/update.py +35 -0
- mposcli/cli_dev/__init__.py +70 -0
- mposcli/cli_dev/__main__.py +10 -0
- mposcli/cli_dev/code_style.py +12 -0
- mposcli/cli_dev/packaging.py +62 -0
- mposcli/cli_dev/shell_completion.py +23 -0
- mposcli/cli_dev/testing.py +52 -0
- mposcli/cli_dev/update_readme_history.py +33 -0
- mposcli/constants.py +8 -0
- mposcli/fs_utils.py +6 -0
- mposcli/mpos_utils.py +28 -0
- mposcli/tests/__init__.py +36 -0
- mposcli/tests/test_doctests.py +10 -0
- mposcli/tests/test_project_setup.py +46 -0
- mposcli/tests/test_readme.py +88 -0
- mposcli/tests/test_readme_history.py +9 -0
- mposcli/user_input.py +37 -0
- mposcli-0.1.0.dist-info/METADATA +178 -0
- mposcli-0.1.0.dist-info/RECORD +26 -0
- mposcli-0.1.0.dist-info/WHEEL +4 -0
- mposcli-0.1.0.dist-info/entry_points.txt +2 -0
mposcli/__init__.py
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"""
|
|
2
|
+
mposcli
|
|
3
|
+
CLI helper for MicroPythonOS: https://github.com/MicroPythonOS/MicroPythonOS
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
# See https://packaging.python.org/en/latest/specifications/version-specifiers/
|
|
7
|
+
__version__ = '0.1.0'
|
|
8
|
+
__author__ = 'Jens Diemer <cookiecutter_templates@jensdiemer.de>'
|
mposcli/__main__.py
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"""
|
|
2
|
+
CLI for usage
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import logging
|
|
6
|
+
import sys
|
|
7
|
+
from collections.abc import Sequence
|
|
8
|
+
|
|
9
|
+
from cli_base.autodiscover import import_all_files
|
|
10
|
+
from cli_base.cli_tools.version_info import print_version
|
|
11
|
+
from rich import print # noqa
|
|
12
|
+
from tyro.extras import SubcommandApp
|
|
13
|
+
|
|
14
|
+
import mposcli
|
|
15
|
+
from mposcli import constants
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
logger = logging.getLogger(__name__)
|
|
19
|
+
|
|
20
|
+
app = SubcommandApp()
|
|
21
|
+
|
|
22
|
+
# Register all CLI commands, just by import all files in this package:
|
|
23
|
+
import_all_files(package=__package__, init_file=__file__)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@app.command
|
|
27
|
+
def version():
|
|
28
|
+
"""Print version and exit"""
|
|
29
|
+
# Pseudo command, because the version always printed on every CLI call ;)
|
|
30
|
+
sys.exit(0)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def main(args: Sequence[str] | None = None):
|
|
34
|
+
print_version(mposcli)
|
|
35
|
+
app.cli(
|
|
36
|
+
prog='mposcli', # Enforce "pipx" usage
|
|
37
|
+
description=constants.CLI_EPILOG,
|
|
38
|
+
use_underscores=False, # use hyphens instead of underscores
|
|
39
|
+
sort_subcommands=True,
|
|
40
|
+
args=args,
|
|
41
|
+
)
|
mposcli/cli_app/build.py
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from typing import Annotated, Literal
|
|
3
|
+
|
|
4
|
+
import tyro
|
|
5
|
+
from bx_py_utils.path import assert_is_file
|
|
6
|
+
from cli_base.cli_tools.subprocess_utils import verbose_check_call
|
|
7
|
+
from cli_base.cli_tools.verbosity import setup_logging
|
|
8
|
+
from cli_base.tyro_commands import TyroVerbosityArgType
|
|
9
|
+
from rich import print # noqa
|
|
10
|
+
|
|
11
|
+
from mposcli.cli_app import app
|
|
12
|
+
from mposcli.mpos_utils import get_mpos_path
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
logger = logging.getLogger(__name__)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@app.command
|
|
19
|
+
def build(
|
|
20
|
+
target: Annotated[
|
|
21
|
+
Literal['esp32', 'esp32s3', 'unix', 'macOS'],
|
|
22
|
+
tyro.conf.arg(
|
|
23
|
+
help='Target platform to build for.',
|
|
24
|
+
),
|
|
25
|
+
] = 'unix',
|
|
26
|
+
verbosity: TyroVerbosityArgType = 1,
|
|
27
|
+
):
|
|
28
|
+
"""
|
|
29
|
+
Build MicroPythonOS by calling: ./scripts/build_mpos.sh <target>
|
|
30
|
+
see: https://docs.micropythonos.com/os-development/
|
|
31
|
+
"""
|
|
32
|
+
setup_logging(verbosity=verbosity)
|
|
33
|
+
|
|
34
|
+
mpos_path = get_mpos_path()
|
|
35
|
+
|
|
36
|
+
script_path = mpos_path / 'scripts' / 'build_mpos.sh'
|
|
37
|
+
assert_is_file(script_path)
|
|
38
|
+
|
|
39
|
+
verbose_check_call(
|
|
40
|
+
script_path,
|
|
41
|
+
target,
|
|
42
|
+
verbose=True,
|
|
43
|
+
cwd=mpos_path,
|
|
44
|
+
timeout=None,
|
|
45
|
+
text=None,
|
|
46
|
+
)
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import logging
|
|
3
|
+
import os
|
|
4
|
+
import sys
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from typing import Annotated
|
|
7
|
+
|
|
8
|
+
import tyro
|
|
9
|
+
from bx_py_utils.path import assert_is_file
|
|
10
|
+
from cli_base.cli_tools.subprocess_utils import verbose_check_call
|
|
11
|
+
from cli_base.cli_tools.verbosity import setup_logging
|
|
12
|
+
from cli_base.tyro_commands import TyroVerbosityArgType
|
|
13
|
+
from rich import print # noqa
|
|
14
|
+
|
|
15
|
+
from mposcli.cli_app import app
|
|
16
|
+
from mposcli.fs_utils import list_executables
|
|
17
|
+
from mposcli.mpos_utils import get_mpos_path
|
|
18
|
+
from mposcli.user_input import file_chooser
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
logger = logging.getLogger(__name__)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@app.command
|
|
25
|
+
def run_desktop(
|
|
26
|
+
heapsize: Annotated[
|
|
27
|
+
int,
|
|
28
|
+
tyro.conf.arg(
|
|
29
|
+
help='Heap size in MB (default: 8, same as PSRAM on many ESP32-S3 boards)',
|
|
30
|
+
),
|
|
31
|
+
] = 8,
|
|
32
|
+
script: Annotated[
|
|
33
|
+
str | None,
|
|
34
|
+
tyro.conf.arg(help='Script file (.py) or app name to run. If omitted, starts normally.'),
|
|
35
|
+
] = None,
|
|
36
|
+
binary: Annotated[
|
|
37
|
+
str | None,
|
|
38
|
+
tyro.conf.arg(
|
|
39
|
+
help='Optional name of the binary to start.'
|
|
40
|
+
' If omitted, shows a file chooser to select one from the lvgl_micropython build directory.'
|
|
41
|
+
),
|
|
42
|
+
] = None,
|
|
43
|
+
verbosity: TyroVerbosityArgType = 1,
|
|
44
|
+
):
|
|
45
|
+
"""
|
|
46
|
+
Run MicroPythonOS on desktop.
|
|
47
|
+
see: https://docs.micropythonos.com/getting-started/running/#running-on-desktop
|
|
48
|
+
"""
|
|
49
|
+
setup_logging(verbosity=verbosity)
|
|
50
|
+
|
|
51
|
+
mpos_path = get_mpos_path()
|
|
52
|
+
|
|
53
|
+
internal_fs = mpos_path / 'internal_filesystem'
|
|
54
|
+
lvgl_micropython_build_path = mpos_path / 'lvgl_micropython' / 'build'
|
|
55
|
+
|
|
56
|
+
executables = list_executables(lvgl_micropython_build_path)
|
|
57
|
+
if not executables:
|
|
58
|
+
print(f'Error: No executable found in {lvgl_micropython_build_path}.')
|
|
59
|
+
print('Hint: Download or build the lvgl_micropython binary first.')
|
|
60
|
+
print('Hint 2: Forgotten to make the binary executable? e.g.: chmod +x <binary>')
|
|
61
|
+
sys.exit(1)
|
|
62
|
+
|
|
63
|
+
if binary:
|
|
64
|
+
binary = lvgl_micropython_build_path / binary
|
|
65
|
+
else:
|
|
66
|
+
binary = file_chooser(executables)
|
|
67
|
+
assert_is_file(binary)
|
|
68
|
+
|
|
69
|
+
os.environ['HEAPSIZE'] = f'{heapsize}M'
|
|
70
|
+
|
|
71
|
+
# Change to internal_filesystem dir
|
|
72
|
+
os.chdir(internal_fs)
|
|
73
|
+
|
|
74
|
+
popenargs = [binary]
|
|
75
|
+
|
|
76
|
+
if script and script.endswith('.py') and Path(script).is_file():
|
|
77
|
+
# Run script file directly
|
|
78
|
+
script_path = str(Path(script).resolve())
|
|
79
|
+
popenargs += ('-v', '-i', script_path)
|
|
80
|
+
else:
|
|
81
|
+
if script:
|
|
82
|
+
# Treat as app name
|
|
83
|
+
config_file = Path('data/com.micropythonos.settings/config.json')
|
|
84
|
+
config_file.parent.mkdir(parents=True, exist_ok=True)
|
|
85
|
+
if config_file.exists():
|
|
86
|
+
with config_file.open('r', encoding='utf-8') as f:
|
|
87
|
+
try:
|
|
88
|
+
config = json.load(f)
|
|
89
|
+
except Exception:
|
|
90
|
+
config = {}
|
|
91
|
+
else:
|
|
92
|
+
config = {}
|
|
93
|
+
config['auto_start_app'] = script
|
|
94
|
+
with config_file.open('w', encoding='utf-8') as f:
|
|
95
|
+
json.dump(config, f)
|
|
96
|
+
popenargs += ('-X', f'heapsize={os.environ["HEAPSIZE"]}', '-v', '-i', '-c', Path('main.py').read_text())
|
|
97
|
+
|
|
98
|
+
verbose_check_call(
|
|
99
|
+
*popenargs,
|
|
100
|
+
env=os.environ,
|
|
101
|
+
verbose=True,
|
|
102
|
+
cwd=internal_fs,
|
|
103
|
+
timeout=None,
|
|
104
|
+
text=None,
|
|
105
|
+
)
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
|
|
3
|
+
from cli_base.cli_tools.subprocess_utils import verbose_check_call
|
|
4
|
+
from cli_base.cli_tools.verbosity import setup_logging
|
|
5
|
+
from cli_base.tyro_commands import TyroVerbosityArgType
|
|
6
|
+
from rich import print # noqa
|
|
7
|
+
|
|
8
|
+
from mposcli.cli_app import app
|
|
9
|
+
from mposcli.mpos_utils import get_mpos_path
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
logger = logging.getLogger(__name__)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@app.command
|
|
16
|
+
def update_submodules(verbosity: TyroVerbosityArgType = 1):
|
|
17
|
+
"""
|
|
18
|
+
Update MicroPythonOS repository and all submodules
|
|
19
|
+
see: https://docs.micropythonos.com/os-development/linux/#optional-updating-the-code
|
|
20
|
+
"""
|
|
21
|
+
setup_logging(verbosity=verbosity)
|
|
22
|
+
mpos_path = get_mpos_path()
|
|
23
|
+
|
|
24
|
+
commands = (
|
|
25
|
+
('git', 'submodule', 'foreach', '--recursive', 'git', 'clean', '-f', ';', 'git', 'checkout', '.'),
|
|
26
|
+
('git', 'pull', '--recurse-submodules'),
|
|
27
|
+
)
|
|
28
|
+
for popenargs in commands:
|
|
29
|
+
verbose_check_call(
|
|
30
|
+
*popenargs,
|
|
31
|
+
verbose=True,
|
|
32
|
+
cwd=mpos_path,
|
|
33
|
+
timeout=None,
|
|
34
|
+
text=None,
|
|
35
|
+
)
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"""
|
|
2
|
+
CLI for development
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import importlib
|
|
6
|
+
import logging
|
|
7
|
+
import sys
|
|
8
|
+
from collections.abc import Sequence
|
|
9
|
+
|
|
10
|
+
from bx_py_utils.path import assert_is_file
|
|
11
|
+
from cli_base.autodiscover import import_all_files
|
|
12
|
+
from cli_base.cli_tools.dev_tools import run_coverage, run_nox, run_unittest_cli
|
|
13
|
+
from cli_base.cli_tools.version_info import print_version
|
|
14
|
+
from typeguard import install_import_hook
|
|
15
|
+
from tyro.extras import SubcommandApp
|
|
16
|
+
|
|
17
|
+
import mposcli
|
|
18
|
+
from mposcli import constants
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
# Check type annotations via typeguard in all tests.
|
|
22
|
+
# Sadly we must activate this here and can't do this in ./tests/__init__.py
|
|
23
|
+
install_import_hook(packages=('mposcli',))
|
|
24
|
+
|
|
25
|
+
# reload the module, after the typeguard import hook is activated:
|
|
26
|
+
importlib.reload(mposcli)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
logger = logging.getLogger(__name__)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
PACKAGE_ROOT = constants.BASE_PATH.parent
|
|
33
|
+
assert_is_file(PACKAGE_ROOT / 'pyproject.toml') # Exists only in cloned git repo
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
app = SubcommandApp()
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
# Register all CLI commands, just by import all files in this package:
|
|
40
|
+
import_all_files(package=__package__, init_file=__file__)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
@app.command
|
|
44
|
+
def version():
|
|
45
|
+
"""Print version and exit"""
|
|
46
|
+
# Pseudo command, because the version always printed on every CLI call ;)
|
|
47
|
+
sys.exit(0)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def main(args: Sequence[str] | None = None):
|
|
51
|
+
print_version(mposcli)
|
|
52
|
+
|
|
53
|
+
if len(sys.argv) >= 2:
|
|
54
|
+
# Check if we can just pass a command call to origin CLI:
|
|
55
|
+
command = sys.argv[1]
|
|
56
|
+
command_map = {
|
|
57
|
+
'test': run_unittest_cli,
|
|
58
|
+
'nox': run_nox,
|
|
59
|
+
'coverage': run_coverage,
|
|
60
|
+
}
|
|
61
|
+
if real_func := command_map.get(command):
|
|
62
|
+
real_func(argv=sys.argv, exit_after_run=True)
|
|
63
|
+
|
|
64
|
+
app.cli(
|
|
65
|
+
prog='./dev-cli.py',
|
|
66
|
+
description=constants.CLI_EPILOG,
|
|
67
|
+
use_underscores=False, # use hyphens instead of underscores
|
|
68
|
+
sort_subcommands=True,
|
|
69
|
+
args=args,
|
|
70
|
+
)
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
from cli_base.cli_tools.code_style import assert_code_style
|
|
2
|
+
from cli_base.tyro_commands import TyroVerbosityArgType
|
|
3
|
+
|
|
4
|
+
from mposcli.cli_dev import PACKAGE_ROOT, app
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
@app.command
|
|
8
|
+
def lint(verbosity: TyroVerbosityArgType = 1):
|
|
9
|
+
"""
|
|
10
|
+
Check/fix code style by run: "ruff check --fix"
|
|
11
|
+
"""
|
|
12
|
+
assert_code_style(package_root=PACKAGE_ROOT, verbose=bool(verbosity), sys_exit=True)
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
|
|
3
|
+
from cli_base.cli_tools.dev_tools import run_unittest_cli
|
|
4
|
+
from cli_base.cli_tools.subprocess_utils import ToolsExecutor
|
|
5
|
+
from cli_base.cli_tools.verbosity import setup_logging
|
|
6
|
+
from cli_base.run_pip_audit import run_pip_audit
|
|
7
|
+
from cli_base.tyro_commands import TyroVerbosityArgType
|
|
8
|
+
from manageprojects.utilities.publish import publish_package
|
|
9
|
+
|
|
10
|
+
import mposcli
|
|
11
|
+
from mposcli.cli_dev import PACKAGE_ROOT, app
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
logger = logging.getLogger(__name__)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@app.command
|
|
18
|
+
def install():
|
|
19
|
+
"""
|
|
20
|
+
Install requirements and 'mposcli' via pip as editable.
|
|
21
|
+
"""
|
|
22
|
+
tools_executor = ToolsExecutor(cwd=PACKAGE_ROOT)
|
|
23
|
+
tools_executor.verbose_check_call('uv', 'sync')
|
|
24
|
+
tools_executor.verbose_check_call('uv', 'pip', 'install', '--no-deps', '-e', '.')
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@app.command
|
|
28
|
+
def pip_audit(verbosity: TyroVerbosityArgType):
|
|
29
|
+
"""
|
|
30
|
+
Run pip-audit check against current requirements files
|
|
31
|
+
"""
|
|
32
|
+
setup_logging(verbosity=verbosity)
|
|
33
|
+
run_pip_audit(base_path=PACKAGE_ROOT, verbosity=verbosity)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
@app.command
|
|
37
|
+
def update(verbosity: TyroVerbosityArgType):
|
|
38
|
+
"""
|
|
39
|
+
Update dependencies (uv.lock) and git pre-commit hooks
|
|
40
|
+
"""
|
|
41
|
+
setup_logging(verbosity=verbosity)
|
|
42
|
+
|
|
43
|
+
tools_executor = ToolsExecutor(cwd=PACKAGE_ROOT)
|
|
44
|
+
tools_executor.verbose_check_call('uv', 'lock', '--upgrade')
|
|
45
|
+
|
|
46
|
+
run_pip_audit(base_path=PACKAGE_ROOT, verbosity=verbosity)
|
|
47
|
+
|
|
48
|
+
# Install new dependencies in current .venv:
|
|
49
|
+
tools_executor.verbose_check_call('uv', 'sync')
|
|
50
|
+
|
|
51
|
+
# Update git pre-commit hooks:
|
|
52
|
+
tools_executor.verbose_check_call('pre-commit', 'autoupdate')
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
@app.command
|
|
56
|
+
def publish():
|
|
57
|
+
"""
|
|
58
|
+
Build and upload this project to PyPi
|
|
59
|
+
"""
|
|
60
|
+
run_unittest_cli(verbose=False, exit_after_run=False) # Don't publish a broken state
|
|
61
|
+
|
|
62
|
+
publish_package(module=mposcli, package_path=PACKAGE_ROOT)
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
|
|
3
|
+
from cli_base.cli_tools.shell_completion import setup_tyro_shell_completion
|
|
4
|
+
from cli_base.cli_tools.verbosity import setup_logging
|
|
5
|
+
from cli_base.tyro_commands import TyroVerbosityArgType
|
|
6
|
+
from rich import print # noqa
|
|
7
|
+
|
|
8
|
+
from mposcli.cli_dev import app
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
logger = logging.getLogger(__name__)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@app.command
|
|
15
|
+
def shell_completion(verbosity: TyroVerbosityArgType = 1, remove: bool = False) -> None:
|
|
16
|
+
"""
|
|
17
|
+
Setup shell completion for this CLI (Currently only for bash shell)
|
|
18
|
+
"""
|
|
19
|
+
setup_logging(verbosity=verbosity)
|
|
20
|
+
setup_tyro_shell_completion(
|
|
21
|
+
prog_name='mposcli_dev_cli',
|
|
22
|
+
remove=remove,
|
|
23
|
+
)
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
from cli_base.cli_tools.dev_tools import run_coverage, run_nox, run_unittest_cli
|
|
2
|
+
from cli_base.cli_tools.subprocess_utils import verbose_check_call
|
|
3
|
+
from cli_base.cli_tools.test_utils.snapshot import UpdateTestSnapshotFiles
|
|
4
|
+
from cli_base.tyro_commands import TyroVerbosityArgType
|
|
5
|
+
|
|
6
|
+
from mposcli.cli_dev import PACKAGE_ROOT, app
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@app.command
|
|
10
|
+
def mypy(verbosity: TyroVerbosityArgType):
|
|
11
|
+
"""Run Mypy (configured in pyproject.toml)"""
|
|
12
|
+
verbose_check_call('mypy', '.', cwd=PACKAGE_ROOT, verbose=verbosity > 0, exit_on_error=True)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@app.command
|
|
16
|
+
def update_test_snapshot_files(verbosity: TyroVerbosityArgType):
|
|
17
|
+
"""
|
|
18
|
+
Update all test snapshot files (by remove and recreate all snapshot files)
|
|
19
|
+
"""
|
|
20
|
+
with UpdateTestSnapshotFiles(root_path=PACKAGE_ROOT, verbose=verbosity > 0):
|
|
21
|
+
# Just recreate them by running tests:
|
|
22
|
+
run_unittest_cli(
|
|
23
|
+
extra_env=dict(
|
|
24
|
+
RAISE_SNAPSHOT_ERRORS='0', # Recreate snapshot files without error
|
|
25
|
+
),
|
|
26
|
+
verbose=verbosity > 1,
|
|
27
|
+
exit_after_run=False,
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
@app.command # Dummy command
|
|
32
|
+
def test():
|
|
33
|
+
"""
|
|
34
|
+
Run unittests
|
|
35
|
+
"""
|
|
36
|
+
run_unittest_cli()
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
@app.command # Dummy command
|
|
40
|
+
def coverage():
|
|
41
|
+
"""
|
|
42
|
+
Run tests and show coverage report.
|
|
43
|
+
"""
|
|
44
|
+
run_coverage()
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
@app.command # Dummy "nox" command
|
|
48
|
+
def nox():
|
|
49
|
+
"""
|
|
50
|
+
Run nox
|
|
51
|
+
"""
|
|
52
|
+
run_nox()
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import sys
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
from cli_base.cli_tools import git_history
|
|
6
|
+
from cli_base.cli_tools.verbosity import setup_logging
|
|
7
|
+
from cli_base.tyro_commands import TyroVerbosityArgType
|
|
8
|
+
from rich import print # noqa
|
|
9
|
+
|
|
10
|
+
from mposcli.cli_dev import app
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
logger = logging.getLogger(__name__)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@app.command
|
|
17
|
+
def update_readme_history(verbosity: TyroVerbosityArgType):
|
|
18
|
+
"""
|
|
19
|
+
Update project history base on git commits/tags in README.md
|
|
20
|
+
|
|
21
|
+
Will be exited with 1 if the README.md was updated otherwise with 0.
|
|
22
|
+
|
|
23
|
+
Also, callable via e.g.:
|
|
24
|
+
python -m cli_base update-readme-history -v
|
|
25
|
+
"""
|
|
26
|
+
setup_logging(verbosity=verbosity)
|
|
27
|
+
|
|
28
|
+
logger.debug('%s called. CWD: %s', __name__, Path.cwd())
|
|
29
|
+
updated = git_history.update_readme_history(verbosity=verbosity)
|
|
30
|
+
exit_code = 1 if updated else 0
|
|
31
|
+
if verbosity:
|
|
32
|
+
print(f'{exit_code=}')
|
|
33
|
+
sys.exit(exit_code)
|
mposcli/constants.py
ADDED
mposcli/fs_utils.py
ADDED
mposcli/mpos_utils.py
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import sys
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
from rich import print # noqa
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
logger = logging.getLogger(__name__)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def get_mpos_path() -> Path:
|
|
12
|
+
"""
|
|
13
|
+
Get the path to the MicroPythonOS project root directory.
|
|
14
|
+
Assume that mposcli is only called from the root directory of a MicroPythonOS project.
|
|
15
|
+
"""
|
|
16
|
+
current_path = Path().cwd().resolve()
|
|
17
|
+
logger.info('Current working directory: %s', current_path)
|
|
18
|
+
|
|
19
|
+
for dir_name in ('internal_filesystem', Path('lvgl_micropython', 'build')):
|
|
20
|
+
dir_path = current_path / dir_name
|
|
21
|
+
logger.debug('Checking for directory: %s', dir_path)
|
|
22
|
+
if not dir_path.is_dir():
|
|
23
|
+
print(f"Error: Directory '{dir_name}' not found in {current_path}.")
|
|
24
|
+
print('Hint: Call "mposcli" only in the root directory of a MicroPythonOS project!')
|
|
25
|
+
sys.exit(1)
|
|
26
|
+
|
|
27
|
+
mpos_path = current_path
|
|
28
|
+
return mpos_path
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import unittest.util
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
from bx_py_utils.test_utils.deny_requests import deny_any_real_request
|
|
6
|
+
from cli_base.cli_tools.verbosity import MAX_LOG_LEVEL, setup_logging
|
|
7
|
+
from rich import print # noqa
|
|
8
|
+
from typeguard import install_import_hook
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
# Check type annotations via typeguard in all tests:
|
|
12
|
+
install_import_hook(packages=('mposcli',))
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def pre_configure_tests() -> None:
|
|
16
|
+
print(f'Configure unittests via "load_tests Protocol" from {Path(__file__).relative_to(Path.cwd())}')
|
|
17
|
+
|
|
18
|
+
# Hacky way to display more "assert"-Context in failing tests:
|
|
19
|
+
_MIN_MAX_DIFF = unittest.util._MAX_LENGTH - unittest.util._MIN_DIFF_LEN
|
|
20
|
+
unittest.util._MAX_LENGTH = int(os.environ.get('UNITTEST_MAX_LENGTH', 2000))
|
|
21
|
+
unittest.util._MIN_DIFF_LEN = unittest.util._MAX_LENGTH - _MIN_MAX_DIFF
|
|
22
|
+
|
|
23
|
+
# Deny any request via docket/urllib3 because tests they should mock all requests:
|
|
24
|
+
deny_any_real_request()
|
|
25
|
+
|
|
26
|
+
# Display DEBUG logs in tests:
|
|
27
|
+
setup_logging(verbosity=MAX_LOG_LEVEL)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def load_tests(loader, tests, pattern):
|
|
31
|
+
"""
|
|
32
|
+
Use unittest "load_tests Protocol" as a hook to setup test environment before running tests.
|
|
33
|
+
https://docs.python.org/3/library/unittest.html#load-tests-protocol
|
|
34
|
+
"""
|
|
35
|
+
pre_configure_tests()
|
|
36
|
+
return loader.discover(start_dir=Path(__file__).parent, pattern=pattern)
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import subprocess
|
|
2
|
+
from unittest import TestCase
|
|
3
|
+
|
|
4
|
+
from bx_py_utils.path import assert_is_file
|
|
5
|
+
from cli_base.cli_tools.code_style import assert_code_style
|
|
6
|
+
from cli_base.cli_tools.subprocess_utils import ToolsExecutor
|
|
7
|
+
from manageprojects.test_utils.project_setup import check_editor_config, get_py_max_line_length
|
|
8
|
+
from packaging.version import Version
|
|
9
|
+
|
|
10
|
+
from mposcli import __version__
|
|
11
|
+
from mposcli.cli_dev import PACKAGE_ROOT
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class ProjectSetupTestCase(TestCase):
|
|
15
|
+
def test_version(self):
|
|
16
|
+
self.assertIsNotNone(__version__)
|
|
17
|
+
|
|
18
|
+
version = Version(__version__) # Will raise InvalidVersion() if wrong formatted
|
|
19
|
+
self.assertEqual(str(version), __version__)
|
|
20
|
+
|
|
21
|
+
cli_bin = PACKAGE_ROOT / 'cli.py'
|
|
22
|
+
assert_is_file(cli_bin)
|
|
23
|
+
|
|
24
|
+
output = subprocess.check_output([cli_bin, 'version'], text=True)
|
|
25
|
+
self.assertIn(f'mposcli v{__version__}', output)
|
|
26
|
+
|
|
27
|
+
dev_cli_bin = PACKAGE_ROOT / 'dev-cli.py'
|
|
28
|
+
assert_is_file(dev_cli_bin)
|
|
29
|
+
|
|
30
|
+
output = subprocess.check_output([dev_cli_bin, 'version'], text=True)
|
|
31
|
+
self.assertIn(f'mposcli v{__version__}', output)
|
|
32
|
+
|
|
33
|
+
def test_code_style(self):
|
|
34
|
+
return_code = assert_code_style(package_root=PACKAGE_ROOT)
|
|
35
|
+
self.assertEqual(return_code, 0, 'Code style error, see output above!')
|
|
36
|
+
|
|
37
|
+
def test_check_editor_config(self):
|
|
38
|
+
check_editor_config(package_root=PACKAGE_ROOT)
|
|
39
|
+
|
|
40
|
+
max_line_length = get_py_max_line_length(package_root=PACKAGE_ROOT)
|
|
41
|
+
self.assertEqual(max_line_length, 119)
|
|
42
|
+
|
|
43
|
+
def test_pre_commit_hooks(self):
|
|
44
|
+
executor = ToolsExecutor(cwd=PACKAGE_ROOT)
|
|
45
|
+
for command in ('migrate-config', 'validate-config', 'validate-manifest'):
|
|
46
|
+
executor.verbose_check_call('pre-commit', command, exit_on_error=True)
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
from bx_py_utils.auto_doc import assert_readme_block
|
|
2
|
+
from bx_py_utils.path import assert_is_file
|
|
3
|
+
from cli_base.cli_tools.test_utils.assertion import assert_in
|
|
4
|
+
from cli_base.cli_tools.test_utils.rich_test_utils import NoColorEnvRich, invoke
|
|
5
|
+
from manageprojects.tests.base import BaseTestCase
|
|
6
|
+
|
|
7
|
+
from mposcli import constants
|
|
8
|
+
from mposcli.cli_dev import PACKAGE_ROOT
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def assert_cli_help_in_readme(text_block: str, marker: str):
|
|
12
|
+
README_PATH = PACKAGE_ROOT / 'README.md'
|
|
13
|
+
assert_is_file(README_PATH)
|
|
14
|
+
|
|
15
|
+
text_block = text_block.replace(constants.CLI_EPILOG, '')
|
|
16
|
+
text_block = f'```\n{text_block.strip()}\n```'
|
|
17
|
+
assert_readme_block(
|
|
18
|
+
readme_path=README_PATH,
|
|
19
|
+
text_block=text_block,
|
|
20
|
+
start_marker_line=f'[comment]: <> (✂✂✂ auto generated {marker} start ✂✂✂)',
|
|
21
|
+
end_marker_line=f'[comment]: <> (✂✂✂ auto generated {marker} end ✂✂✂)',
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class ReadmeTestCase(BaseTestCase):
|
|
26
|
+
|
|
27
|
+
def test_main_help(self):
|
|
28
|
+
with NoColorEnvRich():
|
|
29
|
+
stdout = invoke(
|
|
30
|
+
cli_bin=PACKAGE_ROOT / 'cli.py',
|
|
31
|
+
args=['--help'],
|
|
32
|
+
strip_line_prefix='usage: ',
|
|
33
|
+
)
|
|
34
|
+
assert_in(
|
|
35
|
+
content=stdout,
|
|
36
|
+
parts=(
|
|
37
|
+
'usage: mposcli [-h]',
|
|
38
|
+
' version ',
|
|
39
|
+
'Print version and exit',
|
|
40
|
+
constants.CLI_EPILOG,
|
|
41
|
+
),
|
|
42
|
+
)
|
|
43
|
+
assert_cli_help_in_readme(text_block=stdout, marker='main help')
|
|
44
|
+
|
|
45
|
+
def test_dev_help(self):
|
|
46
|
+
with NoColorEnvRich():
|
|
47
|
+
stdout = invoke(
|
|
48
|
+
cli_bin=PACKAGE_ROOT / 'dev-cli.py',
|
|
49
|
+
args=['--help'],
|
|
50
|
+
strip_line_prefix='usage: ',
|
|
51
|
+
)
|
|
52
|
+
assert_in(
|
|
53
|
+
content=stdout,
|
|
54
|
+
parts=(
|
|
55
|
+
'usage: ./dev-cli.py [-h]',
|
|
56
|
+
' lint ',
|
|
57
|
+
' coverage ',
|
|
58
|
+
' update-readme-history ',
|
|
59
|
+
' publish ',
|
|
60
|
+
constants.CLI_EPILOG,
|
|
61
|
+
),
|
|
62
|
+
)
|
|
63
|
+
assert_cli_help_in_readme(text_block=stdout, marker='dev help')
|
|
64
|
+
|
|
65
|
+
def test_cli_commands(self):
|
|
66
|
+
from mposcli.cli_app import app
|
|
67
|
+
|
|
68
|
+
# Dynamically build command list from app object
|
|
69
|
+
# tyro SubcommandApp stores subcommands in _subcommands dict
|
|
70
|
+
commands = set(command.replace('_', '-') for command in app._subcommands.keys())
|
|
71
|
+
|
|
72
|
+
commands.discard('version') # version is pseudo command, because the version always printed on every CLI call
|
|
73
|
+
commands = sorted(commands)
|
|
74
|
+
self.assertEqual(commands, ['build', 'run-desktop', 'update-submodules'])
|
|
75
|
+
|
|
76
|
+
for command in commands:
|
|
77
|
+
with self.subTest(command):
|
|
78
|
+
with NoColorEnvRich():
|
|
79
|
+
stdout = invoke(
|
|
80
|
+
cli_bin=PACKAGE_ROOT / 'cli.py',
|
|
81
|
+
args=[command, '--help'],
|
|
82
|
+
strip_line_prefix='usage: ',
|
|
83
|
+
)
|
|
84
|
+
assert_in(
|
|
85
|
+
content=stdout,
|
|
86
|
+
parts=(f'usage: mposcli {command} [-h]',),
|
|
87
|
+
)
|
|
88
|
+
assert_cli_help_in_readme(text_block=stdout, marker=command)
|
mposcli/user_input.py
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import datetime
|
|
2
|
+
import sys
|
|
3
|
+
|
|
4
|
+
from rich import print
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def file_chooser(paths):
|
|
8
|
+
"""
|
|
9
|
+
Display a numbered list of files sorted by modification time (newest first).
|
|
10
|
+
Show mtime and file name. Input number, ENTER = 1. Return selected Path.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
files = [(p, p.stat().st_mtime) for p in paths if p.is_file()]
|
|
14
|
+
if not files:
|
|
15
|
+
print('[red]No files found.[/red]')
|
|
16
|
+
return None
|
|
17
|
+
files.sort(key=lambda x: x[1], reverse=True)
|
|
18
|
+
|
|
19
|
+
print('[bold]Choose a file:[/bold]')
|
|
20
|
+
for idx, (p, mtime) in enumerate(files):
|
|
21
|
+
dt = datetime.datetime.fromtimestamp(mtime).strftime('%Y-%m-%d %H:%M:%S')
|
|
22
|
+
print(f'[{idx}] {dt} {p.name}')
|
|
23
|
+
|
|
24
|
+
number = input('Enter number (ENTER = 0 - the newest file): ').strip() or 0
|
|
25
|
+
try:
|
|
26
|
+
number = int(number)
|
|
27
|
+
except Exception as err:
|
|
28
|
+
print(f'[red]Invalid input: {err}[/red]')
|
|
29
|
+
sys.exit(1)
|
|
30
|
+
|
|
31
|
+
try:
|
|
32
|
+
selection = files[number][0]
|
|
33
|
+
except IndexError:
|
|
34
|
+
print(f'[red]Invalid selection: {number}[/red]')
|
|
35
|
+
sys.exit(1)
|
|
36
|
+
|
|
37
|
+
return selection
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: mposcli
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: CLI helper for MicroPythonOS: https://github.com/MicroPythonOS/MicroPythonOS
|
|
5
|
+
Project-URL: Documentation, https://github.com/jedie/mposcli
|
|
6
|
+
Project-URL: Source, https://github.com/jedie/mposcli
|
|
7
|
+
Author-email: Jens Diemer <cookiecutter_templates@jensdiemer.de>
|
|
8
|
+
License: GPL-3.0-or-later
|
|
9
|
+
Requires-Python: >=3.12
|
|
10
|
+
Requires-Dist: bx-py-utils
|
|
11
|
+
Requires-Dist: cli-base-utilities>=0.27.4
|
|
12
|
+
Requires-Dist: rich
|
|
13
|
+
Requires-Dist: tyro
|
|
14
|
+
Description-Content-Type: text/markdown
|
|
15
|
+
|
|
16
|
+
# mposcli
|
|
17
|
+
|
|
18
|
+
[](https://github.com/jedie/mposcli/actions/workflows/tests.yml)
|
|
19
|
+
[](https://app.codecov.io/github/jedie/mposcli)
|
|
20
|
+
[](https://pypi.org/project/mposcli/)
|
|
21
|
+
[](https://github.com/jedie/mposcli/blob/main/pyproject.toml)
|
|
22
|
+
[](https://github.com/jedie/mposcli/blob/main/LICENSE)
|
|
23
|
+
|
|
24
|
+
Experimental CLI helper for MicroPythonOS: https://github.com/MicroPythonOS/MicroPythonOS
|
|
25
|
+
|
|
26
|
+
Main Idea: Install it via pipx (see below) and use `mposcli` command in MicroPythonOS repository path.
|
|
27
|
+
|
|
28
|
+
## CLI
|
|
29
|
+
|
|
30
|
+
[comment]: <> (✂✂✂ auto generated main help start ✂✂✂)
|
|
31
|
+
```
|
|
32
|
+
usage: mposcli [-h] {build,run-desktop,update-submodules,version}
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
╭─ options ────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
|
|
37
|
+
│ -h, --help show this help message and exit │
|
|
38
|
+
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
|
|
39
|
+
╭─ subcommands ────────────────────────────────────────────────────────────────────────────────────────────────────────╮
|
|
40
|
+
│ (required) │
|
|
41
|
+
│ • build Build MicroPythonOS by calling: ./scripts/build_mpos.sh <target> see: │
|
|
42
|
+
│ https://docs.micropythonos.com/os-development/ │
|
|
43
|
+
│ • run-desktop Run MicroPythonOS on desktop. see: │
|
|
44
|
+
│ https://docs.micropythonos.com/getting-started/running/#running-on-desktop │
|
|
45
|
+
│ • update-submodules Update MicroPythonOS repository and all submodules see: │
|
|
46
|
+
│ https://docs.micropythonos.com/os-development/linux/#optional-updating-the-code │
|
|
47
|
+
│ • version Print version and exit │
|
|
48
|
+
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
|
|
49
|
+
```
|
|
50
|
+
[comment]: <> (✂✂✂ auto generated main help end ✂✂✂)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
## CLI - build
|
|
54
|
+
|
|
55
|
+
[comment]: <> (✂✂✂ auto generated build start ✂✂✂)
|
|
56
|
+
```
|
|
57
|
+
usage: mposcli build [-h] [--target {esp32,esp32s3,unix,macOS}] [-v]
|
|
58
|
+
|
|
59
|
+
Build MicroPythonOS by calling: ./scripts/build_mpos.sh <target> see: https://docs.micropythonos.com/os-development/
|
|
60
|
+
|
|
61
|
+
╭─ options ────────────────────────────────────────────────────────────────╮
|
|
62
|
+
│ -h, --help show this help message and exit │
|
|
63
|
+
│ --target {esp32,esp32s3,unix,macOS} │
|
|
64
|
+
│ Target platform to build for. (default: unix) │
|
|
65
|
+
│ -v, --verbosity Verbosity level; e.g.: -v, -vv, -vvv, etc. (repeatable) │
|
|
66
|
+
╰──────────────────────────────────────────────────────────────────────────╯
|
|
67
|
+
```
|
|
68
|
+
[comment]: <> (✂✂✂ auto generated build end ✂✂✂)
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
## CLI - run-desktop
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
[comment]: <> (✂✂✂ auto generated run-desktop start ✂✂✂)
|
|
76
|
+
```
|
|
77
|
+
usage: mposcli run-desktop [-h] [--heapsize INT] [--script {None}|STR] [--binary {None}|STR] [-v]
|
|
78
|
+
|
|
79
|
+
Run MicroPythonOS on desktop. see: https://docs.micropythonos.com/getting-started/running/#running-on-desktop
|
|
80
|
+
|
|
81
|
+
╭─ options ────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
|
|
82
|
+
│ -h, --help show this help message and exit │
|
|
83
|
+
│ --heapsize INT Heap size in MB (default: 8, same as PSRAM on many ESP32-S3 boards) (default: 8) │
|
|
84
|
+
│ --script {None}|STR Script file (.py) or app name to run. If omitted, starts normally. (default: None) │
|
|
85
|
+
│ --binary {None}|STR Optional name of the binary to start. If omitted, shows a file chooser to select one from the │
|
|
86
|
+
│ lvgl_micropython build directory. (default: None) │
|
|
87
|
+
│ -v, --verbosity Verbosity level; e.g.: -v, -vv, -vvv, etc. (repeatable) │
|
|
88
|
+
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
|
|
89
|
+
```
|
|
90
|
+
[comment]: <> (✂✂✂ auto generated run-desktop end ✂✂✂)
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
## CLI - update-submodules
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
[comment]: <> (✂✂✂ auto generated update-submodules start ✂✂✂)
|
|
97
|
+
```
|
|
98
|
+
usage: mposcli update-submodules [-h] [-v]
|
|
99
|
+
|
|
100
|
+
Update MicroPythonOS repository and all submodules see: https://docs.micropythonos.com/os-development/linux/#optional-updating-the-code
|
|
101
|
+
|
|
102
|
+
╭─ options ────────────────────────────────────────────────────────────────╮
|
|
103
|
+
│ -h, --help show this help message and exit │
|
|
104
|
+
│ -v, --verbosity Verbosity level; e.g.: -v, -vv, -vvv, etc. (repeatable) │
|
|
105
|
+
╰──────────────────────────────────────────────────────────────────────────╯
|
|
106
|
+
```
|
|
107
|
+
[comment]: <> (✂✂✂ auto generated update-submodules end ✂✂✂)
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
## start development
|
|
115
|
+
|
|
116
|
+
At least `uv` is needed. Install e.g.: via pipx:
|
|
117
|
+
```bash
|
|
118
|
+
apt-get install pipx
|
|
119
|
+
pipx install uv
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Clone the project and just start the CLI help commands.
|
|
123
|
+
A virtual environment will be created/updated automatically.
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
~$ git clone https://github.com/jedie/mposcli.git
|
|
127
|
+
~$ cd mposcli
|
|
128
|
+
~/mposcli$ ./cli.py --help
|
|
129
|
+
~/mposcli$ ./dev-cli.py --help
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
[comment]: <> (✂✂✂ auto generated dev help start ✂✂✂)
|
|
133
|
+
```
|
|
134
|
+
usage: ./dev-cli.py [-h] {coverage,install,lint,mypy,nox,pip-audit,publish,shell-completion,test,update,update-readme-history,update-test-snapshot-files,version}
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
╭─ options ────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
|
|
139
|
+
│ -h, --help show this help message and exit │
|
|
140
|
+
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
|
|
141
|
+
╭─ subcommands ────────────────────────────────────────────────────────────────────────────────────────────────────────╮
|
|
142
|
+
│ (required) │
|
|
143
|
+
│ • coverage Run tests and show coverage report. │
|
|
144
|
+
│ • install Install requirements and 'mposcli' via pip as editable. │
|
|
145
|
+
│ • lint Check/fix code style by run: "ruff check --fix" │
|
|
146
|
+
│ • mypy Run Mypy (configured in pyproject.toml) │
|
|
147
|
+
│ • nox Run nox │
|
|
148
|
+
│ • pip-audit Run pip-audit check against current requirements files │
|
|
149
|
+
│ • publish Build and upload this project to PyPi │
|
|
150
|
+
│ • shell-completion │
|
|
151
|
+
│ Setup shell completion for this CLI (Currently only for bash shell) │
|
|
152
|
+
│ • test Run unittests │
|
|
153
|
+
│ • update Update dependencies (uv.lock) and git pre-commit hooks │
|
|
154
|
+
│ • update-readme-history │
|
|
155
|
+
│ Update project history base on git commits/tags in README.md Will be exited with 1 if the README.md │
|
|
156
|
+
│ was updated otherwise with 0. │
|
|
157
|
+
│ │
|
|
158
|
+
│ Also, callable via e.g.: │
|
|
159
|
+
│ python -m cli_base update-readme-history -v │
|
|
160
|
+
│ • update-test-snapshot-files │
|
|
161
|
+
│ Update all test snapshot files (by remove and recreate all snapshot files) │
|
|
162
|
+
│ • version Print version and exit │
|
|
163
|
+
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
|
|
164
|
+
```
|
|
165
|
+
[comment]: <> (✂✂✂ auto generated dev help end ✂✂✂)
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
## History
|
|
169
|
+
|
|
170
|
+
[comment]: <> (✂✂✂ auto generated history start ✂✂✂)
|
|
171
|
+
|
|
172
|
+
* [**dev**](https://github.com/jedie/mposcli/compare/1695026...main)
|
|
173
|
+
* 2026-02-16 - Add "update-submodules" command
|
|
174
|
+
* 2026-02-16 - Add "build" command
|
|
175
|
+
* 2026-02-16 - CLI command: "run-desktop"
|
|
176
|
+
* 2026-02-16 - first commit
|
|
177
|
+
|
|
178
|
+
[comment]: <> (✂✂✂ auto generated history end ✂✂✂)
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
mposcli/__init__.py,sha256=xJiMZ56FfdXOY73tYd5S2cxUMBXmiwtzl7kkbcEFdPI,270
|
|
2
|
+
mposcli/__main__.py,sha256=Xyf-B30u54m12uBqpL1HDMdFtD64a-rhFPgmRZlevjU,150
|
|
3
|
+
mposcli/constants.py,sha256=26abB8No0nNvCd--M7Z6sGgAPG_OloyUk5ugJGR6D6I,152
|
|
4
|
+
mposcli/fs_utils.py,sha256=_S2TtgG5iY0ZHctKFZ-9J49WrV0QChbyU-JqpZjsBJg,175
|
|
5
|
+
mposcli/mpos_utils.py,sha256=DJ9LHL0Dw0nFe7Kmqattc0kxoQIk6u8tiwFkv_GR5co,899
|
|
6
|
+
mposcli/user_input.py,sha256=eUuRiGCHb7OxorDB-dyG6pbXKDeDIPc8VFcDLT7AWSg,1048
|
|
7
|
+
mposcli/cli_app/__init__.py,sha256=ngvmI2LD2Qtc18TNxORzv4yvQT1QrflD3kj5EoOlyjs,966
|
|
8
|
+
mposcli/cli_app/build.py,sha256=7fjxPYT5jTXgrqouMYlvnY5R0whd2H6JzuFmfFMlISU,1141
|
|
9
|
+
mposcli/cli_app/run_deskop.py,sha256=cBl5-JMd6SK6dAKJ-ttjGmb8CXvciMfW2bO9svXaWqU,3330
|
|
10
|
+
mposcli/cli_app/update.py,sha256=J2cAfITOa_GhmOzvsACSuqzKRVvDfD1XpAT8awb8GKo,1023
|
|
11
|
+
mposcli/cli_dev/__init__.py,sha256=cPMttKS3TNZdP-CTSKCNSEIsquaUi8K-8VDxQ9Ey8xQ,1873
|
|
12
|
+
mposcli/cli_dev/__main__.py,sha256=Yx-Cc_oeUQo_M1uPV37Evz0PvKy5gUsUeEH19oEzSvM,158
|
|
13
|
+
mposcli/cli_dev/code_style.py,sha256=5kBHRqAPmAg27R00TWXE4EdPlTsOLkw65RKn4qEVkx8,382
|
|
14
|
+
mposcli/cli_dev/packaging.py,sha256=bZH7DLIF9lVWwdKJjpe69VgGmTLGylSfU9i_WUlm0PY,1798
|
|
15
|
+
mposcli/cli_dev/shell_completion.py,sha256=y96MQ8L0PLFYop9l8QTvRKs3q-aSC_5IrVf5AiSixqo,636
|
|
16
|
+
mposcli/cli_dev/testing.py,sha256=j4yj6aMQLlEYDUoel3uJnfkFKArW0YtiSGPK7BPMxfM,1381
|
|
17
|
+
mposcli/cli_dev/update_readme_history.py,sha256=k0wVSHMIRyQxiQdxHWwVxxQAYSqMWuEogEkdlWP0fBQ,900
|
|
18
|
+
mposcli/tests/__init__.py,sha256=LsOCUKW7i2biT8mo4eGTiNqS6d_G0p7801FrrDJQku8,1338
|
|
19
|
+
mposcli/tests/test_doctests.py,sha256=Gfv3EbactIO1JgDroQVp-sunSDWhasgEtElwc_ddL3Q,209
|
|
20
|
+
mposcli/tests/test_project_setup.py,sha256=dSqtKBQo6lUFTnX22LU7buY_jWkUiGrM_rXfslYtwCY,1759
|
|
21
|
+
mposcli/tests/test_readme.py,sha256=I9H5uxhASMCzxllPBShHQKS14ZdRZWiyvXOpYc4uLf8,3173
|
|
22
|
+
mposcli/tests/test_readme_history.py,sha256=PbxF_yRspyRwkVCQosZXevIHrsla3WFBTUVeLI0bb-s,263
|
|
23
|
+
mposcli-0.1.0.dist-info/METADATA,sha256=9TTGJ634Iun41T0m5w-XH8egoPx50z5IiEmvDSA0q30,13266
|
|
24
|
+
mposcli-0.1.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
25
|
+
mposcli-0.1.0.dist-info/entry_points.txt,sha256=N3mHDYWJTw7GQa9Kakr3fcyDpRIXRC04TllScaURHN4,50
|
|
26
|
+
mposcli-0.1.0.dist-info/RECORD,,
|