mirror of
https://git.pumpin.online/funkpower/typikon.git
synced 2026-10-23 11:07:16 +00:00
describe() in Python was answering a different fast than the same date on the command line: xerophagy on a Wednesday of the Great Fast read as wine_oil. Not a cosmetic difference in a tool whose whole job is to say what may be eaten. The cause is that Jurisdiction grew a tradition and a discipline, and config carries all three — main.rs reads the saved jurisdiction, then the saved tradition, then whether the Typikon's full discipline was asked for, and builds an overridden Jurisdiction from the lot. The bindings resolved the key and stopped, so everything the other two decide was silently dropped. They now take the same three steps, and tradition= and typikon= are arguments, so the library can say what the command line can. Pascha does not take them: it follows the paschalion alone and neither can move it. The overrides are interned rather than leaked per call. main.rs leaks one per run and exits; a library gets called in a loop, and a leak per call adds up. The combinations are bounded by jurisdictions x traditions x discipline, so the map cannot grow past that. The parity test spread widens to seven dates across both fasts and both calendars, and clippy now runs under the feature as well — the binding code only exists there, so a bare clippy run had never looked at it.
74 lines
2.7 KiB
YAML
74 lines
2.7 KiB
YAML
name: ci
|
|
|
|
# Deliberately not triggered by pull_request.
|
|
#
|
|
# The forge this runs on is public and takes pull requests from strangers, and a
|
|
# runner executes whatever the workflow checks out. Triggering on pull_request
|
|
# would mean a stranger's first contribution runs code on the runner host before
|
|
# anyone has read it. Triggering only on push means the runner only ever executes
|
|
# code that someone with push rights put there.
|
|
#
|
|
# The cost is that a pull request gets no automatic check. Run it by pushing the
|
|
# branch yourself once you have read the diff.
|
|
on:
|
|
push:
|
|
branches: ['**']
|
|
tags-ignore: ['**']
|
|
|
|
jobs:
|
|
test:
|
|
runs-on: docker
|
|
container:
|
|
image: rust:1.98-bookworm
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Cache cargo
|
|
uses: actions/cache@v4
|
|
with:
|
|
path: |
|
|
~/.cargo/registry
|
|
~/.cargo/git
|
|
target
|
|
key: cargo-${{ runner.os }}-${{ hashFiles('Cargo.lock') }}
|
|
restore-keys: cargo-${{ runner.os }}-
|
|
|
|
# No `cargo fmt --check`. The tables in this crate are aligned by hand —
|
|
# MONTHS, JURISDICTIONS — and rustfmt wants one entry per line, which loses
|
|
# the shape that makes them readable. A gate that fights the house style is
|
|
# a gate that gets ignored.
|
|
- name: Lint
|
|
run: |
|
|
rustup component add clippy
|
|
cargo clippy --all-targets -- -D warnings
|
|
# The binding code only exists under the feature, so a bare clippy
|
|
# run never looks at src/python.rs.
|
|
cargo clippy --features python --all-targets -- -D warnings
|
|
|
|
- name: Rust tests
|
|
run: cargo test
|
|
|
|
# The CLI and the bindings are the same engine, so they have to agree. This
|
|
# is the check that caught the bindings resolving their own default
|
|
# jurisdiction while the CLI read the configured one.
|
|
- name: Python bindings
|
|
run: |
|
|
apt-get update && apt-get install -y --no-install-recommends python3 python3-venv python3-dev
|
|
python3 -m venv /tmp/venv
|
|
/tmp/venv/bin/pip install --quiet maturin pytest mypy
|
|
cargo build --release
|
|
/tmp/venv/bin/maturin build --release --out dist
|
|
/tmp/venv/bin/pip install --quiet --no-index --find-links dist typikon
|
|
/tmp/venv/bin/python -m pytest tests/python -q
|
|
|
|
- name: Type stubs
|
|
run: |
|
|
cat > /tmp/typecheck.py <<'EOF'
|
|
import datetime, typikon
|
|
d: typikon.Day = typikon.describe(datetime.date(2026, 4, 12))
|
|
day: datetime.date = d.date
|
|
feast: str | None = d.feast
|
|
n: int = d.days_to_pascha
|
|
EOF
|
|
/tmp/venv/bin/python -m mypy --strict /tmp/typecheck.py
|