This guide covers development setup, testing, and contributing to the PCILeech Firmware Generator.
For Local Development (requires voltcyclone-fpga submodule):
git clone --recurse-submodules https://github.com/voltcyclone/PCILeechFWGenerator.git
cd PCILeechFWGenerator
python3 -m venv .venv && source .venv/bin/activate
pip install -r requirements-dev.txt
pip install -e .For Container Development (no submodule needed):
# Clone without submodules
git clone https://github.com/voltcyclone/PCILeechFWGenerator.git
cd PCILeechFWGenerator
# Build container (automatically clones voltcyclone-fpga)
podman build -t dma-fw .Note for local development: The --recurse-submodules flag is required to initialize the voltcyclone-fpga submodule at lib/voltcyclone-fpga.
If you already cloned without submodules, initialize them with:
git submodule update --init --recursiveNote for container builds: The container automatically clones the voltcyclone-fpga repository during the build process, eliminating the need for git submodule management. See Container Builds for details.
pip install pre-commit
pre-commit install
pre-commit install --hook-type commit-msg# Run all tests
make test
# Run unit tests only (fast)
make test-unit
# Run TUI tests
make test-tui
# Run fast tests only
make test-fastThe project includes comprehensive template validation to ensure all Jinja2 templates have proper variable definitions.
# Validate templates (non-blocking)
make check-templates
# Validate with strict mode (fails on issues)
make check-templates-strict
# Generate suggested fixes
make check-templates-fix# Basic validation
python scripts/validate_template_variables.py
# Strict mode for CI
python scripts/validate_template_variables.py --strict --format json
# Generate detailed fixes
python scripts/validate_template_variables.py --generate-fixes --verbose
# Summary format for quick checks
python scripts/validate_template_variables.py --format summary# Lint code
make lint
# Format code
make format
# Security scan
make security# Build package
make build
# Full PyPI package build
make build-pypi
# Quick build for testing
make build-quickAll Jinja2 templates must have properly defined variables. The template validation system:
- Analyzes templates for undefined variables
- Checks conditional statements like
{% if var is defined %} - Validates against requirements defined in
TemplateContextValidator - Suggests fixes for missing variables
When adding new templates:
- Define variable requirements in
src/templating/template_context_validator.py - Test template rendering with proper context
- Run template validation before committing:
make check-templates-strict
{# Good: Use variables with proper defaults #}
{% if enable_feature %}
// Feature enabled
{% endif %}
{# Avoid: Conditional existence checks #}
{% if enable_feature is defined %}
// This pattern should be avoided
{% endif %}-
Template Validation (
.github/workflows/template-validation.yml)- Validates all template variables
- Checks template syntax
- Generates reports for PRs
-
Main CI (
.github/workflows/ci.yml)- Includes template validation step
- Non-blocking to avoid build failures
The pre-commit configuration includes:
- Code formatting (Black, isort)
- Linting (flake8, mypy)
- Security scanning (bandit)
- Template validation (custom hook)
- Create feature branch from
main - Make changes following code style
- Run validation with
make check-templates-strict - Run tests with
make test - Commit with conventional commit format
- Push and create pull request
For template-related changes:
- Update variable requirements if needed
- Test rendering with real data
- Validate templates pass strict checks
- Document any new variables
- Python: Black formatting, PEP 8 compliance
- Templates: Consistent indentation, clear variable usage
- Commits: Conventional commits format
- Documentation: Clear, comprehensive
# Analyze specific template
python scripts/validate_template_variables.py --verbose
# Check template syntax only
python -c "
from jinja2 import Environment, FileSystemLoader
env = Environment(loader=FileSystemLoader('src/templates'))
template = env.get_template('your_template.j2')
print('Template syntax is valid')
"# Check environment setup
make check-deps
# Install development dependencies
make install-dev
# Clean build artifacts
make cleanscripts/validate_template_variables.py- Template validationscripts/check_templates.sh- Convenient template checkingscripts/analyze_imports.py- Import analysisscripts/generate_api_docs.py- Documentation generationscripts/iommu_viewer.py- Lightweight IOMMU group and device viewer (useful for VFIO debugging)
Run make help for all available targets:
make helpKey development targets:
check-templates- Template validationtest- Run test suitelint- Code lintingformat- Code formattingclean- Clean artifacts
- Always validate templates before committing
- Use strict mode in CI to catch issues early
- Document new variables in context validator
- Test with real data when possible
- Follow conventional commits for clear history