Compare commits

..

27 commits

Author SHA1 Message Date
Alex Pyrgiotis
3cf34e6182
Ruff fixes
Some checks failed
Tests / Download and cache Tesseract data (push) Has been cancelled
Tests / check-reproducibility (push) Has been cancelled
Tests / windows (push) Has been cancelled
Tests / macOS (arch64) (push) Has been cancelled
Tests / macOS (x86_64) (push) Has been cancelled
Tests / build-deb (debian bookworm) (push) Has been cancelled
Tests / build-deb (debian bullseye) (push) Has been cancelled
Tests / build-deb (debian trixie) (push) Has been cancelled
Tests / build-deb (ubuntu 20.04) (push) Has been cancelled
Tests / build-deb (ubuntu 22.04) (push) Has been cancelled
Tests / build-deb (ubuntu 24.04) (push) Has been cancelled
Tests / build-deb (ubuntu 24.10) (push) Has been cancelled
Tests / install-deb (debian bookworm) (push) Has been cancelled
Tests / install-deb (debian bullseye) (push) Has been cancelled
Tests / install-deb (debian trixie) (push) Has been cancelled
Tests / install-deb (ubuntu 20.04) (push) Has been cancelled
Tests / install-deb (ubuntu 22.04) (push) Has been cancelled
Tests / install-deb (ubuntu 24.04) (push) Has been cancelled
Tests / install-deb (ubuntu 24.10) (push) Has been cancelled
Tests / build-install-rpm (fedora 40) (push) Has been cancelled
Tests / build-install-rpm (fedora 41) (push) Has been cancelled
Tests / run tests (debian bookworm) (push) Has been cancelled
Tests / run tests (debian bullseye) (push) Has been cancelled
Tests / run tests (debian trixie) (push) Has been cancelled
Tests / run tests (fedora 40) (push) Has been cancelled
Tests / run tests (fedora 41) (push) Has been cancelled
Tests / run tests (ubuntu 20.04) (push) Has been cancelled
Tests / run tests (ubuntu 22.04) (push) Has been cancelled
Tests / run tests (ubuntu 24.04) (push) Has been cancelled
Tests / run tests (ubuntu 24.10) (push) Has been cancelled
2025-01-24 10:13:19 +02:00
Alex Pyrgiotis
414efb629f
WIP: Symlink /usr 2025-01-24 09:12:14 +02:00
Alex Pyrgiotis
6d6ac92371
FIXUP: Strip 'v' from image tag 2025-01-23 23:27:36 +02:00
Alex Pyrgiotis
df1ec758bc
Mask some extra paths in gVisor's OCI config
Mask some paths of the outer container in the OCI config of the inner
container. This is done to avoid leaking any sensitive information from
Podman / Docker / gVisor, since we reuse the same rootfs

Refs #1048
2025-01-23 23:27:36 +02:00
Alex Pyrgiotis
9e23802142
docs: Add design document for artifact reproducibility
Refs #1047
2025-01-23 23:27:36 +02:00
Alex Pyrgiotis
7e1f4bca6c
Update RELEASE.md
Co-authored-by: Alexis Métaireau <alexis@freedom.press>
2025-01-23 23:27:36 +02:00
Alex Pyrgiotis
a1383fa016
ci: Add a CI job that enforces image reproducibility
Add a CI job that uses the `reproduce.py` dev script to enforce image
reproducibility, for every PR that we send to the repo.

Fixes #1047
2025-01-23 23:27:36 +02:00
Alex Pyrgiotis
94a57f997e
dev_scripts: Add script for enforcing image reproducibility
Add a dev script for Linux platforms that verifies that a source image
can be reproducibly built from the current Git commit. The
reproducibility check is enforced by the `diffoci` tool, which is
downloaded as part of running the script.
2025-01-23 23:27:36 +02:00
Alex Pyrgiotis
ab10d5b6dd
Allow setting a tag for the container image
Allow setting a tag for the container image, when building it with the
`build-image.py` script. This should be used for development purposes
only, since the proper image name should be dictated by the script.
2025-01-23 23:27:36 +02:00
Alex Pyrgiotis
3ebc454b61
ci: Scan the latest image for CVEs
Update the Debian snapshot date to the current one, so that we always
scan the latest image for CVEs.

Refs #1057
2025-01-23 23:27:36 +02:00
Alex Pyrgiotis
20af68f7f2
Render the Dockerfile from a template and some params
Allow updating the Dockerfile from a template and some envs, so that
it's easier to bump the dates in it.
2025-01-23 23:27:34 +02:00
Alex Pyrgiotis
fa27f4b063
Add jinja2-cli package dependency
Add jinja2-cli as a package dependency, since it will be used to create
the Dockerfile from some user parameters and a template.
2025-01-23 23:26:56 +02:00
Alex Pyrgiotis
8e8a515b64
Allow using the container engine cache when building our image
Remove our suggestions for not using the container cache, which stemmed
from the fact that our Dangerzone image was not reproducible. Now that
we have switched to Debian Stable and the Dockerfile is all we need to
reproducibly build the exact same container image, we can just use the
cache to speed up builds.
2025-01-23 23:25:43 +02:00
Alex Pyrgiotis
270cae1bc0
Rename vendor-pymupdf.py to debian-vendor-pymupdf.py
Rename the `vendor-pymupdf.py` script to `debian-vendor-pymupdf.py`,
since it's used only when building Debian packages.
2025-01-23 23:25:43 +02:00
Alex Pyrgiotis
14bb6c0e39
Do not use poetry.lock when building the container image
Remove all the scaffolding in our `build-image.py` script for using the
`poetry.lock` file, now that we install PyMuPDF from the Debian repos.
2025-01-23 23:25:39 +02:00
Alex Pyrgiotis
033ce0986d
Switch base image to Debian Stable
Switch base image from Alpine Linux to Debian Stable, in order to reduce
our image footprint, improve our security posture, and build our
container image reproducibly.

Fixes #1046
Refs #1047
2025-01-23 23:24:48 +02:00
Alex Pyrgiotis
935396565c
Reuse the same rootfs for the inner and outer container
Remove the need to copy the Dangerzone container image (used by the
inner container) within a wrapper gVisor image (used by the outer
container). Instead, use the root of the container filesystem for both
containers. We can do this safely because we don't mount any secrets to
the container, and because gVisor offers a read-only view of the
underlying filesystem

Fixes #1048
2025-01-23 23:24:48 +02:00
Alex Pyrgiotis
e29837cb43
Copy gVisor public key and a helper script in container helpers
Download and copy the following artifacts that will be used for building
a Debian-based Dangerzone container image in the subsequent commits:
* The APT key for the gVisor repo [1]
* A helper script for building reproducible Debian images [2]

[1] https://gvisor.dev/archive.key
[2] d15cf12b26/repro-sources-list.sh
2025-01-23 23:24:48 +02:00
Alex Pyrgiotis
8568b4bb9d
Move container-only build context to dangerzone/container
Move container-only build context (currently just the entrypoint script)
from `dangerzone/gvisor_wrapper` to `dangerzone/container_helpers`.
Update the rest of the scripts to use this location as well.
2025-01-23 23:24:48 +02:00
Alex Pyrgiotis
be1fa7a395
Whitespace fixes 2025-01-23 23:24:47 +02:00
Alexis Métaireau
b2f4e2d523
Bump poetry.lock
Some checks are pending
Tests / windows (push) Blocked by required conditions
Tests / macOS (arch64) (push) Blocked by required conditions
Tests / macOS (x86_64) (push) Blocked by required conditions
Tests / build-deb (debian bookworm) (push) Blocked by required conditions
Tests / build-deb (debian bullseye) (push) Blocked by required conditions
Tests / build-deb (debian trixie) (push) Blocked by required conditions
Tests / build-deb (ubuntu 20.04) (push) Blocked by required conditions
Tests / build-deb (ubuntu 22.04) (push) Blocked by required conditions
Tests / build-deb (ubuntu 24.04) (push) Blocked by required conditions
Tests / build-deb (ubuntu 24.10) (push) Blocked by required conditions
Tests / install-deb (debian bookworm) (push) Blocked by required conditions
Tests / install-deb (debian bullseye) (push) Blocked by required conditions
Tests / install-deb (debian trixie) (push) Blocked by required conditions
Tests / install-deb (ubuntu 20.04) (push) Blocked by required conditions
Tests / install-deb (ubuntu 22.04) (push) Blocked by required conditions
Tests / install-deb (ubuntu 24.04) (push) Blocked by required conditions
Tests / install-deb (ubuntu 24.10) (push) Blocked by required conditions
Tests / build-install-rpm (fedora 40) (push) Blocked by required conditions
Tests / build-install-rpm (fedora 41) (push) Blocked by required conditions
Tests / run tests (debian bookworm) (push) Blocked by required conditions
Tests / run tests (debian bullseye) (push) Blocked by required conditions
Tests / run tests (debian trixie) (push) Blocked by required conditions
Tests / run tests (fedora 40) (push) Blocked by required conditions
Tests / run tests (fedora 41) (push) Blocked by required conditions
Tests / run tests (ubuntu 20.04) (push) Blocked by required conditions
Tests / run tests (ubuntu 22.04) (push) Blocked by required conditions
Tests / run tests (ubuntu 24.04) (push) Blocked by required conditions
Tests / run tests (ubuntu 24.10) (push) Blocked by required conditions
Scan latest app and container / security-scan-container (push) Waiting to run
Scan latest app and container / security-scan-app (push) Waiting to run
2025-01-23 16:26:07 +01:00
Alexis Métaireau
7409966253
Remove ${Python3:Depends} as it's not used at the moment. 2025-01-23 16:26:06 +01:00
Alexis Métaireau
40fb6579f6
Alternatives for debian/control 2025-01-23 16:26:06 +01:00
Alexis Métaireau
6ae91b024e
Use platformdirs to find user configuration files
The previous library we were using for this (`appdirs`) is dead upstream
and not supported anymore in debian testing.

Fixes #1058
2025-01-23 16:26:06 +01:00
Alexis Métaireau
c2841dcc08
Run ruff format
Some checks failed
Tests / build-container-image (push) Has been cancelled
Tests / Download and cache Tesseract data (push) Has been cancelled
Tests / windows (push) Has been cancelled
Tests / macOS (arch64) (push) Has been cancelled
Tests / macOS (x86_64) (push) Has been cancelled
Tests / build-deb (debian bookworm) (push) Has been cancelled
Tests / build-deb (debian bullseye) (push) Has been cancelled
Tests / build-deb (debian trixie) (push) Has been cancelled
Tests / build-deb (ubuntu 20.04) (push) Has been cancelled
Tests / build-deb (ubuntu 22.04) (push) Has been cancelled
Tests / build-deb (ubuntu 24.04) (push) Has been cancelled
Tests / build-deb (ubuntu 24.10) (push) Has been cancelled
Tests / install-deb (debian bookworm) (push) Has been cancelled
Tests / install-deb (debian bullseye) (push) Has been cancelled
Tests / install-deb (debian trixie) (push) Has been cancelled
Tests / install-deb (ubuntu 20.04) (push) Has been cancelled
Tests / install-deb (ubuntu 22.04) (push) Has been cancelled
Tests / install-deb (ubuntu 24.04) (push) Has been cancelled
Tests / install-deb (ubuntu 24.10) (push) Has been cancelled
Tests / build-install-rpm (fedora 40) (push) Has been cancelled
Tests / build-install-rpm (fedora 41) (push) Has been cancelled
Tests / run tests (debian bookworm) (push) Has been cancelled
Tests / run tests (debian bullseye) (push) Has been cancelled
Tests / run tests (debian trixie) (push) Has been cancelled
Tests / run tests (fedora 40) (push) Has been cancelled
Tests / run tests (fedora 41) (push) Has been cancelled
Tests / run tests (ubuntu 20.04) (push) Has been cancelled
Tests / run tests (ubuntu 22.04) (push) Has been cancelled
Tests / run tests (ubuntu 24.04) (push) Has been cancelled
Tests / run tests (ubuntu 24.10) (push) Has been cancelled
2025-01-23 14:48:33 +01:00
Alexis Métaireau
df5ccb3f75
Fedora: bypass the shiboken specific version. 2025-01-23 14:39:50 +01:00
Alexis Métaireau
9c6c2e1051
build: pin shiboken6 to specific versions 2025-01-23 12:52:48 +01:00
13 changed files with 512 additions and 417 deletions

View file

@ -44,7 +44,7 @@ RUN \
# Download H2ORestart from GitHub using a pinned version and hash. Note that # Download H2ORestart from GitHub using a pinned version and hash. Note that
# it's available in Debian repos, but not in Bookworm yet. # it's available in Debian repos, but not in Bookworm yet.
RUN mkdir /libreoffice_ext && cd libreoffice_ext \ RUN mkdir /opt/libreoffice_ext && cd /opt/libreoffice_ext \
&& H2ORESTART_FILENAME=h2orestart.oxt \ && H2ORESTART_FILENAME=h2orestart.oxt \
&& wget https://github.com/ebandal/H2Orestart/releases/download/$H2ORESTART_VERSION/$H2ORESTART_FILENAME \ && wget https://github.com/ebandal/H2Orestart/releases/download/$H2ORESTART_VERSION/$H2ORESTART_FILENAME \
&& echo "$H2ORESTART_CHECKSUM $H2ORESTART_FILENAME" | sha256sum -c \ && echo "$H2ORESTART_CHECKSUM $H2ORESTART_FILENAME" | sha256sum -c \

View file

@ -4,7 +4,7 @@
ARG DEBIAN_IMAGE_DATE={{DEBIAN_IMAGE_DATE}} ARG DEBIAN_IMAGE_DATE={{DEBIAN_IMAGE_DATE}}
FROM debian:bookworm-${DEBIAN_IMAGE_DATE}-slim FROM debian:bookworm-${DEBIAN_IMAGE_DATE}-slim as dangerzone-image
ARG GVISOR_ARCHIVE_DATE={{GVISOR_ARCHIVE_DATE}} ARG GVISOR_ARCHIVE_DATE={{GVISOR_ARCHIVE_DATE}}
ARG DEBIAN_ARCHIVE_DATE={{DEBIAN_ARCHIVE_DATE}} ARG DEBIAN_ARCHIVE_DATE={{DEBIAN_ARCHIVE_DATE}}
@ -44,7 +44,7 @@ RUN \
# Download H2ORestart from GitHub using a pinned version and hash. Note that # Download H2ORestart from GitHub using a pinned version and hash. Note that
# it's available in Debian repos, but not in Bookworm yet. # it's available in Debian repos, but not in Bookworm yet.
RUN mkdir /libreoffice_ext && cd libreoffice_ext \ RUN mkdir /opt/libreoffice_ext && cd /opt/libreoffice_ext \
&& H2ORESTART_FILENAME=h2orestart.oxt \ && H2ORESTART_FILENAME=h2orestart.oxt \
&& wget https://github.com/ebandal/H2Orestart/releases/download/$H2ORESTART_VERSION/$H2ORESTART_FILENAME \ && wget https://github.com/ebandal/H2Orestart/releases/download/$H2ORESTART_VERSION/$H2ORESTART_FILENAME \
&& echo "$H2ORESTART_CHECKSUM $H2ORESTART_FILENAME" | sha256sum -c \ && echo "$H2ORESTART_CHECKSUM $H2ORESTART_FILENAME" | sha256sum -c \
@ -64,18 +64,71 @@ RUN touch /opt/dangerzone/dangerzone/__init__.py
# Copy only the Python code, and not any produced .pyc files. # Copy only the Python code, and not any produced .pyc files.
COPY conversion/*.py /opt/dangerzone/dangerzone/conversion/ COPY conversion/*.py /opt/dangerzone/dangerzone/conversion/
# Let the entrypoint script write the OCI config for the inner container under
# /config.json.
RUN touch /config.json
RUN chown dangerzone:dangerzone /config.json
# Switch to the dangerzone user for the rest of the script.
USER dangerzone
# Create a directory that will be used by gVisor as the place where it will # Create a directory that will be used by gVisor as the place where it will
# store the state of its containers. # store the state of its containers.
RUN mkdir /home/dangerzone/.containers RUN mkdir /home/dangerzone/.containers
# XXX: Create a new root hierarchy, that will be used in the final container
# image:
#
# /bin -> usr/bin
# /lib -> usr/lib
# /lib64 -> usr/lib64
# /root
# /run
# /tmp
# /usr -> /home/dangerzone/dangerzone-image/rootfs/usr/
#
# We have to create this hierarchy beforehand because we want to use the same
# /usr for both the inner and outer container. The problem though is that /usr
# is very sensitive, and you can't manipulate in a live system. That is, I
# haven't found a way to do the following, or something equivalent:
#
# rm -r /usr && ln -s /home/dangerzone/dangerzone-image/rootfs/usr/ /usr
#
# So, we prefer to create the symlinks here instead, and create the image
# manually in the next steps.
RUN mkdir /new_root
RUN mkdir /new_root/root /new_root/run /new_root/tmp
RUN chmod 777 /new_root/tmp
RUN ln -s /home/dangerzone/dangerzone-image/rootfs/usr/ /new_root/usr
RUN ln -s usr/bin /new_root/bin
RUN ln -s usr/lib /new_root/lib
RUN ln -s usr/lib64 /new_root/lib64
RUN ln -s usr/sbin /new_root/sbin
# Intermediate layer
FROM debian:bookworm-${DEBIAN_IMAGE_DATE}-slim as debian-utils
## Final image
FROM scratch
# Copy the filesystem hierarchy that we created in the previous layer, so that
# /usr can be a symlink.
COPY --from=dangerzone-image /new_root/ /
# Copy some files that are necessary to use the outer container image, e.g., in
# order to run `apt`. We _could_ avoid doing this, but the space cost is very
# small.
COPY --from=dangerzone-image /etc/ /etc/
COPY --from=debian-utils /var/ /var/
# Copy the bare minimum to run Dangerzone in the inner container image.
COPY --from=dangerzone-image /etc/ /home/dangerzone/dangerzone-image/rootfs/etc/
COPY --from=dangerzone-image /usr/ /home/dangerzone/dangerzone-image/rootfs/usr/
COPY --from=dangerzone-image /opt/ /home/dangerzone/dangerzone-image/rootfs/opt/
RUN ln -s usr/bin /home/dangerzone/dangerzone-image/rootfs/bin
RUN ln -s usr/lib /home/dangerzone/dangerzone-image/rootfs/lib
RUN ln -s usr/lib64 /home/dangerzone/dangerzone-image/rootfs/lib64
# Allow our entrypoint script to make changes in the following folders.
RUN chown dangerzone:dangerzone /home/dangerzone /home/dangerzone/dangerzone-image/
# Switch to the dangerzone user for the rest of the script.
USER dangerzone
COPY container_helpers/entrypoint.py / COPY container_helpers/entrypoint.py /
ENTRYPOINT ["/entrypoint.py"] ENTRYPOINT ["/entrypoint.py"]

View file

@ -153,21 +153,6 @@ oci_config: dict[str, typing.Any] = {
"source": "tmpfs", "source": "tmpfs",
"options": ["nosuid", "noexec", "nodev"], "options": ["nosuid", "noexec", "nodev"],
}, },
# Also mask some files that are usually mounted by Docker / Podman. These files
# should not contain any sensitive information, since we use the `--network
# none` flag, but we want to make sure in any case.
{
"destination": "/etc/hostname",
"type": "bind",
"source": "/dev/null",
"options": ["rbind", "ro"],
},
{
"destination": "/etc/hosts",
"type": "bind",
"source": "/dev/null",
"options": ["rbind", "ro"],
},
# LibreOffice needs a writable home directory, so just mount a tmpfs # LibreOffice needs a writable home directory, so just mount a tmpfs
# over it. # over it.
{ {

View file

@ -253,7 +253,7 @@ class DocumentToPixels(DangerzoneConverter):
"unzip", "unzip",
"-d", "-d",
f"/usr/lib/libreoffice/share/extensions/{libreoffice_ext}/", f"/usr/lib/libreoffice/share/extensions/{libreoffice_ext}/",
f"/libreoffice_ext/{libreoffice_ext}", f"/opt/libreoffice_ext/{libreoffice_ext}",
] ]
await self.run_command( await self.run_command(
unzip_args, unzip_args,

View file

@ -335,9 +335,9 @@ class IsolationProvider(ABC):
stderr_thread = self.start_stderr_thread(p, stderr) stderr_thread = self.start_stderr_thread(p, stderr)
if platform.system() != "Windows": if platform.system() != "Windows":
assert os.getpgid(p.pid) != os.getpgid( assert os.getpgid(p.pid) != os.getpgid(os.getpid()), (
os.getpid() "Parent shares same PGID with child"
), "Parent shares same PGID with child" )
try: try:
yield p yield p

View file

@ -5,11 +5,14 @@ import sys
import traceback import traceback
import unicodedata import unicodedata
import appdirs try:
import platformdirs
except ImportError:
import appdirs as platformdirs
def get_config_dir() -> str: def get_config_dir() -> str:
return appdirs.user_config_dir("dangerzone") return platformdirs.user_config_dir("dangerzone")
def get_resource_path(filename: str) -> str: def get_resource_path(filename: str) -> str:

2
debian/control vendored
View file

@ -9,7 +9,7 @@ Rules-Requires-Root: no
Package: dangerzone Package: dangerzone
Architecture: any Architecture: any
Depends: ${misc:Depends}, ${python3:Depends}, podman, python3, python3-pyside2.qtcore, python3-pyside2.qtgui, python3-pyside2.qtwidgets, python3-pyside2.qtsvg, python3-appdirs, python3-click, python3-xdg, python3-colorama, python3-requests, python3-markdown, python3-packaging, tesseract-ocr-all Depends: ${misc:Depends}, podman, python3, python3-pyside2.qtcore, python3-pyside2.qtgui, python3-pyside2.qtwidgets, python3-pyside2.qtsvg, python3-platformdirs | python3-appdirs, python3-click, python3-xdg, python3-colorama, python3-requests, python3-markdown, python3-packaging, tesseract-ocr-all
Description: Take potentially dangerous PDFs, office documents, or images Description: Take potentially dangerous PDFs, office documents, or images
Dangerzone is an open source desktop application that takes potentially dangerous PDFs, office documents, or images and converts them to safe PDFs. It uses disposable VMs on Qubes OS, or container technology in other OSes, to convert the documents within a secure sandbox. Dangerzone is an open source desktop application that takes potentially dangerous PDFs, office documents, or images and converts them to safe PDFs. It uses disposable VMs on Qubes OS, or container technology in other OSes, to convert the documents within a secure sandbox.
. .

View file

@ -21,7 +21,7 @@ IMAGE_NAME = "dangerzone.rocks/dangerzone"
def run(*args): def run(*args):
"""Simple function that runs a command, validates it, and returns the output""" """Simple function that runs a command, validates it, and returns the output"""
logger.debug(f"Running command: {" ".join(args)}") logger.debug(f"Running command: {' '.join(args)}")
return subprocess.run( return subprocess.run(
args, args,
check=True, check=True,

View file

@ -226,6 +226,11 @@ convert the documents within a secure sandbox.
sed -i 's/<3.13/<3.14/' pyproject.toml sed -i 's/<3.13/<3.14/' pyproject.toml
%endif %endif
# Bypass the version pin for Fedora as the 6.8.1.1 package is causing trouble
# A 6.8.1.1 package was only released with a wheel for macOS, but was picked by
# Fedora packagers. We cannot use "*" when PyPI is involved as it will fail to download the latest version.
# For Fedora, we can pick any of the released versions.
sed -i '/shiboken6 = \[/,/\]/c\shiboken6 = "*"' pyproject.toml
%generate_buildrequires %generate_buildrequires
%pyproject_buildrequires -R %pyproject_buildrequires -R

798
poetry.lock generated

File diff suppressed because it is too large Load diff

View file

@ -15,7 +15,7 @@ include = [
[tool.poetry.dependencies] [tool.poetry.dependencies]
python = ">=3.9,<3.13" python = ">=3.9,<3.13"
click = "*" click = "*"
appdirs = "*" platformdirs = "*"
PySide6 = "^6.7.1" PySide6 = "^6.7.1"
PyMuPDF = "^1.23.3" # The version in Fedora 39 PyMuPDF = "^1.23.3" # The version in Fedora 39
colorama = "*" colorama = "*"
@ -23,6 +23,13 @@ pyxdg = {version = "*", platform = "linux"}
requests = "*" requests = "*"
markdown = "*" markdown = "*"
packaging = "*" packaging = "*"
# shiboken6 released a 6.8.1.1 version only for macOS
# and it's getting picked by poetry, so pin it instead.
shiboken6 = [
{version = "*", platform = "darwin"},
{version = "<6.8.1.1", platform = "linux"},
{version = "<6.8.1.1", platform = "win32"},
]
[tool.poetry.scripts] [tool.poetry.scripts]
dangerzone = 'dangerzone:main' dangerzone = 'dangerzone:main'

View file

@ -12,9 +12,9 @@ VERSION_FILE_NAME = "version.txt"
def test_get_resource_path() -> None: def test_get_resource_path() -> None:
share_dir = Path("share").resolve() share_dir = Path("share").resolve()
resource_path = Path(util.get_resource_path(VERSION_FILE_NAME)).parent resource_path = Path(util.get_resource_path(VERSION_FILE_NAME)).parent
assert share_dir.samefile( assert share_dir.samefile(resource_path), (
resource_path f"{share_dir} is not the same file as {resource_path}"
), f"{share_dir} is not the same file as {resource_path}" )
@pytest.mark.skipif(platform.system() != "Windows", reason="Windows-specific") @pytest.mark.skipif(platform.system() != "Windows", reason="Windows-specific")