mposcli 0.3.0__tar.gz → 0.4.0__tar.gz
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-0.3.0 → mposcli-0.4.0}/.pre-commit-config.yaml +1 -1
- {mposcli-0.3.0 → mposcli-0.4.0}/.run/Unittests __all__.run.xml +2 -3
- mposcli-0.4.0/.venv-app/lib/python3.14/site-packages/cli_base/tests/shell_complete_snapshots/.gitignore +1 -0
- {mposcli-0.3.0 → mposcli-0.4.0}/PKG-INFO +45 -7
- {mposcli-0.3.0 → mposcli-0.4.0}/README.md +44 -6
- {mposcli-0.3.0 → mposcli-0.4.0}/mposcli/__init__.py +1 -1
- {mposcli-0.3.0 → mposcli-0.4.0}/mposcli/cli_app/build.py +1 -0
- mposcli-0.4.0/mposcli/cli_app/copy_mpos.py +195 -0
- {mposcli-0.3.0 → mposcli-0.4.0}/mposcli/cli_app/flash.py +1 -1
- {mposcli-0.3.0 → mposcli-0.4.0}/mposcli/cli_app/run_deskop.py +3 -2
- {mposcli-0.3.0 → mposcli-0.4.0}/mposcli/cli_app/update.py +1 -1
- {mposcli-0.3.0 → mposcli-0.4.0}/mposcli/cli_dev/testing.py +3 -3
- {mposcli-0.3.0 → mposcli-0.4.0}/mposcli/cli_dev/update_readme_history.py +1 -1
- mposcli-0.4.0/mposcli/fs_utils.py +26 -0
- {mposcli-0.3.0 → mposcli-0.4.0}/mposcli/mpos_utils.py +3 -3
- {mposcli-0.3.0 → mposcli-0.4.0}/mposcli/tests/__init__.py +2 -2
- {mposcli-0.3.0 → mposcli-0.4.0}/mposcli/tests/test_readme.py +2 -2
- {mposcli-0.3.0 → mposcli-0.4.0}/mposcli/user_input.py +59 -4
- {mposcli-0.3.0 → mposcli-0.4.0}/uv.lock +81 -81
- mposcli-0.3.0/mposcli/cli_app/copy_mpos.py +0 -92
- mposcli-0.3.0/mposcli/fs_utils.py +0 -6
- {mposcli-0.3.0 → mposcli-0.4.0}/.editorconfig +0 -0
- {mposcli-0.3.0 → mposcli-0.4.0}/.github/workflows/tests.yml +0 -0
- {mposcli-0.3.0 → mposcli-0.4.0}/.gitignore +0 -0
- {mposcli-0.3.0 → mposcli-0.4.0}/.idea/.gitignore +0 -0
- {mposcli-0.3.0 → mposcli-0.4.0}/.pre-commit-hooks.yaml +0 -0
- {mposcli-0.3.0 → mposcli-0.4.0}/.run/Template Python tests.run.xml +0 -0
- {mposcli-0.3.0 → mposcli-0.4.0}/.run/Template Python.run.xml +0 -0
- {mposcli-0.3.0 → mposcli-0.4.0}/.run/cli --help.run.xml +0 -0
- {mposcli-0.3.0 → mposcli-0.4.0}/.run/dev-cli --help.run.xml +0 -0
- {mposcli-0.3.0 → mposcli-0.4.0}/.run/dev-cli test.run.xml +0 -0
- {mposcli-0.3.0 → mposcli-0.4.0}/.venv-app/.gitignore +0 -0
- {mposcli-0.3.0 → mposcli-0.4.0}/cli.py +0 -0
- {mposcli-0.3.0 → mposcli-0.4.0}/dev-cli.py +0 -0
- {mposcli-0.3.0 → mposcli-0.4.0}/dist/.gitignore +0 -0
- {mposcli-0.3.0 → mposcli-0.4.0}/mposcli/__main__.py +0 -0
- {mposcli-0.3.0 → mposcli-0.4.0}/mposcli/cli_app/__init__.py +0 -0
- {mposcli-0.3.0 → mposcli-0.4.0}/mposcli/cli_dev/__init__.py +0 -0
- {mposcli-0.3.0 → mposcli-0.4.0}/mposcli/cli_dev/__main__.py +0 -0
- {mposcli-0.3.0 → mposcli-0.4.0}/mposcli/cli_dev/code_style.py +0 -0
- {mposcli-0.3.0 → mposcli-0.4.0}/mposcli/cli_dev/packaging.py +0 -0
- {mposcli-0.3.0 → mposcli-0.4.0}/mposcli/cli_dev/shell_completion.py +0 -0
- {mposcli-0.3.0 → mposcli-0.4.0}/mposcli/constants.py +0 -0
- {mposcli-0.3.0 → mposcli-0.4.0}/mposcli/tests/test_doctests.py +0 -0
- {mposcli-0.3.0 → mposcli-0.4.0}/mposcli/tests/test_project_setup.py +0 -0
- {mposcli-0.3.0 → mposcli-0.4.0}/mposcli/tests/test_readme_history.py +0 -0
- {mposcli-0.3.0 → mposcli-0.4.0}/mposcli/tools.py +0 -0
- {mposcli-0.3.0 → mposcli-0.4.0}/noxfile.py +0 -0
- {mposcli-0.3.0 → mposcli-0.4.0}/pyproject.toml +0 -0
|
@@ -4,10 +4,9 @@
|
|
|
4
4
|
<option name="ENV_FILES" value="" />
|
|
5
5
|
<option name="INTERPRETER_OPTIONS" value="" />
|
|
6
6
|
<option name="PARENT_ENVS" value="true" />
|
|
7
|
-
<option name="SDK_HOME" value="
|
|
8
|
-
<option name="SDK_NAME" value="uv (mposcli) (2)" />
|
|
7
|
+
<option name="SDK_HOME" value="" />
|
|
9
8
|
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
|
|
10
|
-
<option name="IS_MODULE_SDK" value="
|
|
9
|
+
<option name="IS_MODULE_SDK" value="true" />
|
|
11
10
|
<option name="ADD_CONTENT_ROOTS" value="false" />
|
|
12
11
|
<option name="ADD_SOURCE_ROOTS" value="false" />
|
|
13
12
|
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
!.*
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mposcli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.0
|
|
4
4
|
Summary: CLI helper for MicroPythonOS: https://github.com/MicroPythonOS/MicroPythonOS
|
|
5
5
|
Project-URL: Documentation, https://github.com/jedie/mposcli
|
|
6
6
|
Project-URL: Source, https://github.com/jedie/mposcli
|
|
@@ -47,7 +47,7 @@ cd ~/MicroPythonOS
|
|
|
47
47
|
|
|
48
48
|
[comment]: <> (✂✂✂ auto generated main help start ✂✂✂)
|
|
49
49
|
```
|
|
50
|
-
usage: mposcli [-h] {build,cp,flash,run-desktop,update,update-submodules,version}
|
|
50
|
+
usage: mposcli [-h] {build,cp,cp-app,flash,run-desktop,update,update-submodules,version}
|
|
51
51
|
|
|
52
52
|
|
|
53
53
|
|
|
@@ -63,6 +63,11 @@ usage: mposcli [-h] {build,cp,flash,run-desktop,update,update-submodules,version
|
|
|
63
63
|
│ files to copy/update. But can also be used to copy/update all │
|
|
64
64
|
│ files. see: https://docs.micropythonos.com/os-development/insta │
|
|
65
65
|
│ lling-on-esp32/ │
|
|
66
|
+
│ • cp-app Copy/update internal_filesystem/apps to the device via │
|
|
67
|
+
│ "mpremote fs cp". Display a file chooser to select which app to │
|
|
68
|
+
│ copy/update. But can also be used to copy/update all files. │
|
|
69
|
+
│ see: https://docs.micropythonos.com/os-development/installing-o │
|
|
70
|
+
│ n-esp32/ │
|
|
66
71
|
│ • flash Flash MicroPythonOS to the device. Display a file chooser to │
|
|
67
72
|
│ select the image to flash. All lvgl_micropython/build/*.bin │
|
|
68
73
|
│ files will be shown in the file chooser. see: https://docs.micr │
|
|
@@ -88,15 +93,17 @@ usage: mposcli [-h] {build,cp,flash,run-desktop,update,update-submodules,version
|
|
|
88
93
|
|
|
89
94
|
[comment]: <> (✂✂✂ auto generated build start ✂✂✂)
|
|
90
95
|
```
|
|
91
|
-
usage: mposcli build [-h] [
|
|
96
|
+
usage: mposcli build [-h] [{esp32,esp32s3,unix,macOS}] [-v]
|
|
92
97
|
|
|
93
98
|
Build MicroPythonOS by calling: ./scripts/build_mpos.sh <target> see:
|
|
94
99
|
https://docs.micropythonos.com/os-development/
|
|
95
100
|
|
|
101
|
+
╭─ positional arguments ───────────────────────────────────────────────────╮
|
|
102
|
+
│ [{esp32,esp32s3,unix,macOS}] │
|
|
103
|
+
│ Target platform to build for. (default: unix) │
|
|
104
|
+
╰──────────────────────────────────────────────────────────────────────────╯
|
|
96
105
|
╭─ options ────────────────────────────────────────────────────────────────╮
|
|
97
106
|
│ -h, --help show this help message and exit │
|
|
98
|
-
│ --target {esp32,esp32s3,unix,macOS} │
|
|
99
|
-
│ Target platform to build for. (default: unix) │
|
|
100
107
|
│ -v, --verbosity Verbosity level; e.g.: -v, -vv, -vvv, etc. (repeatable) │
|
|
101
108
|
╰──────────────────────────────────────────────────────────────────────────╯
|
|
102
109
|
```
|
|
@@ -108,13 +115,15 @@ https://docs.micropythonos.com/os-development/
|
|
|
108
115
|
|
|
109
116
|
[comment]: <> (✂✂✂ auto generated cp start ✂✂✂)
|
|
110
117
|
```
|
|
111
|
-
usage: mposcli cp [-h] [
|
|
112
|
-
[-v]
|
|
118
|
+
usage: mposcli cp [-h] [CP OPTIONS]
|
|
113
119
|
|
|
114
120
|
Copy/update internal_filesystem/lib/mpos files to the device via "mpremote fs cp". Display
|
|
115
121
|
a file chooser to select which files to copy/update. But can also be used to copy/update
|
|
116
122
|
all files. see: https://docs.micropythonos.com/os-development/installing-on-esp32/
|
|
117
123
|
|
|
124
|
+
╭─ positional arguments ─────────────────────────────────────────────────────────────────╮
|
|
125
|
+
│ [{None}|PATH] Optional file or directory path. (default: None) │
|
|
126
|
+
╰────────────────────────────────────────────────────────────────────────────────────────╯
|
|
118
127
|
╭─ options ──────────────────────────────────────────────────────────────────────────────╮
|
|
119
128
|
│ -h, --help show this help message and exit │
|
|
120
129
|
│ --new-file-limit INT How many of the newest files to show in the file chooser? │
|
|
@@ -129,6 +138,29 @@ all files. see: https://docs.micropythonos.com/os-development/installing-on-esp3
|
|
|
129
138
|
|
|
130
139
|
|
|
131
140
|
|
|
141
|
+
|
|
142
|
+
## mposcli cp-app
|
|
143
|
+
|
|
144
|
+
[comment]: <> (✂✂✂ auto generated cp-app start ✂✂✂)
|
|
145
|
+
```
|
|
146
|
+
usage: mposcli cp-app [-h] [--reset | --no-reset] [--repl | --no-repl] [-v]
|
|
147
|
+
|
|
148
|
+
Copy/update internal_filesystem/apps to the device via "mpremote fs cp". Display a file
|
|
149
|
+
chooser to select which app to copy/update. But can also be used to copy/update all files.
|
|
150
|
+
see: https://docs.micropythonos.com/os-development/installing-on-esp32/
|
|
151
|
+
|
|
152
|
+
╭─ options ──────────────────────────────────────────────────────────────────────────────╮
|
|
153
|
+
│ -h, --help show this help message and exit │
|
|
154
|
+
│ --reset, --no-reset Reset the device after copy/update? (default: True) │
|
|
155
|
+
│ --repl, --no-repl After flashing/verify start REPL with mpremote to see the output │
|
|
156
|
+
│ of the device? (default: True) │
|
|
157
|
+
│ -v, --verbosity Verbosity level; e.g.: -v, -vv, -vvv, etc. (repeatable) │
|
|
158
|
+
╰────────────────────────────────────────────────────────────────────────────────────────╯
|
|
159
|
+
```
|
|
160
|
+
[comment]: <> (✂✂✂ auto generated cp-app end ✂✂✂)
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
|
|
132
164
|
## mposcli flash
|
|
133
165
|
|
|
134
166
|
[comment]: <> (✂✂✂ auto generated flash start ✂✂✂)
|
|
@@ -285,6 +317,12 @@ completion,test,update,update-readme-history,update-test-snapshot-files,version}
|
|
|
285
317
|
|
|
286
318
|
[comment]: <> (✂✂✂ auto generated history start ✂✂✂)
|
|
287
319
|
|
|
320
|
+
* [v0.4.0](https://github.com/jedie/mposcli/compare/v0.3.0...v0.4.0)
|
|
321
|
+
* 2026-02-24 - NEW command: "cp-app" to install/update internal_filesystem/apps
|
|
322
|
+
* 2026-02-24 - Log skipped files
|
|
323
|
+
* 2026-02-23 - Update requirements and fix code style
|
|
324
|
+
* 2026-02-23 - "build" command: target as positional argument
|
|
325
|
+
* 2026-02-23 - Expand "cp" command and allow optional filesystem path
|
|
288
326
|
* [v0.3.0](https://github.com/jedie/mposcli/compare/v0.2.0...v0.3.0)
|
|
289
327
|
* 2026-02-18 - Add "update" beside "update-submodules"
|
|
290
328
|
* 2026-02-17 - Update requirements
|
|
@@ -32,7 +32,7 @@ cd ~/MicroPythonOS
|
|
|
32
32
|
|
|
33
33
|
[comment]: <> (✂✂✂ auto generated main help start ✂✂✂)
|
|
34
34
|
```
|
|
35
|
-
usage: mposcli [-h] {build,cp,flash,run-desktop,update,update-submodules,version}
|
|
35
|
+
usage: mposcli [-h] {build,cp,cp-app,flash,run-desktop,update,update-submodules,version}
|
|
36
36
|
|
|
37
37
|
|
|
38
38
|
|
|
@@ -48,6 +48,11 @@ usage: mposcli [-h] {build,cp,flash,run-desktop,update,update-submodules,version
|
|
|
48
48
|
│ files to copy/update. But can also be used to copy/update all │
|
|
49
49
|
│ files. see: https://docs.micropythonos.com/os-development/insta │
|
|
50
50
|
│ lling-on-esp32/ │
|
|
51
|
+
│ • cp-app Copy/update internal_filesystem/apps to the device via │
|
|
52
|
+
│ "mpremote fs cp". Display a file chooser to select which app to │
|
|
53
|
+
│ copy/update. But can also be used to copy/update all files. │
|
|
54
|
+
│ see: https://docs.micropythonos.com/os-development/installing-o │
|
|
55
|
+
│ n-esp32/ │
|
|
51
56
|
│ • flash Flash MicroPythonOS to the device. Display a file chooser to │
|
|
52
57
|
│ select the image to flash. All lvgl_micropython/build/*.bin │
|
|
53
58
|
│ files will be shown in the file chooser. see: https://docs.micr │
|
|
@@ -73,15 +78,17 @@ usage: mposcli [-h] {build,cp,flash,run-desktop,update,update-submodules,version
|
|
|
73
78
|
|
|
74
79
|
[comment]: <> (✂✂✂ auto generated build start ✂✂✂)
|
|
75
80
|
```
|
|
76
|
-
usage: mposcli build [-h] [
|
|
81
|
+
usage: mposcli build [-h] [{esp32,esp32s3,unix,macOS}] [-v]
|
|
77
82
|
|
|
78
83
|
Build MicroPythonOS by calling: ./scripts/build_mpos.sh <target> see:
|
|
79
84
|
https://docs.micropythonos.com/os-development/
|
|
80
85
|
|
|
86
|
+
╭─ positional arguments ───────────────────────────────────────────────────╮
|
|
87
|
+
│ [{esp32,esp32s3,unix,macOS}] │
|
|
88
|
+
│ Target platform to build for. (default: unix) │
|
|
89
|
+
╰──────────────────────────────────────────────────────────────────────────╯
|
|
81
90
|
╭─ options ────────────────────────────────────────────────────────────────╮
|
|
82
91
|
│ -h, --help show this help message and exit │
|
|
83
|
-
│ --target {esp32,esp32s3,unix,macOS} │
|
|
84
|
-
│ Target platform to build for. (default: unix) │
|
|
85
92
|
│ -v, --verbosity Verbosity level; e.g.: -v, -vv, -vvv, etc. (repeatable) │
|
|
86
93
|
╰──────────────────────────────────────────────────────────────────────────╯
|
|
87
94
|
```
|
|
@@ -93,13 +100,15 @@ https://docs.micropythonos.com/os-development/
|
|
|
93
100
|
|
|
94
101
|
[comment]: <> (✂✂✂ auto generated cp start ✂✂✂)
|
|
95
102
|
```
|
|
96
|
-
usage: mposcli cp [-h] [
|
|
97
|
-
[-v]
|
|
103
|
+
usage: mposcli cp [-h] [CP OPTIONS]
|
|
98
104
|
|
|
99
105
|
Copy/update internal_filesystem/lib/mpos files to the device via "mpremote fs cp". Display
|
|
100
106
|
a file chooser to select which files to copy/update. But can also be used to copy/update
|
|
101
107
|
all files. see: https://docs.micropythonos.com/os-development/installing-on-esp32/
|
|
102
108
|
|
|
109
|
+
╭─ positional arguments ─────────────────────────────────────────────────────────────────╮
|
|
110
|
+
│ [{None}|PATH] Optional file or directory path. (default: None) │
|
|
111
|
+
╰────────────────────────────────────────────────────────────────────────────────────────╯
|
|
103
112
|
╭─ options ──────────────────────────────────────────────────────────────────────────────╮
|
|
104
113
|
│ -h, --help show this help message and exit │
|
|
105
114
|
│ --new-file-limit INT How many of the newest files to show in the file chooser? │
|
|
@@ -114,6 +123,29 @@ all files. see: https://docs.micropythonos.com/os-development/installing-on-esp3
|
|
|
114
123
|
|
|
115
124
|
|
|
116
125
|
|
|
126
|
+
|
|
127
|
+
## mposcli cp-app
|
|
128
|
+
|
|
129
|
+
[comment]: <> (✂✂✂ auto generated cp-app start ✂✂✂)
|
|
130
|
+
```
|
|
131
|
+
usage: mposcli cp-app [-h] [--reset | --no-reset] [--repl | --no-repl] [-v]
|
|
132
|
+
|
|
133
|
+
Copy/update internal_filesystem/apps to the device via "mpremote fs cp". Display a file
|
|
134
|
+
chooser to select which app to copy/update. But can also be used to copy/update all files.
|
|
135
|
+
see: https://docs.micropythonos.com/os-development/installing-on-esp32/
|
|
136
|
+
|
|
137
|
+
╭─ options ──────────────────────────────────────────────────────────────────────────────╮
|
|
138
|
+
│ -h, --help show this help message and exit │
|
|
139
|
+
│ --reset, --no-reset Reset the device after copy/update? (default: True) │
|
|
140
|
+
│ --repl, --no-repl After flashing/verify start REPL with mpremote to see the output │
|
|
141
|
+
│ of the device? (default: True) │
|
|
142
|
+
│ -v, --verbosity Verbosity level; e.g.: -v, -vv, -vvv, etc. (repeatable) │
|
|
143
|
+
╰────────────────────────────────────────────────────────────────────────────────────────╯
|
|
144
|
+
```
|
|
145
|
+
[comment]: <> (✂✂✂ auto generated cp-app end ✂✂✂)
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
|
|
117
149
|
## mposcli flash
|
|
118
150
|
|
|
119
151
|
[comment]: <> (✂✂✂ auto generated flash start ✂✂✂)
|
|
@@ -270,6 +302,12 @@ completion,test,update,update-readme-history,update-test-snapshot-files,version}
|
|
|
270
302
|
|
|
271
303
|
[comment]: <> (✂✂✂ auto generated history start ✂✂✂)
|
|
272
304
|
|
|
305
|
+
* [v0.4.0](https://github.com/jedie/mposcli/compare/v0.3.0...v0.4.0)
|
|
306
|
+
* 2026-02-24 - NEW command: "cp-app" to install/update internal_filesystem/apps
|
|
307
|
+
* 2026-02-24 - Log skipped files
|
|
308
|
+
* 2026-02-23 - Update requirements and fix code style
|
|
309
|
+
* 2026-02-23 - "build" command: target as positional argument
|
|
310
|
+
* 2026-02-23 - Expand "cp" command and allow optional filesystem path
|
|
273
311
|
* [v0.3.0](https://github.com/jedie/mposcli/compare/v0.2.0...v0.3.0)
|
|
274
312
|
* 2026-02-18 - Add "update" beside "update-submodules"
|
|
275
313
|
* 2026-02-17 - Update requirements
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import time
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from typing import Annotated
|
|
5
|
+
|
|
6
|
+
import tyro
|
|
7
|
+
from bx_py_utils.path import assert_is_dir
|
|
8
|
+
from cli_base.cli_tools.subprocess_utils import verbose_check_call
|
|
9
|
+
from cli_base.cli_tools.verbosity import setup_logging
|
|
10
|
+
from cli_base.tyro_commands import TyroVerbosityArgType
|
|
11
|
+
from rich import print
|
|
12
|
+
|
|
13
|
+
from mposcli.cli_app import app
|
|
14
|
+
from mposcli.mpos_utils import get_mpos_path
|
|
15
|
+
from mposcli.tools import get_mpremote_bin
|
|
16
|
+
from mposcli.user_input import choose_newest_modified_directory, get_newest_files
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
logger = logging.getLogger(__name__)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@app.command
|
|
23
|
+
def cp(
|
|
24
|
+
local_path: Annotated[
|
|
25
|
+
Path | None,
|
|
26
|
+
tyro.conf.arg(help='Optional file or directory path.'),
|
|
27
|
+
] = None,
|
|
28
|
+
/,
|
|
29
|
+
new_file_limit: Annotated[
|
|
30
|
+
int,
|
|
31
|
+
tyro.conf.arg(help='How many of the newest files to show in the file chooser?'),
|
|
32
|
+
] = 10,
|
|
33
|
+
reset: Annotated[
|
|
34
|
+
bool,
|
|
35
|
+
tyro.conf.arg(help='Reset the device after copy/update?'),
|
|
36
|
+
] = True,
|
|
37
|
+
repl: Annotated[
|
|
38
|
+
bool,
|
|
39
|
+
tyro.conf.arg(help='After flashing/verify start REPL with mpremote to see the output of the device?'),
|
|
40
|
+
] = True,
|
|
41
|
+
verbosity: TyroVerbosityArgType = 1,
|
|
42
|
+
):
|
|
43
|
+
"""
|
|
44
|
+
Copy/update internal_filesystem/lib/mpos files to the device via "mpremote fs cp".
|
|
45
|
+
Display a file chooser to select which files to copy/update.
|
|
46
|
+
But can also be used to copy/update all files.
|
|
47
|
+
see: https://docs.micropythonos.com/os-development/installing-on-esp32/
|
|
48
|
+
"""
|
|
49
|
+
setup_logging(verbosity=verbosity)
|
|
50
|
+
|
|
51
|
+
mpos_path = get_mpos_path()
|
|
52
|
+
|
|
53
|
+
internal_fs = mpos_path / 'internal_filesystem'
|
|
54
|
+
lib_mpos = internal_fs / 'lib' / 'mpos'
|
|
55
|
+
assert_is_dir(lib_mpos)
|
|
56
|
+
apps_path = internal_fs / 'apps'
|
|
57
|
+
assert_is_dir(apps_path)
|
|
58
|
+
|
|
59
|
+
mpremote_bin = get_mpremote_bin()
|
|
60
|
+
|
|
61
|
+
print('\n')
|
|
62
|
+
|
|
63
|
+
popenargs = (mpremote_bin, 'fs', 'cp')
|
|
64
|
+
|
|
65
|
+
if local_path:
|
|
66
|
+
if not local_path.is_absolute():
|
|
67
|
+
local_path = mpos_path / local_path
|
|
68
|
+
|
|
69
|
+
print(f'Copy/update app: "{local_path}" ...')
|
|
70
|
+
|
|
71
|
+
if not local_path.exists():
|
|
72
|
+
print(f'[red]Error: The specified source path "{local_path}" does not exist.[/red]')
|
|
73
|
+
return
|
|
74
|
+
|
|
75
|
+
# Is source a sub path of "apps_path" ?
|
|
76
|
+
if local_path.is_relative_to(apps_path):
|
|
77
|
+
local_rel_path = local_path.relative_to(mpos_path)
|
|
78
|
+
remote_path = f':/{local_path.relative_to(internal_fs)}'
|
|
79
|
+
else:
|
|
80
|
+
raise NotImplementedError
|
|
81
|
+
else:
|
|
82
|
+
local_path = get_newest_files(lib_mpos, limit=new_file_limit)
|
|
83
|
+
if not local_path:
|
|
84
|
+
print('Copy/update all files in lib/mpos to the device')
|
|
85
|
+
local_path = lib_mpos
|
|
86
|
+
|
|
87
|
+
local_rel_path = local_path.relative_to(mpos_path)
|
|
88
|
+
remote_path = f':/{local_path.relative_to(lib_mpos.parent)}'
|
|
89
|
+
|
|
90
|
+
if local_path.is_dir():
|
|
91
|
+
popenargs += ('-r',)
|
|
92
|
+
print(f'Copying directory "[bold]{local_rel_path}[/bold]" to device at "[bold]{remote_path}[/bold]" ...')
|
|
93
|
+
else:
|
|
94
|
+
print(f'Copying file "[bold]{local_rel_path}[/bold]" to device at "[bold]{remote_path}[/bold]" ...')
|
|
95
|
+
|
|
96
|
+
popenargs += (local_rel_path, remote_path)
|
|
97
|
+
verbose_check_call(
|
|
98
|
+
*popenargs,
|
|
99
|
+
verbose=True,
|
|
100
|
+
cwd=mpos_path,
|
|
101
|
+
text=None,
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
if reset:
|
|
105
|
+
time.sleep(1)
|
|
106
|
+
verbose_check_call(
|
|
107
|
+
mpremote_bin,
|
|
108
|
+
'reset',
|
|
109
|
+
verbose=True,
|
|
110
|
+
cwd=mpos_path,
|
|
111
|
+
text=None,
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
if repl:
|
|
115
|
+
time.sleep(1)
|
|
116
|
+
verbose_check_call(
|
|
117
|
+
mpremote_bin,
|
|
118
|
+
'repl',
|
|
119
|
+
verbose=True,
|
|
120
|
+
cwd=mpos_path,
|
|
121
|
+
timeout=None,
|
|
122
|
+
text=None,
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
@app.command
|
|
127
|
+
def cp_app(
|
|
128
|
+
reset: Annotated[
|
|
129
|
+
bool,
|
|
130
|
+
tyro.conf.arg(help='Reset the device after copy/update?'),
|
|
131
|
+
] = True,
|
|
132
|
+
repl: Annotated[
|
|
133
|
+
bool,
|
|
134
|
+
tyro.conf.arg(help='After flashing/verify start REPL with mpremote to see the output of the device?'),
|
|
135
|
+
] = True,
|
|
136
|
+
verbosity: TyroVerbosityArgType = 1,
|
|
137
|
+
):
|
|
138
|
+
"""
|
|
139
|
+
Copy/update internal_filesystem/apps to the device via "mpremote fs cp".
|
|
140
|
+
Display a file chooser to select which app to copy/update.
|
|
141
|
+
But can also be used to copy/update all files.
|
|
142
|
+
see: https://docs.micropythonos.com/os-development/installing-on-esp32/
|
|
143
|
+
"""
|
|
144
|
+
setup_logging(verbosity=verbosity)
|
|
145
|
+
|
|
146
|
+
mpos_path = get_mpos_path()
|
|
147
|
+
|
|
148
|
+
internal_fs = mpos_path / 'internal_filesystem'
|
|
149
|
+
apps_path = internal_fs / 'apps'
|
|
150
|
+
assert_is_dir(apps_path)
|
|
151
|
+
|
|
152
|
+
mpremote_bin = get_mpremote_bin()
|
|
153
|
+
popenargs = (mpremote_bin, 'fs', 'cp', '-r')
|
|
154
|
+
|
|
155
|
+
app = choose_newest_modified_directory(apps_path)
|
|
156
|
+
|
|
157
|
+
print('\n')
|
|
158
|
+
|
|
159
|
+
if not app:
|
|
160
|
+
print('Copy/update all apps in "internal_filesystem/apps" to the device')
|
|
161
|
+
local_rel_path = 'internal_filesystem/apps'
|
|
162
|
+
remote_path = ':/apps'
|
|
163
|
+
else:
|
|
164
|
+
print(f'Copy/update {app=} ...')
|
|
165
|
+
local_rel_path = f'internal_filesystem/apps/{app.name}'
|
|
166
|
+
remote_path = f':/apps/{app.name}'
|
|
167
|
+
|
|
168
|
+
popenargs += (local_rel_path, remote_path)
|
|
169
|
+
verbose_check_call(
|
|
170
|
+
*popenargs,
|
|
171
|
+
verbose=True,
|
|
172
|
+
cwd=mpos_path,
|
|
173
|
+
text=None,
|
|
174
|
+
)
|
|
175
|
+
|
|
176
|
+
if reset:
|
|
177
|
+
time.sleep(1)
|
|
178
|
+
verbose_check_call(
|
|
179
|
+
mpremote_bin,
|
|
180
|
+
'reset',
|
|
181
|
+
verbose=True,
|
|
182
|
+
cwd=mpos_path,
|
|
183
|
+
text=None,
|
|
184
|
+
)
|
|
185
|
+
|
|
186
|
+
if repl:
|
|
187
|
+
time.sleep(1)
|
|
188
|
+
verbose_check_call(
|
|
189
|
+
mpremote_bin,
|
|
190
|
+
'repl',
|
|
191
|
+
verbose=True,
|
|
192
|
+
cwd=mpos_path,
|
|
193
|
+
timeout=None,
|
|
194
|
+
text=None,
|
|
195
|
+
)
|
|
@@ -5,7 +5,7 @@ import tyro
|
|
|
5
5
|
from cli_base.cli_tools.subprocess_utils import verbose_check_call
|
|
6
6
|
from cli_base.cli_tools.verbosity import setup_logging
|
|
7
7
|
from cli_base.tyro_commands import TyroVerbosityArgType
|
|
8
|
-
from rich import print
|
|
8
|
+
from rich import print
|
|
9
9
|
|
|
10
10
|
from mposcli.cli_app import app
|
|
11
11
|
from mposcli.mpos_utils import get_mpos_path
|
|
@@ -10,7 +10,7 @@ from bx_py_utils.path import assert_is_file
|
|
|
10
10
|
from cli_base.cli_tools.subprocess_utils import verbose_check_call
|
|
11
11
|
from cli_base.cli_tools.verbosity import setup_logging
|
|
12
12
|
from cli_base.tyro_commands import TyroVerbosityArgType
|
|
13
|
-
from rich import print
|
|
13
|
+
from rich import print
|
|
14
14
|
|
|
15
15
|
from mposcli.cli_app import app
|
|
16
16
|
from mposcli.fs_utils import list_executables
|
|
@@ -86,7 +86,8 @@ def run_desktop(
|
|
|
86
86
|
with config_file.open('r', encoding='utf-8') as f:
|
|
87
87
|
try:
|
|
88
88
|
config = json.load(f)
|
|
89
|
-
except
|
|
89
|
+
except json.JSONDecodeError as err:
|
|
90
|
+
logger.error('Error parsing config file: %s: %s', config_file, err)
|
|
90
91
|
config = {}
|
|
91
92
|
else:
|
|
92
93
|
config = {}
|
|
@@ -3,7 +3,7 @@ import logging
|
|
|
3
3
|
from cli_base.cli_tools.git import Git
|
|
4
4
|
from cli_base.cli_tools.verbosity import setup_logging
|
|
5
5
|
from cli_base.tyro_commands import TyroVerbosityArgType
|
|
6
|
-
from rich import print
|
|
6
|
+
from rich import print
|
|
7
7
|
|
|
8
8
|
from mposcli.cli_app import app
|
|
9
9
|
from mposcli.mpos_utils import get_mpos_path
|
|
@@ -20,9 +20,9 @@ def update_test_snapshot_files(verbosity: TyroVerbosityArgType):
|
|
|
20
20
|
with UpdateTestSnapshotFiles(root_path=PACKAGE_ROOT, verbose=verbosity > 0):
|
|
21
21
|
# Just recreate them by running tests:
|
|
22
22
|
run_unittest_cli(
|
|
23
|
-
extra_env=
|
|
24
|
-
RAISE_SNAPSHOT_ERRORS
|
|
25
|
-
|
|
23
|
+
extra_env={
|
|
24
|
+
'RAISE_SNAPSHOT_ERRORS': '0', # Recreate snapshot files without error
|
|
25
|
+
},
|
|
26
26
|
verbose=verbosity > 1,
|
|
27
27
|
exit_after_run=False,
|
|
28
28
|
)
|
|
@@ -5,7 +5,7 @@ from pathlib import Path
|
|
|
5
5
|
from cli_base.cli_tools import git_history
|
|
6
6
|
from cli_base.cli_tools.verbosity import setup_logging
|
|
7
7
|
from cli_base.tyro_commands import TyroVerbosityArgType
|
|
8
|
-
from rich import print
|
|
8
|
+
from rich import print
|
|
9
9
|
|
|
10
10
|
from mposcli.cli_dev import app
|
|
11
11
|
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import os
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
logger = logging.getLogger(__name__)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def iter_files(directory):
|
|
10
|
+
with os.scandir(directory) as it:
|
|
11
|
+
for entry in it:
|
|
12
|
+
if entry.is_file(follow_symlinks=False):
|
|
13
|
+
yield entry
|
|
14
|
+
elif entry.is_dir(follow_symlinks=False):
|
|
15
|
+
yield from iter_files(entry.path)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def list_executables(directory: Path) -> list[Path]:
|
|
19
|
+
executables = []
|
|
20
|
+
for entry in directory.iterdir():
|
|
21
|
+
if entry.is_file():
|
|
22
|
+
if os.access(entry, os.X_OK):
|
|
23
|
+
executables.append(entry)
|
|
24
|
+
else:
|
|
25
|
+
logger.info('Skipping non-executable file: %s', entry)
|
|
26
|
+
return executables
|
|
@@ -2,7 +2,7 @@ import logging
|
|
|
2
2
|
import sys
|
|
3
3
|
from pathlib import Path
|
|
4
4
|
|
|
5
|
-
from rich import print
|
|
5
|
+
from rich import print
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
logger = logging.getLogger(__name__)
|
|
@@ -24,5 +24,5 @@ def get_mpos_path() -> Path:
|
|
|
24
24
|
print('Hint: Call "mposcli" only in the root directory of a MicroPythonOS project!')
|
|
25
25
|
sys.exit(1)
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
return current_path
|
|
28
|
+
|
|
@@ -4,7 +4,7 @@ from pathlib import Path
|
|
|
4
4
|
|
|
5
5
|
from bx_py_utils.test_utils.deny_requests import deny_any_real_request
|
|
6
6
|
from cli_base.cli_tools.verbosity import MAX_LOG_LEVEL, setup_logging
|
|
7
|
-
from rich import print
|
|
7
|
+
from rich import print
|
|
8
8
|
from typeguard import install_import_hook
|
|
9
9
|
|
|
10
10
|
|
|
@@ -17,7 +17,7 @@ def pre_configure_tests() -> None:
|
|
|
17
17
|
|
|
18
18
|
# Hacky way to display more "assert"-Context in failing tests:
|
|
19
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'
|
|
20
|
+
unittest.util._MAX_LENGTH = int(os.environ.get('UNITTEST_MAX_LENGTH') or 2000)
|
|
21
21
|
unittest.util._MIN_DIFF_LEN = unittest.util._MAX_LENGTH - _MIN_MAX_DIFF
|
|
22
22
|
|
|
23
23
|
# Deny any request via docket/urllib3 because tests they should mock all requests:
|
|
@@ -79,11 +79,11 @@ class ReadmeTestCase(BaseTestCase):
|
|
|
79
79
|
|
|
80
80
|
# Dynamically build command list from app object
|
|
81
81
|
# tyro SubcommandApp stores subcommands in _subcommands dict
|
|
82
|
-
commands =
|
|
82
|
+
commands = {command.replace('_', '-') for command in app._subcommands}
|
|
83
83
|
|
|
84
84
|
commands.discard('version') # version is pseudo command, because the version always printed on every CLI call
|
|
85
85
|
commands = sorted(commands)
|
|
86
|
-
self.assertEqual(commands, ['build', 'cp', 'flash', 'run-desktop', 'update', 'update-submodules'])
|
|
86
|
+
self.assertEqual(commands, ['build', 'cp', 'cp-app', 'flash', 'run-desktop', 'update', 'update-submodules'])
|
|
87
87
|
|
|
88
88
|
for command in commands:
|
|
89
89
|
with self.subTest(command):
|