Contributing to ToolR¶
First off, thank you for considering contributing to ToolR! It's people like you that make ToolR such a great tool.
Table of Contents¶
- Code of Conduct
- Getting Started
- Development Setup
- How to Contribute
- Pull Request Process
- Coding Standards
- Testing Guidelines
- Commit Message Guidelines
- Security
- Development Workflow
- Code Review Guidelines
Code of Conduct¶
This project and everyone participating in it is governed by respect, professionalism, and inclusivity. By participating, you are expected to uphold these values. Please report unacceptable behavior by opening a GitHub Issue or contacting the project maintainers.
Our Standards¶
Positive behaviors include:
- Using welcoming and inclusive language
- Being respectful of differing viewpoints and experiences
- Gracefully accepting constructive criticism
- Focusing on what is best for the community
- Showing empathy towards other community members
Unacceptable behaviors include:
- Trolling, insulting/derogatory comments, and personal or political attacks
- Public or private harassment
- Publishing others' private information without explicit permission
- Other conduct which could reasonably be considered inappropriate in a professional setting
Getting Started¶
Prerequisites¶
Before contributing, make sure you have:
- Python 3.11+ installed
- Rust toolchain (for building native extensions)
- mise - Development environment manager
- gh CLI (optional, for GitHub Actions utilities)
- git for version control
First-time Contributors¶
New to open source? Here are some resources:
Look for issues labeled good first issue
or help wanted.
Development Setup¶
1. Fork and Clone¶
# Fork the repository on GitHub, then clone your fork
git clone https://github.com/YOUR_USERNAME/ToolR.git
cd ToolR
# Add upstream remote
git remote add upstream https://github.com/s0undt3ch/ToolR.git
2. Install mise¶
mise manages our development environment, including Python, Rust, and other tools (see https://mise.jdx.dev/getting-started.html).
curl https://mise.run | sh
# Install project tools
mise install
# Activate the environment
mise activate
This will automatically:
- Install the correct Python version
- Install the Rust toolchain
- Install uv package manager
- Set up other project dependencies
3. Install Dependencies¶
4. Install prek (Pre-commit Hooks)¶
We use prek instead of standard pre-commit:
5. Verify Setup¶
How to Contribute¶
Reporting Bugs¶
GitHub Issues are used for bug tracking. Before creating a bug report:
- Search existing issues to avoid duplicates
- Use the latest version of ToolR
- Collect information about your environment
When filing a bug report, include:
- Clear title and description
- Steps to reproduce the issue
- Expected vs actual behavior
- Environment details (OS, Python version, ToolR version)
- Error messages (full stack traces)
- Screenshots if applicable
Create a new issue to report bugs.
Suggesting Enhancements¶
Feature requests are also tracked as GitHub Issues. When creating an enhancement suggestion:
- Use a clear title describing the enhancement
- Provide a detailed description of the proposed functionality
- Explain why this would be useful to most ToolR users
- List examples of how the enhancement would be used
- Note any alternatives you've considered
Create a new issue to suggest features.
Pull Requests¶
GitHub Pull Requests are used for code contributions. Follow the pull request process below.
Your First Code Contribution¶
- Find an issue to work on (or create one)
- Comment on the issue to let others know you're working on it
- Create a branch from
main:
- Make your changes following our coding standards
- Write/update tests to cover your changes
- Run the test suite to ensure nothing breaks
- Commit your changes with descriptive messages
- Push to your fork and submit a pull request
Pull Request Process¶
Before Submitting¶
- [ ] Run all tests and ensure they pass
- [ ] Run prek to check linting, formatting, and types
- [ ] Update documentation if needed
- [ ] Add tests for new functionality
- [ ] Ensure commits follow our commit message guidelines
- [ ] Rebase on latest main if needed
Note: Do NOT manually update CHANGELOG.md - it's automatically generated from commit messages using git-cliff.
Submitting¶
- Push your branch to your fork
- Open a pull request against the
mainbranch - Write a clear PR description:
- What changes were made
- Why the changes are needed
- Any breaking changes
- Link related issues (e.g., "Closes #123")
- Respond to feedback and update as needed
PR Review Process¶
- Maintainers will review your PR within a few days
- You may be asked to make changes
- Once approved, maintainers will merge your PR
- Your contribution will be included in the next release!
CI Checks¶
All PRs must pass:
- ✅ Tests (pytest on Linux/macOS/Windows)
- ✅ Linting (ruff, via prek)
- ✅ Type checking (mypy, via prek)
- ✅ Formatting (ruff format, via prek)
- ✅ Rust checks (cargo clippy, cargo check, via prek)
- ✅ GitHub Actions (actionlint, via prek)
- ✅ Shell scripts (shellcheck, via prek)
- ✅ Security (CodeQL, dependency review)
- ✅ Spelling (codespell, typos, via prek)
- ✅ Markdown (markdownlint, via prek)
- ✅ Documentation (builds without errors)
All these checks run automatically via prek hooks and CI.
Coding Standards¶
Python Code¶
- Follow PEP 8 for style (enforced by ruff)
- Use type hints for all function signatures
- Use
from __future__ import annotationsat the top of files - Maximum line length: 120 characters
- Use ruff for linting and formatting (automated by prek)
- Use mypy for type checking (automated by prek)
from __future__ import annotations
from typing import Any
def greet(name: str, *, enthusiastic: bool = False) -> str:
"""Greet someone by name.
Args:
name: The name of the person to greet.
enthusiastic: Whether to add extra enthusiasm.
Returns:
A greeting message.
"""
greeting = f"Hello, {name}"
return f"{greeting}!" if enthusiastic else greeting
Rust Code¶
- Follow Rust style guidelines
- Use
cargo fmtfor formatting (automated by prek) - Use
cargo clippyfor linting (automated by prek) - Write doc comments for public APIs
- Add tests for new functionality
/// Greet someone by name.
///
/// # Arguments
///
/// * `name` - The name of the person to greet
///
/// # Returns
///
/// A greeting message
pub fn greet(name: &str) -> String {
format!("Hello, {}", name)
}
Documentation¶
- Use Google-style docstrings for Python
- Use Rustdoc for Rust code
- Include examples in docstrings
- Update docs/ when adding features
- Keep README.md up to date
Pre-commit Hooks¶
All formatting and linting is handled automatically by prek:
# Run all checks
prek run --all-files
# Run specific hook
prek run ruff-format
# Bypass hooks (use sparingly!)
git commit --no-verify
Testing Guidelines¶
Writing Tests¶
- Write tests for all new functionality
- Update tests when changing behavior
- Test edge cases and error conditions
- Use descriptive test names
- Keep tests focused (one concept per test)
Running Tests¶
# Run all tests
uv run pytest
# Run specific test file
uv run pytest tests/test_version.py
# Run with coverage
uv run coverage run -m pytest
uv run coverage report
# Run Rust tests
cargo test
# Run specific Rust test
cargo test test_name
Test Organization¶
tests/
├── cli/ # CLI argument parsing tests
├── context/ # Context and runtime tests
├── parser/ # Parser tests
├── registry/ # Command discovery and registry tests
├── utils/ # Utility function tests
├── support/ # Test fixtures and support files
├── conftest.py # Shared fixtures
└── test_*.py # Additional test modules
Property-Based Testing¶
ToolR uses Hypothesis for property-based testing (fuzzing):
from hypothesis import given
from hypothesis import strategies as st
@given(st.text())
def test_handles_any_input(text: str) -> None:
"""Test that the function handles any text input."""
result = process_text(text)
assert isinstance(result, str)
Commit Message Guidelines¶
We follow Conventional Commits for clear commit history and automated changelogs.
Format¶
Types¶
- feat: New feature
- fix: Bug fix
- docs: Documentation changes
- style: Code style changes (formatting, etc.)
- refactor: Code refactoring
- perf: Performance improvements
- test: Adding or updating tests
- build: Build system changes
- ci: CI configuration changes
- chore: Other changes (dependencies, etc.)
Examples¶
feat(cli): add --verbose flag for detailed output
Add a --verbose flag to enable detailed logging output.
This helps users debug issues with command execution.
Closes #123
---
fix(version): correct git describe pattern for multi-digit versions
The pattern v[0-9].[0-9].[0-9] only matched single digits.
Changed to v[0-9]*.[0-9]*.[0-9]* to support versions like v0.11.0.
Fixes #456
---
docs: update contributing guidelines with commit conventions
Breaking Changes¶
For breaking changes, add BREAKING CHANGE: in the footer:
feat(api)!: remove deprecated get_version function
BREAKING CHANGE: The get_version() function has been removed.
Use version.current() instead.
Why Conventional Commits?¶
- Automated changelog generation using git-cliff
- Semantic versioning automation
- Clear history for understanding project evolution
- Better collaboration through standardized messages
Security¶
Reporting Vulnerabilities¶
DO NOT open a public issue for security vulnerabilities.
Instead, use GitHub Security Advisories to privately report security issues.
See our Security Policy for more details.
Security Best Practices¶
When contributing:
- Never commit secrets (API keys, passwords, tokens)
- Pin action versions to commit SHAs in workflows
- Validate user input to prevent injection attacks
- Use secure defaults in configurations
- Review dependencies for known vulnerabilities
Development Workflow¶
Branch Naming¶
feature/description- New featuresfix/description- Bug fixesdocs/description- Documentation updatesrefactor/description- Code refactoringtest/description- Test additions/updates
Daily Development¶
# Update your fork
git checkout main
git pull upstream main
git push origin main
# Create feature branch
git checkout -b feature/my-feature
# Make changes, commit often
git add .
git commit -m "feat: add my feature"
# Run checks before pushing
prek run --all-files
# Push to your fork
git push origin feature/my-feature
# Open a pull request on GitHub
Keeping Your Branch Updated¶
# Fetch latest changes
git fetch upstream
# Rebase your branch
git rebase upstream/main
# Force push if already pushed
git push --force-with-lease origin feature/my-feature
Code Review Guidelines¶
For Contributors¶
- Respond promptly to review feedback
- Ask questions if feedback is unclear
- Make requested changes or explain why not
- Mark conversations as resolved when addressed
- Be respectful and professional
For Reviewers¶
- Review thoroughly but constructively
- **Provide specific feedback