Skip to content

Commit 2e454fa

Browse files
authored
MNT: Add pre-commit hooks and checks (#138)
1 parent c1df605 commit 2e454fa

15 files changed

+254
-204
lines changed

.github/workflows/tests.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ jobs:
1818
- name: Install ruff
1919
run: pip install . ruff
2020
- name: Run ruff
21-
run: ruff check space_packet_parser
21+
run: ruff check
2222

2323
ci-tests:
2424
runs-on: ${{ matrix.os }}
@@ -43,12 +43,12 @@ jobs:
4343
uses: actions/setup-python@v5
4444
with:
4545
python-version: ${{ matrix.python-version }}
46-
46+
4747
- name: Install dependencies
4848
run: |
4949
python -m pip install --upgrade pip
5050
pip install ".[test,xarray]"
51-
51+
5252
- name: Testing
5353
run: |
5454
pytest --color=yes --cov

.pre-commit-config.yaml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
ci:
2+
autofix_prs: false
3+
autoupdate_schedule: 'quarterly'
4+
skip: [poetry-lock]
5+
repos:
6+
- repo: https://github.com/pre-commit/pre-commit-hooks
7+
rev: v4.5.0
8+
hooks:
9+
- id: check-added-large-files
10+
args: ['--maxkb=1000']
11+
- id: detect-aws-credentials
12+
args: [--allow-missing-credentials]
13+
- id: detect-private-key
14+
- id: mixed-line-ending
15+
- id: trailing-whitespace
16+
- id: no-commit-to-branch
17+
args: [--branch, main, --branch, dev]
18+
- repo: https://github.com/astral-sh/ruff-pre-commit
19+
rev: 'v0.9.6'
20+
hooks:
21+
- id: ruff
22+
args: [--fix]
23+
# - id: ruff-format
24+
- repo: https://github.com/codespell-project/codespell
25+
rev: v2.2.6
26+
hooks:
27+
- id: codespell
28+
files: ^.*\.(py|md|rst|yml)$

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66

77
Documentation: [https://space-packet-parser.readthedocs.io/en/latest/](https://space-packet-parser.readthedocs.io/en/latest/)
88

9-
Space Packet Parser is a package for decoding CCSDS telemetry packets according to an XTCE packet structure definition.
10-
It is based on the UML model of the XTCE spec and aims to support all but the most esoteric elements of the
9+
Space Packet Parser is a package for decoding CCSDS telemetry packets according to an XTCE packet structure definition.
10+
It is based on the UML model of the XTCE spec and aims to support all but the most esoteric elements of the
1111
XTCE telemetry packet specification.
1212

1313
Resources:

docs/source/benchmarking.md

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22

33
## Full Packet Parsing Performance
44

5-
Benchmarking packet parsing is challenging because performance is greatly impacted by the complexity of the packet
5+
Benchmarking packet parsing is challenging because performance is greatly impacted by the complexity of the packet
66
structures being parsed. There are a few measures by which we can assess the performance of Space Packet Parser.
77

88
> [!NOTE]
9-
> Throughout the Space Packet Parser repo and documentation space,
9+
> Throughout the Space Packet Parser repo and documentation space,
1010
> B/kB means bytes/kilobytes and b/kb means bits/kilobits.*
1111
1212
Common factors affecting performance:
@@ -17,23 +17,23 @@ Common factors affecting performance:
1717

1818
### Packets Per Second
1919

20-
This is a metric we are often asked about. Unfortunately, the answer is that it depends on which packets are
21-
being parsed: how many fields are in each packet and how much extra work the parser is doing to sort out complex
20+
This is a metric we are often asked about. Unfortunately, the answer is that it depends on which packets are
21+
being parsed: how many fields are in each packet and how much extra work the parser is doing to sort out complex
2222
packet structures and evaluate calibrators.
2323

2424
### Kilobits Per Second
2525

26-
This metric is often used when discussing data volumes and downlink bandwidths to make sure that a data processing
27-
system can keep up with the data rate from a spacecraft in the time allowed for processing. This number is also
28-
affected by packet structures. It will be high for simple packets containing large binary blobs and low for
26+
This metric is often used when discussing data volumes and downlink bandwidths to make sure that a data processing
27+
system can keep up with the data rate from a spacecraft in the time allowed for processing. This number is also
28+
affected by packet structures. It will be high for simple packets containing large binary blobs and low for
2929
complex packets containing many small fields.
3030

3131
### Results
3232

33-
These tests were run on an Apple Silicon M3 Max processor.
33+
These tests were run on an Apple Silicon M3 Max processor.
3434

35-
As a baseline, for relatively simple packets (these are JPSS-1 spacecraft geolocation packets containing attitude
36-
and ephemeris data), we benchmarked using 7200 packets with a consistent size of 71B per packet. These packets contain
35+
As a baseline, for relatively simple packets (these are JPSS-1 spacecraft geolocation packets containing attitude
36+
and ephemeris data), we benchmarked using 7200 packets with a consistent size of 71B per packet. These packets contain
3737
32-bit floats and integers of various sizes.
3838

3939
- **26405-34620 packets per second**
@@ -89,9 +89,9 @@ Progress: [====================]100% [Elapsed: 0:00:00.264275, Parsed 511200 byt
8989

9090
## Parsing Individual Values Benchmarking
9191

92-
In addition to the benchmarks discussed above, we also benchmarked the low level operations that make up most
92+
In addition to the benchmarks discussed above, we also benchmarked the low level operations that make up most
9393
of the parsing work. The parser relies on two fundamental methods: `read_as_int(nbits)` and `read_as_bytes(nbits)`,
94-
each of which is capable of reading an arbitrary number of bits from a byte string. That is, the binary data being
94+
each of which is capable of reading an arbitrary number of bits from a byte string. That is, the binary data being
9595
parsed need not be byte aligned or even an integer number of bytes.
9696

9797
```
@@ -108,9 +108,9 @@ test_benchmark__read_as_bytes__partial_bytes 441.6660 (1.91) 46
108108

109109
The results are as expected:
110110

111-
- The most efficient parsing is byte-aligned parsing of objects that are integer number of bytes in length.
111+
- The most efficient parsing is byte-aligned parsing of objects that are integer number of bytes in length.
112112
- Parsing integers is slower than raw bytes due to the conversion from bytes to int.
113-
- The most expensive operation is parsing a bytes object that is an odd number of bits (e.g. 6 bits). This is due
113+
- The most expensive operation is parsing a bytes object that is an odd number of bits (e.g. 6 bits). This is due
114114
to the padding operation required to return a bytes object from such a call.
115115
- The only surprise is that non-aligned integers parse faster than non-aligned full bytes. Ironically this is due
116116
to a check that we perform during byte parsing to return faster if the request _is_ byte aligned.

docs/source/changelog.md

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
# Change Log
2-
This is a log of changes made to the library over time. For planned upcoming changes, please check the GitHub issue
2+
This is a log of changes made to the library over time. For planned upcoming changes, please check the GitHub issue
33
list and release milestones.
44

55
## Version Release Notes
66
Release notes for the `space_packet_parser` library
77

88
### v6.0.0 (unreleased)
9-
- *BREAKING*: `XtcePacketDefinition` no longer accepts a file object as input.
9+
- *BREAKING*: `XtcePacketDefinition` no longer accepts a file object as input.
1010
Use `spp.xtce.definitions.XtcePacketDefinition.from_document()` or `spp.load_xml()` instead.
1111
- *BREAKING*: Reorganization of the project into different submodules for more explicit handling
1212
of imports. There is now an `space_packet_parser.xtce` module with xtce representations separated
@@ -41,27 +41,27 @@ Release notes for the `space_packet_parser` library
4141
- If a packet definition parses too few bits, a UserWarning is now emitted instead of a logger warning.
4242

4343
### v5.0.0 (released)
44-
- *BREAKING*: Main API changed. No need to create separate definition and parser objects any more. Create only a
44+
- *BREAKING*: Main API changed. No need to create separate definition and parser objects any more. Create only a
4545
definition from your XTCE document and instead of `my_parser.generator`, use `my_packet_definition.packet_generator`.
46-
- *BREAKING*: Removed CSV-based packet definition support. We may indirectly support this in the future via
46+
- *BREAKING*: Removed CSV-based packet definition support. We may indirectly support this in the future via
4747
a utility for converting CSV definitions to XTCE.
4848
- *BREAKING*: Separated out logical pieces into separate modules rather than everything
4949
living within the xtcedef module. This means user imports may be different now.
5050
- *BREAKING*: Replace `bitstring` objects with native Python bytes objects
5151
- Remove dependency on the `bitstring` library
5252
- Much faster parsing speed
53-
- Users that are passing `bitstring.ConstBitStream` objects to `generator` will need to pass a
53+
- Users that are passing `bitstring.ConstBitStream` objects to `generator` will need to pass a
5454
binary filelike object instead
5555
- *BREAKING*: The ``ParsedDataItem`` class has been removed and the derived values are being returned now.
5656
The ``raw_value`` is stored as an attribute on the returned object. The other items can be accessed
5757
through the packet definition object ``my_packet_definition.named_parameters["my_item"].short_description``
5858
- *BREAKING*: The return type of BinaryDataEncoding is now the raw bytes.
5959
To get the previous behavior you can convert the data to an integer and then format it as a binary string.
6060
``f"{int.from_bytes(data, byteorder='big'):0{len(data)*8}b}"``
61-
- *BREAKING*: Removed `word_size` kwarg from packet generator method.
61+
- *BREAKING*: Removed `word_size` kwarg from packet generator method.
6262
We expect all binary data to be integer number of bytes.
6363
- *BREAKING*: Changed `packet_generator` kwarg `skip_header_bits` to `skip_header_bytes`.
64-
- Fixed incorrect parsing of StringDataEncoding elements. Raw string values are now returned as byte buffers.
64+
- Fixed incorrect parsing of StringDataEncoding elements. Raw string values are now returned as byte buffers.
6565
Derived string values contain python string objects.
6666
- The ``CCSDSPacket`` class is now a dictionary subclass, enabling direct lookup of items from the Packet itself.
6767
- A ``RawPacketData`` class has been added that is a subclass of bytes. It keeps track of the current
@@ -101,9 +101,9 @@ Release notes for the `space_packet_parser` library
101101

102102
## Historical Changes (`lasp_packets`)
103103
Changes documented in v3.0 and earlier correspond to development efforts undertaken before this library was
104-
moved to GitHub (it was previously known as `lasp_packets`).
105-
None of the git history is available for these versions as the git history was truncated
106-
in preparation for the move to Github to prevent accidental release of non-public example data which may be
104+
moved to GitHub (it was previously known as `lasp_packets`).
105+
None of the git history is available for these versions as the git history was truncated
106+
in preparation for the move to Github to prevent accidental release of non-public example data which may be
107107
(but probably isn't) present in historical commits.
108108

109109
### v3.0 (released publicly)
@@ -135,7 +135,7 @@ in preparation for the move to Github to prevent accidental release of non-publi
135135
- Add support for BooleanExpression in a RestrictionCriteria element
136136

137137
### v1.3 (released internally)
138-
- Expand version compatiblity for python >=3.6, <4
138+
- Expand version compatibility for python >=3.6, <4
139139

140140
### v1.2 (released internally)
141141
- Remove unnecessary warning about float data types being IEEE formatted.
@@ -146,7 +146,7 @@ in preparation for the move to Github to prevent accidental release of non-publi
146146
- Add support for CSV-based packet definitions (contribution by Michael Chambliss).
147147

148148
### v1.0 (released internally)
149-
- Add support for all parameter types.
149+
- Add support for all parameter types.
150150
- Add support for all data encodings.
151151
- Add support for calibrators and contextual calibrators.
152152
- Add support for variable length strings given by termination characters or preceding length fields.

docs/source/developers.md

Lines changed: 38 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,30 @@
11
# Developer Documentation
2+
23
## Installing Development Dependencies
3-
Poetry installs dev dependencies by default from the `poetry.lock` or `pyproject.toml` files. Just run
4+
5+
Poetry installs dev dependencies by default from the `poetry.lock` or `pyproject.toml` files.
6+
47
```bash
58
poetry install
69
```
710

11+
Alternatively, if you are using something other than Poetry for development you can install from
12+
the `dev` extras group.
13+
14+
```bash
15+
pip install ".[dev]"
16+
```
17+
18+
Once the development dependencies are installed, you can run
19+
20+
```bash
21+
pre-commit install
22+
```
23+
24+
to get pre-commit hooks to automatically run the linting and formatting checks for you before each commit.
25+
826
## Testing
9-
Testing is run with `pytest` and the order is randomized by `pytest-randomly`.
27+
Testing is run with `pytest` and the order is randomized by `pytest-randomly`.
1028
To run all tests, run
1129
```bash
1230
pytest tests
@@ -18,15 +36,15 @@ docker-compose up --build && docker-compose down
1836
```
1937

2038
## Building Documentation with Sphinx
21-
Documentation is automatically built on ReadTheDocs in response to every PR and release,
39+
Documentation is automatically built on ReadTheDocs in response to every PR and release,
2240
but you can also build it locally with:
2341
```bash
2442
# From docs directory
2543
make html && open build/html/index.html
2644
```
2745

2846
## Making a Pull Request
29-
Feel free to fork this repo and submit a PR!
47+
Feel free to fork this repo and submit a PR!
3048
- If you are working on an issue, link your PR to that issue.
3149
- All PRs should be destined for the `main` branch (trunk-based development).
3250
- Reviews are required before merging and our automated tests must pass.
@@ -45,7 +63,7 @@ That is,
4563

4664
### Preparing for Release
4765
1. Create a release candidate branch named according to the version to be released. This branch is used to polish
48-
the release but is fundamentally not different from any other feature branch in trunk-based development.
66+
the release but is fundamentally not different from any other feature branch in trunk-based development.
4967
The naming convention is `release/X.Y.Z`.
5068

5169
2. Bump the version of the package to the version you are about to release, either manually by editing `pyproject.toml`
@@ -56,30 +74,30 @@ That is,
5674

5775
4. Update `changelog.md` to reflect that the version is now "released" and revisit `README.md` to keep it up to date.
5876

59-
5. Open a PR to merge the release branch into main. This informs the rest of the team how the release
60-
process is progressing as you polish the release branch. You may need to rebase the release branch onto
77+
5. Open a PR to merge the release branch into main. This informs the rest of the team how the release
78+
process is progressing as you polish the release branch. You may need to rebase the release branch onto
6179
any recent changes to `main` and resolve any conflicts on a regular basis.
6280

63-
6. When you are satisfied that the release branch is ready, merge the PR into `main`.
81+
6. When you are satisfied that the release branch is ready, merge the PR into `main`.
6482

65-
7. Check out the `main` branch, pull the merged changes, and tag the newly created merge commit with the
66-
desired version `X.Y.Z` and push the tag upstream.
83+
7. Check out the `main` branch, pull the merged changes, and tag the newly created merge commit with the
84+
desired version `X.Y.Z` and push the tag upstream.
6785

6886
### Automatic Release Process
69-
We use GitHub Actions for automatic release process that responds to pushes of git tags. When a tag matching
70-
a semantic version (`[0-9]+.[0-9]+.[0-9]+*` or `test-release/[0-9]+.[0-9]+.[0-9]+*`) is pushed,
71-
a workflow runs that builds the package, pushes the artifacts to PyPI or TestPyPI
72-
(if tag is prefixed with `test-release`),
73-
and creates a GitHub Release from the distributed artifacts. Release notes
87+
We use GitHub Actions for automatic release process that responds to pushes of git tags. When a tag matching
88+
a semantic version (`[0-9]+.[0-9]+.[0-9]+*` or `test-release/[0-9]+.[0-9]+.[0-9]+*`) is pushed,
89+
a workflow runs that builds the package, pushes the artifacts to PyPI or TestPyPI
90+
(if tag is prefixed with `test-release`),
91+
and creates a GitHub Release from the distributed artifacts. Release notes
7492
are automatically generated from commit history and the Release name is taken from the basename of the tag.
7593

7694
#### Official Releases
7795
Official releases are published to the public PyPI (even if they are release candidates like `1.2.3rc1`). This differs
78-
from test releases, which are only published to TestPyPI and are not published to GitHub at all.
79-
If the semantic version has any suffixes (e.g. `rc1`), the release will be marked as
96+
from test releases, which are only published to TestPyPI and are not published to GitHub at all.
97+
If the semantic version has any suffixes (e.g. `rc1`), the release will be marked as
8098
a prerelease in GitHub and PyPI.
8199

82-
To trigger an official release, push a tag referencing the commit you want to release. The commit _MUST_ be on
100+
To trigger an official release, push a tag referencing the commit you want to release. The commit _MUST_ be on
83101
the `main` branch. Never publish an official release from a commit that hasn't been merged to `main`!
84102

85103
```bash
@@ -90,10 +108,10 @@ git push origin X.Y.Z
90108
```
91109

92110
#### Test Releases
93-
Test releases are published to TestPyPI only and are not published on GitHub. Test releases are triggered by tags
111+
Test releases are published to TestPyPI only and are not published on GitHub. Test releases are triggered by tags
94112
prefixed with `test-release`.
95113

96-
To publish a test release, prefix the tag with `test-release`. This will prevent any publishing to the public PyPI
114+
To publish a test release, prefix the tag with `test-release`. This will prevent any publishing to the public PyPI
97115
and will prevent the artifacts being published on GitHub.
98116

99117
```bash

docs/source/examples.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
[Examples folder on Github](https://github.com/lasp/space_packet_parser/tree/main/examples)
44

55
Examples on Github include:
6-
- [Basic quicklook tool](https://github.com/lasp/space_packet_parser/blob/main/examples/parsing_and_plotting_idex_waveforms_from_socket.py)
6+
- [Basic quicklook tool](https://github.com/lasp/space_packet_parser/blob/main/examples/parsing_and_plotting_idex_waveforms_from_socket.py)
77
using realtime packet parsing from a streaming socket
8-
- [CSV to XTCE](https://github.com/lasp/space_packet_parser/blob/main/examples/csv_to_xtce_conversion.py)
8+
- [CSV to XTCE](https://github.com/lasp/space_packet_parser/blob/main/examples/csv_to_xtce_conversion.py)
99
packet definition conversion and parsing

0 commit comments

Comments
 (0)