|
| 1 | +# Contributing |
| 2 | + |
| 3 | +Thanks for helping out. docling.rs is a Rust port of |
| 4 | +[docling](https://github.com/docling-project/docling); the guiding constraint is |
| 5 | +**conformance**: output is validated against upstream Python docling, byte-for-byte |
| 6 | +where the format allows it. |
| 7 | + |
| 8 | +## Setup |
| 9 | + |
| 10 | +```bash |
| 11 | +git clone https://github.com/docling-project/docling.rs |
| 12 | +cd docling.rs |
| 13 | +cargo build |
| 14 | + |
| 15 | +# Optional — only for the ML pipeline (PDF layout/OCR/tables, ASR, enrichment): |
| 16 | +scripts/install/download_dependencies.sh # models/ + .pdfium/ |
| 17 | +``` |
| 18 | + |
| 19 | +Without models and pdfium the declarative converters (DOCX, HTML, XLSX, PPTX, EPUB, …) |
| 20 | +and text-layer PDFs work fine, and the test suite stays green — tests that need runtime |
| 21 | +assets skip themselves. |
| 22 | + |
| 23 | +## Build & test |
| 24 | + |
| 25 | +```bash |
| 26 | +cargo test --lib --tests -p docling-core -p docling -p docling-asr -p docling-serve -p docling-pdf |
| 27 | +cargo clippy --workspace --all-targets -- -D warnings |
| 28 | +cargo fmt --all |
| 29 | +``` |
| 30 | + |
| 31 | +Prefer `--lib --tests` over a bare `cargo test`: it skips the example binaries, each of |
| 32 | +which statically links onnxruntime and adds gigabytes to `target/`. |
| 33 | + |
| 34 | +CI additionally checks: |
| 35 | + |
| 36 | +- MSRV: `docling-core` on 1.85, the workspace on 1.88; |
| 37 | +- `wasm32-unknown-unknown`: `cargo check -p docling --no-default-features [--features pdf-text]`, |
| 38 | + a release build of `docling-wasm`, and its host-side tests; |
| 39 | +- GPU feature combinations for `docling-cli` / `docling-rag` / `docling-pdf`; |
| 40 | +- `cargo test --workspace --locked`. |
| 41 | + |
| 42 | +If you touch the Python or Node bindings, check them from their own directories |
| 43 | +(`cd crates/docling-py && cargo check`) — they are excluded from the workspace default |
| 44 | +members. |
| 45 | + |
| 46 | +## Conformance |
| 47 | + |
| 48 | +The corpus lives in `tests/data/<format>/sources/` with `groundtruth/` produced by |
| 49 | +published Python docling. Declarative formats must match **byte-for-byte**; the ML |
| 50 | +pipeline is pinned by deterministic snapshots. |
| 51 | + |
| 52 | +```bash |
| 53 | +scripts/conformance/pdf_groundtruth.sh # PDF vs the committed groundtruth (no docling install) |
| 54 | +scripts/conformance/conformance.sh <format> # installs docling and diffs against it |
| 55 | +DOCLING_RS_REGEN=1 cargo test -p docling --test regression # regenerate intentional output changes |
| 56 | +``` |
| 57 | + |
| 58 | +A change that moves conformance numbers must say so in the pull request and update |
| 59 | +`docs/PDF_CONFORMANCE.md` / `docs/MIGRATION.md` with the real measured numbers. |
| 60 | + |
| 61 | +## Conventions |
| 62 | + |
| 63 | +- **Options plumb through every surface in one pull request**: library builder on |
| 64 | + `DocumentConverter` → CLI flag → serve option (multipart field + JSON body + query |
| 65 | + param) → Python kwarg → Node option. Grep an existing option (`page_range`, |
| 66 | + `video_frames`) for the full pattern. |
| 67 | +- **Degradation over failure**: a missing optional tool or model warns and degrades; only |
| 68 | + "nothing convertible at all" is an error. |
| 69 | +- **Comments explain *why*** — docling parity, a performance trade-off, a corpus fixture |
| 70 | + that forced the shape. What the code does should be readable from the code. |
| 71 | +- **Docs are part of the change**: `README.md` for user-facing behavior, |
| 72 | + `docs/MIGRATION.md` for the parity table, `docs/PDF_CONFORMANCE.md` for pipeline/model |
| 73 | + changes. |
| 74 | +- New behavior needs a test — ideally a corpus fixture, otherwise a unit test that pins |
| 75 | + the specific case. |
| 76 | + |
| 77 | +## Commits and pull requests |
| 78 | + |
| 79 | +- One feature per branch, branched off fresh `master`. Don't stack unrelated work. |
| 80 | +- **Sign off every commit**: `Signed-off-by: Name <email>` (`git commit -s`). |
| 81 | +- Reference issues in the message (`Refs #123`). |
| 82 | +- Commit subjects drive releases: a merge whose commits are all `fix:` / `perf:` / |
| 83 | + `revert:` cuts a patch version; anything else bumps the minor. Prefix bug fixes |
| 84 | + accordingly and don't worry about the rest. Docs- or CI-only merges publish nothing. |
| 85 | +- Describe in the pull request what you ran: which suites, which conformance numbers |
| 86 | + moved. |
| 87 | + |
| 88 | +## Reporting bugs |
| 89 | + |
| 90 | +Include the input format, the exact command or API call, the docling.rs version, and — |
| 91 | +where the output is wrong rather than absent — what Python docling produces for the same |
| 92 | +file. A minimal reproducing file is worth more than a description of one. |
| 93 | + |
| 94 | +## License |
| 95 | + |
| 96 | +MIT. By contributing you agree your work is licensed under it. |
0 commit comments