Skip to content

Commit 8aa129a

Browse files
committed
Changed: update developer docs and optimize release tagging logic
Update AGENTS.md and scripts/README.md with details on feature flags, code structure, and release workflows. Improve the efficiency of changelog section extraction in tag_release.py by using slice-based trimming.
1 parent 0ef2b94 commit 8aa129a

3 files changed

Lines changed: 70 additions & 13 deletions

File tree

AGENTS.md

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,29 +13,36 @@ When making changes in this repo, prioritize (in order):
1313
## Common commands
1414

1515
- All tests (Rust + Python): `just test-all`
16-
- Changelog (generate full): `just changelog` (runs `git-cliff -o CHANGELOG.md`)
17-
- Changelog (prepend unreleased): `just changelog-unreleased v0.3.0`
18-
- Create release tag: `just tag v0.3.0` (creates annotated tag from CHANGELOG.md section)
1916
- Benchmarks: `cargo bench` (or `just bench`)
2017
- Build (debug): `cargo build` (or `just build`)
2118
- Build (release): `cargo build --release` (or `just build-release`)
22-
- CI simulation (lint + tests + examples + bench compile): `just ci`
19+
- Changelog (generate full): `just changelog` (runs `git-cliff -o CHANGELOG.md` + post-processing)
20+
- Changelog (prepend unreleased): `just changelog-unreleased v0.3.0`
2321
- Coverage (CI XML): `just coverage-ci`
2422
- Coverage (HTML): `just coverage`
23+
- Create release tag: `just tag v0.3.0` (creates annotated tag from CHANGELOG.md section)
2524
- Fast compile check (no binary produced): `cargo check` (or `just check-fast`)
2625
- Fast Rust tests (lib + doc): `just test`
2726
- Format: `cargo fmt` (or `just fmt`)
2827
- Integration tests: `just test-integration`
2928
- Lint (Clippy): `cargo clippy --all-targets --all-features -- -D warnings` (or `just clippy`)
3029
- Lint (Clippy, exact feature): `cargo clippy --features exact --all-targets -- -D warnings` (or `just clippy-exact`)
3130
- Lint/validate: `just check`
32-
- Pre-commit validation: `just ci`
31+
- Pre-commit validation / CI simulation: `just ci` (lint + tests + examples + bench compile)
32+
- Python setup: `uv sync --group dev` (or `just python-sync`)
3333
- Python tests: `just test-python`
3434
- Run a single test (by name filter): `cargo test solve_2x2_basic` (or the full path: `cargo test lu::tests::solve_2x2_basic`)
3535
- Run exact-feature tests: `cargo test --features exact --verbose` (or `just test-exact`)
36-
- Run examples: `just examples` (or `cargo run --example det_5x5` / `cargo run --example solve_5x5` / `cargo run --example const_det_4x4`)
36+
- Run examples: `just examples` (or `cargo run --example det_5x5` / `cargo run --example solve_5x5` /
37+
`cargo run --example const_det_4x4` / `cargo run --features exact --example exact_sign_3x3`)
3738
- Spell check: `just spell-check` (uses `typos.toml` at repo root; add false positives to `[default.extend-words]`)
3839

40+
## Feature flags
41+
42+
- `exact` — enables `det_sign_exact()` (adaptive-precision determinant sign via `BigRational`).
43+
Gates `src/exact.rs`, additional tests, and the `exact_sign_3x3` example.
44+
Clippy, doc builds, and test commands have dedicated `--features exact` variants.
45+
3946
## Code structure (big picture)
4047

4148
- This is a single Rust *library crate* (no `src/main.rs`). The crate root is `src/lib.rs`.
@@ -47,9 +54,17 @@ When making changes in this repo, prioritize (in order):
4754
- `src/ldlt.rs`: `Ldlt<const D: usize>` factorization without pivoting for symmetric SPD/PSD matrices (`solve_vec`, `det`)
4855
- `src/exact.rs`: `det_sign_exact()` — adaptive-precision determinant sign
4956
(Shewchuk-style f64 filter + Bareiss in `BigRational`); `features = ["exact"]`
50-
- A minimal `justfile` exists for common workflows (see `just --list`).
57+
- Rust tests are inline `#[cfg(test)]` modules in each `src/*.rs` file.
58+
- Python tests live in `scripts/tests/` and run via `just test-python` (`uv run pytest`).
5159
- The public API re-exports these items from `src/lib.rs`.
60+
- The `justfile` defines all dev workflows (see `just --list`).
5261
- Dev-only benchmarks live in `benches/vs_linalg.rs` (Criterion + nalgebra/faer comparison).
62+
- Python scripts under `scripts/`:
63+
- `criterion_dim_plot.py`: benchmark plotting (CSV + SVG + README table update)
64+
- `tag_release.py`: annotated tag creation from CHANGELOG.md sections
65+
- `postprocess_changelog.py`: strips trailing blank lines from git-cliff output
66+
- `subprocess_utils.py`: safe subprocess wrappers for git commands
67+
- Release workflow is documented in `docs/RELEASING.md`.
5368

5469
## Publishing note
5570

scripts/README.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,3 +118,41 @@ gnuplot --version
118118
```
119119

120120
This repo has been tested with `gnuplot 6.0 patchlevel 3` (Homebrew `gnuplot 6.0.3`).
121+
122+
## Changelog and release tooling
123+
124+
### Generating the changelog
125+
126+
```bash
127+
# Full regeneration from all history
128+
just changelog
129+
130+
# Prepend only unreleased changes for a new version
131+
just changelog-unreleased v0.3.0
132+
```
133+
134+
`just changelog` runs `git-cliff -o CHANGELOG.md` followed by
135+
`postprocess-changelog` (strips trailing blank lines). Configuration
136+
lives in `cliff.toml` at the repo root.
137+
138+
### Creating a release tag
139+
140+
```bash
141+
just tag v0.3.0 # create annotated tag from CHANGELOG.md section
142+
just tag-force v0.3.0 # recreate tag if it already exists
143+
```
144+
145+
The `tag-release` CLI (in `tag_release.py`) extracts the matching version
146+
section from `CHANGELOG.md`, validates semver, and handles GitHub's 125KB
147+
tag-annotation size limit.
148+
149+
### Scripts overview
150+
151+
| Script | Purpose |
152+
|---|---|
153+
| `criterion_dim_plot.py` | Plot Criterion benchmark results (CSV + SVG + README table) |
154+
| `tag_release.py` | Create annotated git tags from CHANGELOG.md sections |
155+
| `postprocess_changelog.py` | Strip trailing blank lines from git-cliff output |
156+
| `subprocess_utils.py` | Safe subprocess wrappers for git commands |
157+
158+
See `docs/RELEASING.md` for the full release workflow.

scripts/tag_release.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -115,11 +115,14 @@ def extract_changelog_section(changelog: Path, version: str) -> str:
115115
msg = f"No changelog section found for version {version}. Expected a heading like: ## [{version}] - YYYY-MM-DD"
116116
raise LookupError(msg)
117117

118-
# Trim leading/trailing blank lines
119-
while section and not section[0].strip():
120-
section.pop(0)
121-
while section and not section[-1].strip():
122-
section.pop()
118+
# Trim leading/trailing blank lines (O(n) index scan + slice)
119+
start = 0
120+
while start < len(section) and not section[start].strip():
121+
start += 1
122+
end = len(section)
123+
while end > start and not section[end - 1].strip():
124+
end -= 1
125+
section = section[start:end]
123126

124127
body = "\n".join(section)
125128
if not body.strip():
@@ -137,9 +140,10 @@ def _tag_exists(tag_version: str) -> bool:
137140
"""Return ``True`` if *tag_version* already exists as a git tag."""
138141
try:
139142
run_git_command(["rev-parse", "-q", "--verify", f"refs/tags/{tag_version}"])
140-
return True
141143
except subprocess.CalledProcessError:
142144
return False
145+
else:
146+
return True
143147

144148

145149
def _delete_tag(tag_version: str) -> None:

0 commit comments

Comments
 (0)