From 49a81c77d79fabd27e893566a32778b08074a594 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Sat, 18 Oct 2025 21:43:08 +0200 Subject: [PATCH] package/python-pyfatfs: new package This commit adds a new host package for python-pyfatfs, which is needed by Snagboot. Homepage: https://pypi.org/project/pyfatfs/ A small test doing some minimal verification that pyfatfs works is also added. Signed-off-by: Thomas Petazzoni Signed-off-by: Julien Olivain --- DEVELOPERS | 2 + ...oject.toml-relax-version-constraints.patch | 45 ++++++++++++++++ package/python-pyfatfs/python-pyfatfs.hash | 4 ++ package/python-pyfatfs/python-pyfatfs.mk | 17 ++++++ .../tests/package/test_python_pyfatfs.py | 53 +++++++++++++++++++ 5 files changed, 121 insertions(+) create mode 100644 package/python-pyfatfs/0001-pyproject.toml-relax-version-constraints.patch create mode 100644 package/python-pyfatfs/python-pyfatfs.hash create mode 100644 package/python-pyfatfs/python-pyfatfs.mk create mode 100644 support/testing/tests/package/test_python_pyfatfs.py diff --git a/DEVELOPERS b/DEVELOPERS index cca984780a..fa9fe7bbe2 100644 --- a/DEVELOPERS +++ b/DEVELOPERS @@ -3259,6 +3259,7 @@ F: package/python-crccheck/ F: package/python-flask-expects-json/ F: package/python-fs/ F: package/python-git/ +F: package/python-pyfatfs/ F: package/python-qrcode/ F: package/python-serial/ F: package/python-unittest-xml-reporting/ @@ -3291,6 +3292,7 @@ F: support/testing/tests/package/test_python_flask.py F: support/testing/tests/package/test_python_flask_expects_json.py F: support/testing/tests/package/test_python_fs.py F: support/testing/tests/package/test_python_git.py +F: support/testing/tests/package/test_python_pyfatfs.py F: support/testing/tests/package/test_python_pyusb.py F: support/testing/tests/package/test_python_serial.py F: support/testing/tests/package/test_python_unittest_xml_reporting.py diff --git a/package/python-pyfatfs/0001-pyproject.toml-relax-version-constraints.patch b/package/python-pyfatfs/0001-pyproject.toml-relax-version-constraints.patch new file mode 100644 index 0000000000..791401f876 --- /dev/null +++ b/package/python-pyfatfs/0001-pyproject.toml-relax-version-constraints.patch @@ -0,0 +1,45 @@ +From 9d40ef086d25c8434adcf6552de1d8bb5022a277 Mon Sep 17 00:00:00 2001 +From: Thomas Petazzoni +Date: Mon, 22 Sep 2025 23:27:47 +0200 +Subject: [PATCH] pyproject.toml: relax version constraints + +The version constraints defined with ~= in pyproject.toml are too +strict, and don't allow using pyfatfs with newer versions. + +We have successfully tested with: + +- setuptools 80.9.0 +- setuptools-scm 8.3.1 +- python 3.13 +- fs 2.4.16 + +Upstream: https://github.com/nathanhi/pyfatfs/pull/47 +Signed-off-by: Thomas Petazzoni +--- + pyproject.toml | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/pyproject.toml b/pyproject.toml +index 9649c10..a6eb198 100644 +--- a/pyproject.toml ++++ b/pyproject.toml +@@ -1,13 +1,13 @@ + [build-system] +-requires = ["setuptools ~= 67.8", "setuptools_scm[toml] ~= 7.1"] ++requires = ["setuptools >= 67.8", "setuptools_scm[toml] >= 7.1"] + build-backend = "setuptools.build_meta" + + [project] + name = "pyfatfs" + description = "FAT12/FAT16/FAT32 implementation with VFAT support" + readme = "README.rst" +-requires-python = "~=3.8" +-dependencies = ["fs~=2.4"] ++requires-python = ">=3.8" ++dependencies = ["fs>=2.4"] + keywords = ["filesystem", "PyFilesystem2", "FAT12", "FAT16", "FAT32", "VFAT", "LFN"] + license = {file = "LICENSE"} + classifiers = [ +-- +2.51.0 + diff --git a/package/python-pyfatfs/python-pyfatfs.hash b/package/python-pyfatfs/python-pyfatfs.hash new file mode 100644 index 0000000000..05e940779e --- /dev/null +++ b/package/python-pyfatfs/python-pyfatfs.hash @@ -0,0 +1,4 @@ +# From https://pypi.org/project/pyfatfs/#pyfatfs-1.1.0.tar.gz +sha256 9725ccd0a4da1c09c27358abbf10f08c043ac84210af576803e087f51a2b30e0 pyfatfs-1.1.0.tar.gz +# Locally calculated +sha256 df8f053d3cbf23fe7002e6a34b06580653a74d40dc2e54f3b717a963ea9b70cb LICENSE diff --git a/package/python-pyfatfs/python-pyfatfs.mk b/package/python-pyfatfs/python-pyfatfs.mk new file mode 100644 index 0000000000..a61fb1afb2 --- /dev/null +++ b/package/python-pyfatfs/python-pyfatfs.mk @@ -0,0 +1,17 @@ +################################################################################ +# +# python-pyfatfs +# +################################################################################ + +PYTHON_PYFATFS_VERSION = 1.1.0 +PYTHON_PYFATFS_SOURCE = pyfatfs-$(PYTHON_PYFATFS_VERSION).tar.gz +PYTHON_PYFATFS_SITE = https://files.pythonhosted.org/packages/44/3f/d08f1dbc44a7eef9c7fb355b83423fbd15bb3e487c250479a2c179cb39bf +PYTHON_PYFATFS_LICENSE = MIT +PYTHON_PYFATFS_LICENSE_FILES = LICENSE +PYTHON_PYFATFS_SETUP_TYPE = setuptools +# host-python-fs is not a build time dependency, but is needed at +# runtime for host-python-pyfatfs to work +HOST_PYTHON_PYFATFS_DEPENDENCIES = host-python-setuptools-scm host-python-fs + +$(eval $(host-python-package)) diff --git a/support/testing/tests/package/test_python_pyfatfs.py b/support/testing/tests/package/test_python_pyfatfs.py new file mode 100644 index 0000000000..ceb4e924a1 --- /dev/null +++ b/support/testing/tests/package/test_python_pyfatfs.py @@ -0,0 +1,53 @@ +import infra.basetest +import os + + +class TestHostPythonPyfatfs(infra.basetest.BRHostPkgTest): + hostpkgs = ["host-python-pyfatfs", + "host-genimage", + "host-dosfstools", + "host-mtools"] + config = infra.basetest.BASIC_TOOLCHAIN_CONFIG + infra.basetest.MINIMAL_CONFIG + \ + """ + BR2_PACKAGE_HOST_GENIMAGE=y + BR2_PACKAGE_HOST_DOSFSTOOLS=y + BR2_PACKAGE_HOST_MTOOLS=y + """ + + genimage_cfg = """ +image test.vfat { + vfat { + files = { + "test.txt" + } + } + + size = 8M +}""" + + def test_run(self): + os.makedirs(os.path.join(self.builddir, "genimage-input"), + exist_ok=True) + with open(os.path.join(self.builddir, "genimage-input", "test.txt"), "w") as f: + f.write("Hello World!") + with open(os.path.join(self.builddir, "genimage.cfg"), "w") as f: + f.write(self.genimage_cfg) + os.makedirs(os.path.join(self.builddir, "genimage-tmp"), + exist_ok=True) + os.makedirs(os.path.join(self.builddir, "genimage-root"), + exist_ok=True) + + cmd = ["host/bin/genimage", + "--config", os.path.join(self.builddir, "genimage.cfg"), + "--outputpath", self.builddir, + "--inputpath", os.path.join(self.builddir, "genimage-input"), + "--tmppath", os.path.join(self.builddir, "genimage-tmp"), + "--rootpath", os.path.join(self.builddir, "genimage-root"), + "--mkdosfs", os.path.join(self.builddir, "host", "sbin", "mkdosfs"), + "--mcopy", os.path.join(self.builddir, "host", "bin", "mcopy") + ] + infra.run_cmd_on_host(self.builddir, cmd) + + cmd = ["host/bin/python3", "-c", + "import fs; fatfs = fs.open_fs('fat://test.vfat'); assert(fatfs.listdir('/') == ['TEST.TXT'])"] + infra.run_cmd_on_host(self.builddir, cmd)