Testing and Quality Checks
Run the smallest check that covers the changed behavior, then run the component's broader gate before opening a pull request. Integration tests require the local services described in Development Environment.
Treefmt
treefmt.toml is the repository-wide formatting entry point. It dispatches by file type:
| Files | Formatter |
|---|---|
| Rust | rustfmt, edition 2024 |
| Java | google-java-format with AOSP style |
| Scala/SBT | Scalafmt |
| Python | Ruff format |
| TOML | Taplo |
| YAML/JSON | Prettier |
Markdown is not currently included in treefmt.toml.
Format changed files:
treefmt path/to/changed-file another/changed-file
Check without modifying files:
treefmt --ci -- path/to/changed-file another/changed-file
Nix users can run the pinned formatter set directly:
nix develop .#formatter --command \
treefmt --ci -- path/to/changed-file another/changed-file
Generated files, build output, lockfiles, and paths listed under excludes in treefmt.toml are intentionally skipped. The GitHub Format Check workflow is authoritative.
Lefthook
lefthook.yml defines local Git hooks. Lefthook is a hook runner; it does not replace Treefmt or Clippy.
After installing the lefthook executable, install this repository's hooks once per clone:
lefthook install
The configured hooks are:
| Hook | Command | Scope |
|---|---|---|
pre-commit | treefmt --ci -- {staged_files} | Staged Rust, Java, Scala/SBT, Python, TOML, YAML, and JSON files |
pre-push | cargo clippy --no-deps --all-features --all-targets --workspace -- -D warnings | Complete Cargo workspace; warnings fail the push |
Run a hook explicitly while diagnosing a failure:
lefthook run pre-commit
lefthook run pre-push
The pre-push hook is intentionally expensive. Run targeted component tests before it so failures are easier to isolate. Hook success does not replace the component CI workflows.
Rust
Start PostgreSQL before metadata or IO integration tests. Some tests also require RustFS and a test bucket.
Run one package:
cargo -q test -p lakesoul-io
cargo -q test -p lakesoul-metadata
Run the complete Rust test profile used by CI:
RUST_BACKTRACE=full \
cargo -q test --profile test-fast --lib --bins --tests --jobs 2
Exercise the v2 merge path separately:
LAKESOUL_IO_USE_V2_MERGE=true RUST_BACKTRACE=full \
cargo -q test --profile test-fast --lib --bins --tests --jobs 2
Run Clippy with the same strict workspace command as Lefthook:
cargo clippy --no-deps --all-features --all-targets --workspace -- -D warnings
JVM connectors
Build the native C ABI libraries before tests that load JNI:
cargo -q build --release \
-p lakesoul-io-c \
-p lakesoul-metadata-c
Run one Maven module and its dependencies:
mvn -q -B test \
-pl :lakesoul-spark-3.5_2.12 -am \
-Pcross-build --file pom.xml
mvn -q -B test \
-pl :lakesoul-flink-1.20_2.12 -am \
-Pcross-build --file pom.xml
Large Spark suites are split across CI jobs. Prefer a focused -Dtest=SuiteName locally, and preserve -Dsurefire.failIfNoSpecifiedTests=false when the selected suite does not exist in every reactor module.
Python
From python/, install the development group and build the extension first:
uv sync --group dev
uvx --from 'maturin>=1,<2' maturin develop
Run one test file or directory:
uv run pytest -q tests/io/test_writer.py
uv run pytest -q tests/ray_tests/
Run all Python tests:
uv run pytest tests/
Tests that access PostgreSQL read LAKESOUL_PG_URL, LAKESOUL_PG_USERNAME, and LAKESOUL_PG_PASSWORD. S3 integration tests additionally require RustFS, the expected bucket, and the test-specific environment flags.
Website
Build both locales and validate links:
cd website
npm run build
For a visual change, also start the site and inspect the affected English and Chinese pages in a browser:
npm run start
Before opening a pull request
- Format every changed supported source file with Treefmt.
- Run the narrow test that proves the changed behavior.
- Run the affected component's broader test or build gate.
- Run the strict Clippy hook when Rust changed.
- Build the website when documentation changed.
- Keep generated files and lockfile changes limited to intentional dependency or code-generation updates.
Contribution workflow, branch names, and pull-request conventions are defined in CONTRIBUTING.md.