Contributing
Thank you for your interest in contributing to undatum! This document provides guidelines and instructions for contributing.
Development Setup
Prerequisites
- Python 3.10 or higher (we support CPython versions that have not reached end of life)
- Git
- pip
Installation
- Clone the repository:
git clone https://github.com/datenoio/undatum.git
cd undatum
- Create a virtual environment:
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
- Install development dependencies:
make install-dev
# or
pip install -e ".[dev]"
The dev extra pins the tool versions used by CI (ruff, mypy) and installs pytest and
pre-commit. Python 3.10 is the minimum supported version; use it for type checking.
Code Style
All checks run with make check-all (format check, lint, type check, tests).
Formatting
ruff format formats the code (line length 100):
make format # ruff format undatum/ tests/ scripts/
make format-check # what CI runs
Linting
ruff check is the only linter. Besides pycodestyle, pyflakes, isort, bugbear,
comprehensions and pyupgrade, it applies a selection of pylint rules (PL) and Google-style
docstring rules (D) for undatum/cmds/ and undatum/sdk/:
make lint # ruff check + dependency bound check
Every runtime dependency and extra in pyproject.toml needs a lower and an upper version
bound (scripts/check_dependency_bounds.py); the "lowest direct dependencies" CI job tests
the lower bounds.
Type Checking
mypy runs as a ratchet: mypy-baseline.json records the number of errors per file, and CI
fails when a file gets more errors than recorded. undatum/common/ is fully annotated and
checked with disallow_untyped_defs.
make type-check # python scripts/mypy_ratchet.py
make type-baseline # after fixing errors: lock in the lower counts
Pre-commit Hooks
Install pre-commit hooks to run ruff before every commit:
pre-commit install
Documentation
Docstring Style
We use Google-style docstrings for consistency. Example:
def example_function(param1: str, param2: int = 10) -> bool:
"""Brief description of the function.
Longer description explaining what the function does, any important
details about its behavior, and any relevant context.
Args:
param1: Description of param1.
param2: Description of param2 (default: 10).
Returns:
Description of return value.
Raises:
ValueError: When param1 is invalid.
Example:
>>> result = example_function("test", 20)
>>> print(result)
True
"""
pass
Documentation site
User-facing docs are this Docusaurus site. Edit markdown in docs/docs/, then:
cd docs
npm install
npm start # local preview
npm run build # production build (also `make docs`)
Parts of the site are generated, and CI fails when they are stale. Regenerate them after changing the corresponding code:
python scripts/generate_cli_reference.py # CLI options or help text
python scripts/generate_sdk_reference.py # SDK docstrings or signatures
python scripts/generate_result_schemas.py # JSON result layouts
python scripts/generate_rule_reference.py # validation rule catalogue
python scripts/run_doc_examples.py docs/docs/commands/head.md # run a page's examples
Shell examples run in CI against fixture files; mark blocks that need a server, cloud storage
or an AI provider as bash norun.
See the docs README and GitHub Pages setup. The published site is https://datenoio.github.io/undatum/.
Testing
Running Tests
Run all tests:
pytest
Run with coverage:
pytest --cov=undatum --cov-report=html
Writing Tests
- Place tests in the
tests/directory - Test files should be named
test_*.py - Use descriptive test function names:
test_function_name_scenario
Pull Request Process
-
Create a branch: Create a feature branch from
mastergit checkout -b feature/your-feature-name -
Make changes: Make your changes following the code style guidelines
-
Run checks: Ensure all checks pass:
make check-all # ruff format check, ruff lint, mypy ratchet, pytest -
Commit: Write clear commit messages following conventional commits:
feat: add new featurefix: fix bug in converterdocs: update READMErefactor: improve performance -
Push: Push your branch and create a pull request
-
Review: Address any feedback from reviewers
Code Review Guidelines
- All code must be reviewed before merging
- Ensure tests pass and coverage is maintained
- Follow the existing code style
- Add documentation for new features
- Update CHANGELOG.md for user-facing changes
Reporting Issues
When reporting issues, please include:
- Description of the issue
- Steps to reproduce
- Expected behavior
- Actual behavior
- Python version
- undatum version
- Relevant error messages or logs
Questions?
Feel free to open an issue for questions or reach out to the maintainers.
Community
- Prefer GitHub Discussions for Q&A and ideas; use Issues for bugs and actionable feature requests. See Community.
- Look for the
good first issuelabel when getting started. - External contributors are welcome — undatum has persistent usage but historically few PRs; small focused patches (tests, docs, install fixes) are especially helpful.
- Dependency-bot PRs should be auto-merged for patch-level security bumps or closed promptly rather than left unattended.
Release discipline (CLI stability)
- Follow semver for user-facing CLI changes.
- Call out breaking command/flag changes loudly in
CHANGELOG.md. - Prefer deprecation warnings before removing flags that agents or scripts may depend on.
- Keep a stable-command guarantee for core verbs (
convert,stats,validate,select) whenever possible.