Contributing to SoS
November 5, 2025 ยท View on GitHub
Thank you for your interest in contributing to SoS! This document provides guidelines and instructions for contributing to the project.
Table of Contents
- Development Setup
- Building the Project
- Running Tests
- Code Style
- Making Changes
- Submitting Pull Requests
- Deployment
Development Setup
Prerequisites
- Python 3.9 or higher
- Git
- uv (recommended) or pip
Installing uv (Recommended Package Manager)
uv is a fast Python package installer and resolver written in Rust. It's significantly faster than pip and provides better dependency resolution.
# Install uv on macOS/Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
# Or using pip
pip install uv
# Or using Homebrew (macOS)
brew install uv
# On Windows
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"
Setting Up Your Development Environment
- Fork and clone the repository
# Fork the repository on GitHub, then:
git clone https://github.com/YOUR_USERNAME/SoS.git
cd SoS
git remote add upstream https://github.com/vatlab/SoS.git
- Set up Python environment with uv (recommended)
# uv will automatically create a virtual environment and use Python 3.9
# (specified in .python-version file)
uv venv
# Activate the virtual environment
source .venv/bin/activate # On Windows: .venv\Scripts\activate
# Sync all dependencies including dev dependencies
uv sync --all-extras
# Or sync with specific extras
uv sync --extra dev --extra unix # On Linux/macOS
uv sync --extra dev --extra win # On Windows
- Alternative: Traditional pip setup
# Create virtual environment
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# Install in development mode
pip install -e ".[dev]"
# For platform-specific dependencies
pip install -e ".[dev,unix]" # On Linux/macOS
pip install -e ".[dev,win]" # On Windows
- Install pre-commit hooks
# With uv
uv pip install pre-commit
pre-commit install
# Or with pip
pip install pre-commit
pre-commit install
Managing Dependencies
Adding Dependencies
# Add a runtime dependency
uv add requests
# Add a development dependency
uv add --dev pytest-mock
# Add an optional dependency to an extra group
uv add --optional dot graphviz
# Update all dependencies to latest compatible versions
uv lock --upgrade
Installing Dependencies
# Install all dependencies (including dev)
uv sync --all-extras
# Install only runtime dependencies
uv sync
# Install with specific extras
uv sync --extra dot --extra dev
Updating Dependencies
# Update a specific package
uv lock --upgrade-package pytest
# Update all packages
uv lock --upgrade
# Show outdated packages
uv pip list --outdated
Building the Project
SoS now uses modern Python packaging with pyproject.toml and the hatchling build backend.
Building Distributions
# Using uv (fastest)
uv build
# Or using pip with build
pip install build
python -m build
# Output will be in dist/
ls dist/
# sos-0.25.2-py3-none-any.whl
# sos-0.25.2.tar.gz
Building Documentation
# Install documentation dependencies
pip install sphinx sphinx-rtd-theme
# Build docs
cd docs
make html
# View at docs/_build/html/index.html
Running Tests
Using Invoke Tasks (Recommended)
The project includes an Invoke task system for common development operations:
# List all available tasks
invoke --list
# Run tests
invoke test
invoke test --verbose --coverage
invoke test --keyword "test_bash"
invoke test --markers "not slow"
# Format code
invoke format
invoke format --check # Check without modifying
# Run linting
invoke lint
invoke lint --fix # Auto-fix issues
# Run all checks (format, lint, test)
invoke check
# Clean build artifacts
invoke clean
invoke clean --all # Also remove .venv
# Build distribution packages
invoke build
# Show or update dependencies
invoke deps-show
invoke deps-show --outdated
invoke deps-update
invoke deps-update --package pytest
# Shortcuts (aliases)
invoke t # test
invoke l # lint
invoke fmt # format
invoke c # clean
Manual Test Running
# Change to test directory
cd test
# Build required Docker containers for Docker tests
sh build_test_docker.sh
# Run all tests
python run_tests.py
# Or using pytest directly
pytest
# Run with coverage
pytest --cov=sos --cov-report=html
Running Specific Tests
# Using invoke
invoke test-file test/test_actions.py
invoke test --keyword "test_bash"
# Using pytest directly
pytest test/test_actions.py
pytest test/test_actions.py::test_function_name
pytest -k "test_bash"
pytest -v # verbose
pytest -x # stop on first failure
Code Quality Checks
# Using invoke (recommended)
invoke format # Format code with ruff
invoke lint # Check code with ruff
invoke lint --fix # Auto-fix linting issues
invoke pre-commit # Run pre-commit hooks
invoke check # Run all checks
# Manual commands
uv run ruff check src/
uv run ruff format src/
uv run ruff check --fix src/
pre-commit run --all-files
Code Style
- Follow PEP 8 guidelines
- Use meaningful variable and function names
- Add docstrings to all public functions and classes
- Keep functions small and focused
- Write tests for new features
Example Code Style
def calculate_sum(numbers: List[int]) -> int:
"""Calculate the sum of a list of numbers.
Args:
numbers: List of integers to sum
Returns:
The sum of all numbers
Raises:
ValueError: If the list is empty
"""
if not numbers:
raise ValueError("Cannot sum an empty list")
return sum(numbers)
Making Changes
Development Workflow
- Create a new branch
git checkout -b feature/your-feature-name
# or
git checkout -b fix/issue-number
- Make your changes
# Edit files
# Add tests for new functionality
# Update documentation if needed
- Use Invoke tasks for development
# Format your code
invoke format
# Check for linting issues
invoke lint --fix
# Run tests for your changes
invoke test --keyword "your_test"
# Run full check before committing
invoke check
- Commit your changes
git add .
git commit -m "Brief description of changes"
Quick Development Commands
# One-line development cycle
invoke format && invoke lint --fix && invoke test
# Check everything before push
invoke check
# Clean and rebuild
invoke clean && invoke build
Commit Message Guidelines
- Use present tense ("Add feature" not "Added feature")
- Use imperative mood ("Move cursor to..." not "Moves cursor to...")
- Limit first line to 72 characters
- Reference issues and pull requests when relevant
Example:
Fix Docker execution with Python 3.12
- Update subprocess calls for compatibility
- Add error handling for missing containers
- Update tests to cover new behavior
Fixes #1234
Submitting Pull Requests
- Push your branch
git push origin feature/your-feature-name
- Create a Pull Request
- Go to https://github.com/vatlab/SoS
- Click "New Pull Request"
- Select your branch
- Fill in the PR template with:
- Description of changes
- Related issues
- Testing performed
- Checklist items
- PR Requirements
- Tests pass locally
- Code follows project style guidelines
- Documentation updated if needed
- Commit messages are clear
- PR description explains the changes
Deployment
Publishing to PyPI
For maintainers only:
- Update version
# Edit src/sos/_version.py
# Update __version__ = "X.Y.Z"
- Create a release commit
git add src/sos/_version.py
git commit -m "Release version X.Y.Z"
git tag vX.Y.Z
git push origin master --tags
- Build and upload
# Clean previous builds
rm -rf dist/ build/
# Build distributions
python -m build
# Check the distributions
twine check dist/*
# Upload to TestPyPI first (optional)
twine upload --repository testpypi dist/*
# Upload to PyPI
twine upload dist/*
Publishing to Conda-Forge
The conda-forge package is maintained separately. After PyPI release:
- Fork https://github.com/conda-forge/sos-feedstock
- Update the version and SHA256 in
recipe/meta.yaml - Submit a PR to conda-forge
Getting Help
- Issues: https://github.com/vatlab/SoS/issues
- Discussions: https://github.com/vatlab/SoS/discussions
- Gitter Chat: https://gitter.im/vatlab/SoS
- Documentation: https://vatlab.github.io/sos-docs
Additional Resources
License
By contributing to SoS, you agree that your contributions will be licensed under the same 3-clause BSD License that covers the project.