littlefs-python 0.15.0__tar.gz → 0.17.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.
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/.github/workflows/deploy.yml +11 -10
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/.github/workflows/run-tests.yml +2 -2
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/PKG-INFO +15 -3
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/README.rst +14 -2
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/src/littlefs/__init__.py +2 -1
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/src/littlefs/__main__.py +57 -1
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/src/littlefs/context.py +55 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/src/littlefs/lfs.c +9402 -9403
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/src/littlefs/lfs.pxd +1 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/src/littlefs/lfs.pyi +5 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/src/littlefs/lfs.pyx +8 -0
- littlefs_python-0.17.0/src/littlefs/repl.py +281 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/src/littlefs_python.egg-info/PKG-INFO +15 -3
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/src/littlefs_python.egg-info/SOURCES.txt +2 -0
- littlefs_python-0.17.0/test/test_context.py +41 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/.gitattributes +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/.github/dependabot.yml +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/.gitignore +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/.gitmodules +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/.pre-commit-config.yaml +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/.readthedocs.yml +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/LICENSE +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/MANIFEST.in +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/ci/build-wheels.sh +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/ci/download_release_files.py +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/docs/Makefile +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/docs/api/index.rst +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/docs/cli.rst +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/docs/conf.py +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/docs/doc8.ini +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/docs/examples/index.rst +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/docs/index.rst +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/docs/make.bat +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/docs/requirements.txt +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/docs/usage.rst +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/examples/mkfsimg.py +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/examples/walk.py +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/littlefs/.git +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/littlefs/.gitattributes +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/littlefs/.github/workflows/post-release.yml +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/littlefs/.github/workflows/release.yml +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/littlefs/.github/workflows/status.yml +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/littlefs/.github/workflows/test.yml +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/littlefs/.gitignore +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/littlefs/DESIGN.md +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/littlefs/LICENSE.md +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/littlefs/Makefile +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/littlefs/README.md +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/littlefs/SPEC.md +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/littlefs/bd/lfs_emubd.c +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/littlefs/bd/lfs_emubd.h +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/littlefs/bd/lfs_filebd.c +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/littlefs/bd/lfs_filebd.h +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/littlefs/bd/lfs_rambd.c +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/littlefs/bd/lfs_rambd.h +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/littlefs/benches/bench_dir.toml +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/littlefs/benches/bench_file.toml +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/littlefs/benches/bench_superblock.toml +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/littlefs/lfs.c +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/littlefs/lfs.h +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/littlefs/lfs_util.c +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/littlefs/lfs_util.h +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/littlefs/runners/bench_runner.c +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/littlefs/runners/bench_runner.h +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/littlefs/runners/test_runner.c +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/littlefs/runners/test_runner.h +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/littlefs/scripts/bench.py +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/littlefs/scripts/changeprefix.py +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/littlefs/scripts/code.py +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/littlefs/scripts/cov.py +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/littlefs/scripts/data.py +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/littlefs/scripts/perf.py +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/littlefs/scripts/perfbd.py +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/littlefs/scripts/plot.py +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/littlefs/scripts/plotmpl.py +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/littlefs/scripts/prettyasserts.py +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/littlefs/scripts/readblock.py +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/littlefs/scripts/readmdir.py +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/littlefs/scripts/readtree.py +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/littlefs/scripts/stack.py +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/littlefs/scripts/structs.py +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/littlefs/scripts/summary.py +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/littlefs/scripts/tailpipe.py +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/littlefs/scripts/teepipe.py +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/littlefs/scripts/test.py +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/littlefs/scripts/tracebd.py +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/littlefs/scripts/watch.py +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/littlefs/tests/test_alloc.toml +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/littlefs/tests/test_attrs.toml +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/littlefs/tests/test_badblocks.toml +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/littlefs/tests/test_bd.toml +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/littlefs/tests/test_compat.toml +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/littlefs/tests/test_dirs.toml +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/littlefs/tests/test_entries.toml +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/littlefs/tests/test_evil.toml +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/littlefs/tests/test_exhaustion.toml +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/littlefs/tests/test_files.toml +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/littlefs/tests/test_interspersed.toml +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/littlefs/tests/test_move.toml +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/littlefs/tests/test_orphans.toml +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/littlefs/tests/test_paths.toml +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/littlefs/tests/test_powerloss.toml +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/littlefs/tests/test_relocations.toml +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/littlefs/tests/test_seek.toml +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/littlefs/tests/test_shrink.toml +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/littlefs/tests/test_superblocks.toml +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/littlefs/tests/test_truncate.toml +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/mypy.ini +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/pyproject.toml +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/requirements.txt +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/setup.cfg +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/setup.py +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/src/littlefs/errors.py +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/src/littlefs/py.typed +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/src/littlefs_python.egg-info/dependency_links.txt +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/src/littlefs_python.egg-info/entry_points.txt +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/src/littlefs_python.egg-info/not-zip-safe +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/src/littlefs_python.egg-info/requires.txt +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/src/littlefs_python.egg-info/top_level.txt +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/test/lfs/conftest.py +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/test/lfs/test_dir_functions.py +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/test/lfs/test_file_functions.py +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/test/lfs/test_fs_functions.py +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/test/test_attr.py +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/test/test_block_count.py +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/test/test_directories.py +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/test/test_files.py +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/test/test_grow.py +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/test/test_multiversion.py +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/test/test_name_max.py +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/test/test_remove_rename.py +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/test/test_version.py +0 -0
- {littlefs_python-0.15.0 → littlefs_python-0.17.0}/test/test_walk.py +0 -0
|
@@ -15,7 +15,7 @@ jobs:
|
|
|
15
15
|
runs-on: ${{ matrix.os }}
|
|
16
16
|
strategy:
|
|
17
17
|
matrix:
|
|
18
|
-
os: [ubuntu-22.04, macos-
|
|
18
|
+
os: [ubuntu-22.04, macos-15-intel, windows-latest]
|
|
19
19
|
|
|
20
20
|
env:
|
|
21
21
|
CIBW_BUILD: "cp38-* cp39-* cp310-* cp311-* cp312-* cp313-* cp314-*"
|
|
@@ -23,7 +23,7 @@ jobs:
|
|
|
23
23
|
CIBW_ARCHS_LINUX: "x86_64 i686 aarch64"
|
|
24
24
|
|
|
25
25
|
steps:
|
|
26
|
-
- uses: actions/checkout@
|
|
26
|
+
- uses: actions/checkout@v6
|
|
27
27
|
with:
|
|
28
28
|
submodules: "recursive"
|
|
29
29
|
fetch-depth: 0
|
|
@@ -35,9 +35,9 @@ jobs:
|
|
|
35
35
|
platforms: all
|
|
36
36
|
|
|
37
37
|
- name: Build wheels
|
|
38
|
-
uses: pypa/cibuildwheel@v3.
|
|
38
|
+
uses: pypa/cibuildwheel@v3.3.0
|
|
39
39
|
|
|
40
|
-
- uses: actions/upload-artifact@
|
|
40
|
+
- uses: actions/upload-artifact@v6
|
|
41
41
|
with:
|
|
42
42
|
name: wheels-${{ matrix.os }}
|
|
43
43
|
path: ./wheelhouse/*.whl
|
|
@@ -51,13 +51,13 @@ jobs:
|
|
|
51
51
|
cibw_archs: ["arm64"]
|
|
52
52
|
|
|
53
53
|
steps:
|
|
54
|
-
- uses: actions/checkout@
|
|
54
|
+
- uses: actions/checkout@v6
|
|
55
55
|
with:
|
|
56
56
|
submodules: "recursive"
|
|
57
57
|
fetch-depth: 0
|
|
58
58
|
|
|
59
59
|
- name: Build wheels
|
|
60
|
-
uses: pypa/cibuildwheel@v3.
|
|
60
|
+
uses: pypa/cibuildwheel@v3.3.0
|
|
61
61
|
env:
|
|
62
62
|
CIBW_BUILD: ${{ matrix.cibw_build }}
|
|
63
63
|
CIBW_SKIP: "pp*"
|
|
@@ -84,7 +84,7 @@ jobs:
|
|
|
84
84
|
delocate-listdeps --all {dest_dir}/$WHEEL_SIMPLE_FILENAME
|
|
85
85
|
|
|
86
86
|
echo "DONE."
|
|
87
|
-
- uses: actions/upload-artifact@
|
|
87
|
+
- uses: actions/upload-artifact@v6
|
|
88
88
|
with:
|
|
89
89
|
name: wheels-macos-arm64
|
|
90
90
|
path: ./wheelhouse/*.whl
|
|
@@ -93,7 +93,7 @@ jobs:
|
|
|
93
93
|
name: Build source distribution
|
|
94
94
|
runs-on: ubuntu-22.04
|
|
95
95
|
steps:
|
|
96
|
-
- uses: actions/checkout@
|
|
96
|
+
- uses: actions/checkout@v6
|
|
97
97
|
with:
|
|
98
98
|
submodules: "recursive"
|
|
99
99
|
fetch-depth: 0
|
|
@@ -103,7 +103,7 @@ jobs:
|
|
|
103
103
|
pip install build
|
|
104
104
|
python -m build . --sdist
|
|
105
105
|
|
|
106
|
-
- uses: actions/upload-artifact@
|
|
106
|
+
- uses: actions/upload-artifact@v6
|
|
107
107
|
with:
|
|
108
108
|
name: wheels-sdist
|
|
109
109
|
path: dist/*.tar.gz
|
|
@@ -113,7 +113,7 @@ jobs:
|
|
|
113
113
|
runs-on: ubuntu-22.04
|
|
114
114
|
if: ${{ inputs.upload_to_pypi }}
|
|
115
115
|
steps:
|
|
116
|
-
- uses: actions/download-artifact@
|
|
116
|
+
- uses: actions/download-artifact@v7
|
|
117
117
|
with:
|
|
118
118
|
path: dist
|
|
119
119
|
pattern: wheels-*
|
|
@@ -123,3 +123,4 @@ jobs:
|
|
|
123
123
|
with:
|
|
124
124
|
user: __token__
|
|
125
125
|
password: ${{ secrets.pypi_api_token }}
|
|
126
|
+
skip-existing: true
|
|
@@ -14,11 +14,11 @@ jobs:
|
|
|
14
14
|
runs-on: ${{ matrix.os }}
|
|
15
15
|
strategy:
|
|
16
16
|
matrix:
|
|
17
|
-
os: [ubuntu-22.04, macos-
|
|
17
|
+
os: [ubuntu-22.04, macos-15, windows-latest]
|
|
18
18
|
python-version: [3.8, 3.9, "3.10", "3.11", "3.12", "3.13", "3.14"]
|
|
19
19
|
|
|
20
20
|
steps:
|
|
21
|
-
- uses: actions/checkout@
|
|
21
|
+
- uses: actions/checkout@v6
|
|
22
22
|
with:
|
|
23
23
|
submodules: "recursive"
|
|
24
24
|
- name: Set up Python ${{ matrix.python-version }}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: littlefs-python
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.17.0
|
|
4
4
|
Summary: A python wrapper for littlefs
|
|
5
5
|
Home-page: https://github.com/jrast/littlefs-python
|
|
6
6
|
Author: Jürg Rast
|
|
@@ -136,7 +136,7 @@ littlefs-python comes bundled with a command-line tool, ``littlefs-python``, tha
|
|
|
136
136
|
.. code:: console
|
|
137
137
|
|
|
138
138
|
$ littlefs-python --help
|
|
139
|
-
usage: littlefs-python [-h] [--version] {create,extract,list} ...
|
|
139
|
+
usage: littlefs-python [-h] [--version] {create,extract,list,repl} ...
|
|
140
140
|
|
|
141
141
|
Create, extract and inspect LittleFS filesystem images. Use one of the
|
|
142
142
|
commands listed below, the '-h' / '--help' option can be used on each command
|
|
@@ -147,10 +147,11 @@ littlefs-python comes bundled with a command-line tool, ``littlefs-python``, tha
|
|
|
147
147
|
--version show program's version number and exit
|
|
148
148
|
|
|
149
149
|
Available Commands:
|
|
150
|
-
{create,extract,list}
|
|
150
|
+
{create,extract,list,repl}
|
|
151
151
|
create Create LittleFS image from file/directory contents.
|
|
152
152
|
extract Extract LittleFS image contents to a directory.
|
|
153
153
|
list List LittleFS image contents.
|
|
154
|
+
repl Inspect an existing LittleFS image through an interactive shell.
|
|
154
155
|
|
|
155
156
|
To create a littlefs binary image:
|
|
156
157
|
|
|
@@ -168,6 +169,17 @@ To extract the contents of a littlefs binary image:
|
|
|
168
169
|
|
|
169
170
|
$ littlefs-python extract lfs.bin output/ --block-size=4096
|
|
170
171
|
|
|
172
|
+
To inspect or debug an existing image without extracting it first you can start a
|
|
173
|
+
simple REPL. It provides shell-like commands such as ``ls``, ``tree``, ``put``, ``get``
|
|
174
|
+
and ``rm`` that operate directly on the image data:
|
|
175
|
+
|
|
176
|
+
.. code:: console
|
|
177
|
+
|
|
178
|
+
$ littlefs-python repl lfs.bin --block-size=4096
|
|
179
|
+
Mounted remote littlefs.
|
|
180
|
+
littlefs> ls
|
|
181
|
+
README.rst
|
|
182
|
+
|
|
171
183
|
Development Setup
|
|
172
184
|
=================
|
|
173
185
|
|
|
@@ -103,7 +103,7 @@ littlefs-python comes bundled with a command-line tool, ``littlefs-python``, tha
|
|
|
103
103
|
.. code:: console
|
|
104
104
|
|
|
105
105
|
$ littlefs-python --help
|
|
106
|
-
usage: littlefs-python [-h] [--version] {create,extract,list} ...
|
|
106
|
+
usage: littlefs-python [-h] [--version] {create,extract,list,repl} ...
|
|
107
107
|
|
|
108
108
|
Create, extract and inspect LittleFS filesystem images. Use one of the
|
|
109
109
|
commands listed below, the '-h' / '--help' option can be used on each command
|
|
@@ -114,10 +114,11 @@ littlefs-python comes bundled with a command-line tool, ``littlefs-python``, tha
|
|
|
114
114
|
--version show program's version number and exit
|
|
115
115
|
|
|
116
116
|
Available Commands:
|
|
117
|
-
{create,extract,list}
|
|
117
|
+
{create,extract,list,repl}
|
|
118
118
|
create Create LittleFS image from file/directory contents.
|
|
119
119
|
extract Extract LittleFS image contents to a directory.
|
|
120
120
|
list List LittleFS image contents.
|
|
121
|
+
repl Inspect an existing LittleFS image through an interactive shell.
|
|
121
122
|
|
|
122
123
|
To create a littlefs binary image:
|
|
123
124
|
|
|
@@ -135,6 +136,17 @@ To extract the contents of a littlefs binary image:
|
|
|
135
136
|
|
|
136
137
|
$ littlefs-python extract lfs.bin output/ --block-size=4096
|
|
137
138
|
|
|
139
|
+
To inspect or debug an existing image without extracting it first you can start a
|
|
140
|
+
simple REPL. It provides shell-like commands such as ``ls``, ``tree``, ``put``, ``get``
|
|
141
|
+
and ``rm`` that operate directly on the image data:
|
|
142
|
+
|
|
143
|
+
.. code:: console
|
|
144
|
+
|
|
145
|
+
$ littlefs-python repl lfs.bin --block-size=4096
|
|
146
|
+
Mounted remote littlefs.
|
|
147
|
+
littlefs> ls
|
|
148
|
+
README.rst
|
|
149
|
+
|
|
138
150
|
Development Setup
|
|
139
151
|
=================
|
|
140
152
|
|
|
@@ -34,6 +34,7 @@ __all__ = [
|
|
|
34
34
|
"LittleFS",
|
|
35
35
|
"LittleFSError",
|
|
36
36
|
"UserContext",
|
|
37
|
+
"UserContextFile",
|
|
37
38
|
"UserContextWinDisk",
|
|
38
39
|
"__LFS_DISK_VERSION__",
|
|
39
40
|
"__LFS_VERSION__",
|
|
@@ -48,7 +49,7 @@ except PackageNotFoundError:
|
|
|
48
49
|
# Package not installed
|
|
49
50
|
pass
|
|
50
51
|
|
|
51
|
-
from .context import UserContext, UserContextWinDisk
|
|
52
|
+
from .context import UserContext, UserContextFile, UserContextWinDisk
|
|
52
53
|
|
|
53
54
|
if TYPE_CHECKING:
|
|
54
55
|
from .lfs import LFSStat
|
|
@@ -6,6 +6,8 @@ import textwrap
|
|
|
6
6
|
|
|
7
7
|
from littlefs import LittleFS, __version__
|
|
8
8
|
from littlefs.errors import LittleFSError
|
|
9
|
+
from littlefs.repl import LittleFSRepl
|
|
10
|
+
from littlefs.context import UserContextFile
|
|
9
11
|
|
|
10
12
|
# Dictionary mapping suffixes to their size in bytes
|
|
11
13
|
_suffix_map = {
|
|
@@ -110,7 +112,7 @@ def create(parser: argparse.ArgumentParser, args: argparse.Namespace) -> int:
|
|
|
110
112
|
compact_fs.fs_grow(args.block_count)
|
|
111
113
|
data = compact_fs.context.buffer
|
|
112
114
|
if not args.no_pad:
|
|
113
|
-
data = data.ljust(args.fs_size, b"\
|
|
115
|
+
data = data.ljust(args.fs_size, b"\xff")
|
|
114
116
|
else:
|
|
115
117
|
data = fs.context.buffer
|
|
116
118
|
|
|
@@ -188,6 +190,47 @@ def extract(parser: argparse.ArgumentParser, args: argparse.Namespace) -> int:
|
|
|
188
190
|
return 0
|
|
189
191
|
|
|
190
192
|
|
|
193
|
+
def repl(parser: argparse.ArgumentParser, args: argparse.Namespace) -> int:
|
|
194
|
+
"""Inspect an existing LittleFS image through an interactive shell."""
|
|
195
|
+
|
|
196
|
+
source: Path = args.source
|
|
197
|
+
if not source.is_file():
|
|
198
|
+
parser.error(f"Source image '{source}' does not exist.")
|
|
199
|
+
|
|
200
|
+
image_size = source.stat().st_size
|
|
201
|
+
if not image_size or image_size % args.block_size:
|
|
202
|
+
parser.error(
|
|
203
|
+
f"Image size ({image_size} bytes) is not a multiple of the supplied block size ({args.block_size})."
|
|
204
|
+
)
|
|
205
|
+
|
|
206
|
+
block_count = image_size // args.block_size
|
|
207
|
+
if block_count == 0:
|
|
208
|
+
parser.error("Image is smaller than a single block; cannot mount.")
|
|
209
|
+
|
|
210
|
+
context = UserContextFile(str(source))
|
|
211
|
+
fs = LittleFS(
|
|
212
|
+
context=context,
|
|
213
|
+
block_size=args.block_size,
|
|
214
|
+
block_count=block_count,
|
|
215
|
+
name_max=args.name_max,
|
|
216
|
+
mount=False,
|
|
217
|
+
)
|
|
218
|
+
|
|
219
|
+
shell = LittleFSRepl(fs)
|
|
220
|
+
try:
|
|
221
|
+
try:
|
|
222
|
+
shell.do_mount()
|
|
223
|
+
except LittleFSError as exc:
|
|
224
|
+
parser.error(f"Failed to mount '{source}': {exc}")
|
|
225
|
+
shell.cmdloop()
|
|
226
|
+
finally:
|
|
227
|
+
if shell._mounted:
|
|
228
|
+
with suppress(LittleFSError):
|
|
229
|
+
fs.unmount()
|
|
230
|
+
|
|
231
|
+
return 0
|
|
232
|
+
|
|
233
|
+
|
|
191
234
|
def get_parser():
|
|
192
235
|
if sys.argv[0].endswith("__main__.py"):
|
|
193
236
|
prog = f"python -m littlefs"
|
|
@@ -299,6 +342,19 @@ def get_parser():
|
|
|
299
342
|
help="LittleFS block size.",
|
|
300
343
|
)
|
|
301
344
|
|
|
345
|
+
parser_repl = add_command(repl)
|
|
346
|
+
parser_repl.add_argument(
|
|
347
|
+
"source",
|
|
348
|
+
type=Path,
|
|
349
|
+
help="Source LittleFS filesystem binary.",
|
|
350
|
+
)
|
|
351
|
+
parser_repl.add_argument(
|
|
352
|
+
"--block-size",
|
|
353
|
+
type=size_parser,
|
|
354
|
+
required=True,
|
|
355
|
+
help="LittleFS block size.",
|
|
356
|
+
)
|
|
357
|
+
|
|
302
358
|
return parser
|
|
303
359
|
|
|
304
360
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
import typing
|
|
3
3
|
import ctypes
|
|
4
|
+
import os
|
|
4
5
|
|
|
5
6
|
if typing.TYPE_CHECKING:
|
|
6
7
|
from .lfs import LFSConfig
|
|
@@ -78,6 +79,60 @@ class UserContext:
|
|
|
78
79
|
return 0
|
|
79
80
|
|
|
80
81
|
|
|
82
|
+
class UserContextFile(UserContext):
|
|
83
|
+
"""File-backed context using the standard library"""
|
|
84
|
+
|
|
85
|
+
def __init__(self, file_path: str, *, create: bool = False) -> None:
|
|
86
|
+
mode = "r+b"
|
|
87
|
+
if not os.path.exists(file_path):
|
|
88
|
+
if not create:
|
|
89
|
+
raise FileNotFoundError(f"Context file '{file_path}' does not exist")
|
|
90
|
+
mode = "w+b"
|
|
91
|
+
|
|
92
|
+
self._path = file_path
|
|
93
|
+
self._fh = open(file_path, mode)
|
|
94
|
+
|
|
95
|
+
def read(self, cfg: "LFSConfig", block: int, off: int, size: int) -> bytearray:
|
|
96
|
+
logging.getLogger(__name__).debug("LFS Read : Block: %d, Offset: %d, Size=%d" % (block, off, size))
|
|
97
|
+
start = block * cfg.block_size + off
|
|
98
|
+
self._fh.seek(start)
|
|
99
|
+
data = self._fh.read(size)
|
|
100
|
+
|
|
101
|
+
if len(data) < size:
|
|
102
|
+
data += b"\xff" * (size - len(data))
|
|
103
|
+
|
|
104
|
+
return bytearray(data)
|
|
105
|
+
|
|
106
|
+
def prog(self, cfg: "LFSConfig", block: int, off: int, data: bytes) -> int:
|
|
107
|
+
logging.getLogger(__name__).debug("LFS Prog : Block: %d, Offset: %d, Data=%r" % (block, off, data))
|
|
108
|
+
start = block * cfg.block_size + off
|
|
109
|
+
self._fh.seek(start)
|
|
110
|
+
self._fh.write(data)
|
|
111
|
+
return 0
|
|
112
|
+
|
|
113
|
+
def erase(self, cfg: "LFSConfig", block: int) -> int:
|
|
114
|
+
logging.getLogger(__name__).debug("LFS Erase: Block: %d" % block)
|
|
115
|
+
start = block * cfg.block_size
|
|
116
|
+
self._fh.seek(start)
|
|
117
|
+
self._fh.write(b"\xff" * cfg.block_size)
|
|
118
|
+
return 0
|
|
119
|
+
|
|
120
|
+
def sync(self, cfg: "LFSConfig") -> int:
|
|
121
|
+
self._fh.flush()
|
|
122
|
+
os.fsync(self._fh.fileno())
|
|
123
|
+
return 0
|
|
124
|
+
|
|
125
|
+
def close(self) -> None:
|
|
126
|
+
if not self._fh.closed:
|
|
127
|
+
self._fh.close()
|
|
128
|
+
|
|
129
|
+
def __del__(self):
|
|
130
|
+
try:
|
|
131
|
+
self.close()
|
|
132
|
+
except Exception:
|
|
133
|
+
pass
|
|
134
|
+
|
|
135
|
+
|
|
81
136
|
try:
|
|
82
137
|
import win32file
|
|
83
138
|
except ImportError:
|