Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 19 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,25 @@ The following features have not been implemented yet. PRs or notifications for d

You can install this package from PyPI

Install command assuming an active virtual environment:
For example, using [`uv`](https://docs.astral.sh/uv/)

Setting up virtual environment:

```sh
uv venv
```

Regular install:

```sh
pip install cfdp-py
uv pip install -e .
```

Interactive install with testing support:

```sh
uv pip install -e ".[test]"
```

# Examples

Expand All @@ -47,14 +60,13 @@ If you want to run the tests, it is recommended to install `pytest` and `coverag
first. You also have to install the package with the optional `test` feature:

```sh
pip install coverage pytest
pip install cfdp-py[test]
uv pip install -e ".[test]"
```

Running tests regularly:

```sh
pytest .
pytest
```

Running tests with coverage:
Expand Down Expand Up @@ -91,11 +103,11 @@ make doctest
Linting:

```sh
ruff check .
ruff check
```

Formatting:

```sh
ruff format .
ruff format
```
2 changes: 1 addition & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
intersphinx_mapping = {
"python": ("https://docs.python.org/3", None),
"spacepackets": ("https://spacepackets.readthedocs.io/en/latest/", None),
"crcmod": ("https://crcmod.sourceforge.net/", None),
"fastcrc": ("https://fastcrc.readthedocs.io/en/latest/", None),
}

# -- Options for HTML output -------------------------------------------------
Expand Down
2 changes: 2 additions & 0 deletions examples/cfdp-libre-cube-crosstest/requirements.txt
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
cfdp @ git+https://gitlab.com/librecube/lib/python-cfdp.git
# Install local cfdp-py interactively
-e ../..
12 changes: 11 additions & 1 deletion justfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Run with `just all`
all: fmt check test
all: fmt check coverage

setup:
uv venv

install:
uv pip install -e ".[test]"

fmt:
ruff format
Expand All @@ -9,3 +15,7 @@ check:

test:
pytest

coverage:
coverage run -m pytest
coverage report
8 changes: 5 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,16 @@ classifiers = [
"Topic :: Scientific/Engineering"
]
dependencies = [
"spacepackets>=0.26.0, <=0.28",
"crcmod~=1.7",
"spacepackets>=0.30,<0.32",
"fastcrc~=0.3",
"deprecation~=2.1",
]

[project.optional-dependencies]
test = [
"pyfakefs~=5.2"
"pyfakefs~=5.2",
"pytest",
"coverage"
]
lint = ["ruff"]

Expand Down
13 changes: 6 additions & 7 deletions release-checklist.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,16 @@ The steps shown here are for Ubuntu/MacOS.
2. Bump version inside the `pyproject.toml` file.
3. Update `CHANGELOG.md`: Convert `unreleased` section into version section
with date and new `unreleased`section.
4. Run tests with `pytest .`
5. Run auto-formatter with `ruff format .`
6. Run linter with `ruff check .`
4. Run tests with `pytest`
5. Run auto-formatter with `ruff format`
6. Run linter with `ruff check`
7. Wait for CI/CD results. This also runs the tests on different operating systems

# Release

1. Delete existing distributions: `rm dist/*`
2. Build the package. Requires the `build` package: `python3 -m build`
3. Upload the source and build distribution: `python3 -m twine upload dist/*`. You might require
a PyPI upload token to do this.
1. Build the package using `uv build`
2. Upload to package to PyPi using `uv publish`. You might also need to authenticate, for example
by passing `--token <your token>` to the command.

# Post-Release

Expand Down
22 changes: 18 additions & 4 deletions src/cfdppy/filestore.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@
import os
import platform
import shutil
import struct
import subprocess
from typing import TYPE_CHECKING, BinaryIO

from crcmod.predefined import PredefinedCrc
import fastcrc
from spacepackets.cfdp.defs import NULL_CHECKSUM_U32, ChecksumType
from spacepackets.cfdp.tlv import FilestoreResponseStatusCode

Expand Down Expand Up @@ -351,9 +352,12 @@ def checksum_type_to_crcmod_str(self, checksum_type: ChecksumType) -> str | None
return "crc32c"
raise ChecksumNotImplemented(checksum_type)

"""

def _generate_crc_calculator(self, checksum_type: ChecksumType) -> PredefinedCrc:
self._verify_checksum(checksum_type)
return PredefinedCrc(self.checksum_type_to_crcmod_str(checksum_type))
"""

def calculate_checksum(
self,
Expand All @@ -370,16 +374,26 @@ def calculate_checksum(
return calc_modular_checksum(file_path)
if segment_len == 0:
raise ValueError("segment length can not be 0")
crc_obj = self._generate_crc_calculator(checksum_type)
func = None
if checksum_type == ChecksumType.CRC_32:
func = fastcrc.crc32.iso_hdlc
elif checksum_type == ChecksumType.CRC_32C:
func = fastcrc.crc32.iscsi
else:
raise ChecksumNotImplemented(checksum_type)
current = func(b"")
current_offset = 0
# Calculate the file CRC
with open(file_path, "rb") as file:
while current_offset < size_to_verify:
read_len = min(segment_len, size_to_verify - current_offset)
if read_len > 0:
crc_obj.update(self.read_from_opened_file(file, current_offset, read_len))
current = func(
self.read_from_opened_file(file, current_offset, read_len), current
)
current_offset += read_len
return crc_obj.digest()
assert current is not None
return struct.pack("!I", current)


HostFilestore = NativeFilestore
4 changes: 3 additions & 1 deletion src/cfdppy/restricted_filestore.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,12 +133,14 @@ def calculate_checksum(

def verify_checksum(
self,
checksum: bytes,
checksum: int | bytes,
checksum_type: ChecksumType,
file_path: Path,
size_to_verify: int,
segment_len: int = 4096,
) -> bool:
if isinstance(checksum, int):
checksum = checksum.to_bytes(4, "big")
"""Verify checksum of file."""
return super().verify_checksum(
checksum=checksum,
Expand Down
2 changes: 1 addition & 1 deletion tests/test_dest_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ def _insert_file_segment(
)
return fsm_res

def _generic_insert_eof_pdu(self, file_size: int, checksum: bytes) -> FsmResult:
def _generic_insert_eof_pdu(self, file_size: int, checksum: int | bytes) -> FsmResult:
eof_pdu = EofPdu(file_size=file_size, file_checksum=checksum, pdu_conf=self.src_pdu_conf)
fsm_res = self.dest_handler.state_machine(eof_pdu)
if self.expected_mode == TransmissionMode.UNACKNOWLEDGED:
Expand Down
Loading
Loading