Contributing to Nuvom¶
Thank you for considering contributing to Nuvom โ a lightweight, plugin-first task execution engine.
We welcome improvements in stability, performance, plugin support, documentation, bug fixes, and any enhancement that makes Nuvom a more reliable and developer-friendly tool.
๐ฆ Project Setup (with Hatch)¶
We use Hatch for managing environments, dependencies, testing, and packaging.
1. Clone the repository¶
git clone https://github.com/nahom-zewdu/Nuvom
cd Nuvom
````
### 2. Install Hatch (once)
```bash
pip install hatch
3. Enter the development shell¶
hatch shell
This activates a fully isolated dev environment with all dependencies.
4. Run tests¶
pytest
5. Try the CLI¶
nuvom --help
๐งฉ Plugin-Based Development¶
Most Nuvom components are extensible via base interfaces and the Plugin protocol.
โ Add a New Queue Backend¶
- Subclass
BaseJobQueuefromnuvom.queue_backends.base. -
Implement:
-
enqueue,dequeue,pop_batch,qsize,clear -
Register:
-
via
.env, or - via
.nuvom_plugins.toml(preferred) - Add tests under
tests/queue_backends/
โ Add a New Result Backend¶
- Subclass
BaseResultBackendfromnuvom.result_backends.base. -
Implement:
-
set_result,get_result,set_error,get_error,get_full,list_jobs - Register the plugin
- Add tests under
tests/result_backends/
๐งช Plugin Testing¶
Use the CLI to test plugin loading:
nuvom plugin test
nuvom plugin list
nuvom plugin inspect <plugin_name>
Example .nuvom_plugins.toml:
[plugins]
queue_backend = ["my_module:MyQueuePlugin"]
result_backend = ["my_module:MyResultPlugin"]
๐งช Testing & Coverage¶
We use pytest. All new features must include tests.
pytest
Test philosophy:
- Use actual backends in test cases
- Cover all logic branches, including edge/failure cases
- Include both CLI and programmatic tests
- For plugin tests, use isolated
.nuvom_plugins.tomlin a temp dir
๐งผ Code Style & Linting¶
Follow PEP8 and our project standards.
Format & lint code¶
hatch run fmt
Which runs:
black .ruff check .
See pyproject.toml for configuration.
๐ง Logging Guidelines¶
- Use
nuvom.log.logger, notprint() logger.debugโ internalslogger.infoโ lifecycle events (e.g., job started)logger.errorโ job or system failures
๐ Commit Conventions¶
Use semantic, scoped commit messages. Examples:
feat(plugins): add dynamic plugin registry and loader
feat(result): support SQLite result backend
feat(worker): implement graceful shutdown logic
test(plugin): add test for plugin-registered backend
docs: update CONTRIBUTING for plugin architecture
๐ Suggested Directory Layout¶
nuvom/
โโโ cli/ # Typer CLI commands
โโโ queue_backends/ # Job queues (memory, SQLite, etc.)
โโโ result_backends/ # Task result stores
โโโ plugins/ # Loader, registry, capabilities
โโโ execution/ # JobRunner and context
โโโ discovery/ # Static task discovery logic
โโโ registry/ # Task registry and hook system
โโโ task.py # @task decorator
โโโ config.py # App config loader (pydantic)
โโโ log.py # Rich-based logger
โโโ worker.py # Worker pool, threading, retry
โ Best Practices¶
- Think in small, testable units
- Prefer clarity over cleverness
- Avoid global state unless essential
- Use plugin-based injection when adding new backends
- Document public APIs with docstrings
- Follow the
Plugincontract for lifecycle integration
๐ค Code Review Process¶
- Fork the repo, create a feature branch
- Add code and tests
- Submit a PR with a clear title and description
- A maintainer will review and provide feedback
- Once approved, the PR is merged into the main branch
๐ฌ Need Help?¶
Feel free to open an issue โ questions, bugs, and ideas are all welcome.
For more context, see README.md and docs/architecture.md.
Happy contributing! ๐๐ง