Development

This page covers all aspects of contributing to FABulous, including development environment setup, coding standards, and contribution workflows.

Development Environment Setup

Contributors must use uv for reproducible environment management and to ensure consistent dependency resolution with CI.

Note

Recommended setup for full development (including ASIC backend) For end-to-end development, including the ASIC backend flow and EDA tooling, use the Nix-based installation provided in this repository. Nix ensures the full toolchain (GHDL, Yosys, NextPNR, OpenROAD, Librelane, etc.) is available and reproducible.

Use uv alongside Nix for Python-related dependency management of the FABulous project itself (locking, editable installs, tasks), as documented below. The Dev Container is available as a fallback when Nix is not accessible, but Nix remains the preferred method whenever possible.

Installing uv

Linux/macOS:

curl -LsSf https://astral.sh/uv/install.sh | sh

Restart your shell or source the env snippet the installer prints.

macOS with Homebrew:

brew install uv

Windows:

powershell -c "irm https://astral.sh/uv/install.ps1 | iex"

PyPI:

pip install uv

Setting up the development environment

Clone the repository and set up the development environment:

git clone https://github.com/FPGA-Research/FABulous
cd FABulous
uv sync --dev                # install runtime + dev dependencies (locked)
uv pip install -e .          # editable install
source .venv/bin/activate    # activate the environment (optional)

Note

After running uv sync, uv creates a virtual environment in .venv/. You can either:

  • Use uv run <command> for each command (recommended for reproducibility)

  • Activate the environment with source .venv/bin/activate and run commands directly

Common development commands:

# Using uv run:
uv run FABulous -h           # run CLI with project dependencies
uv run pytest               # run test suite
uv run pytest -k test_name  # run specific test
uv run ruff check           # lint code
uv run ruff format          # format code

# Or with activated environment:
(.venv) $ FABulous -h
(.venv) $ pytest
(.venv) $ ruff check
(.venv) $ ruff format

Dependency management:

uv add <package>             # add runtime dependency
uv add --group dev <package> # add development dependency
uv remove <package>          # remove dependency
uv lock                      # refresh lock file after manual edits

Dev Container (Docker-based Development)

For contributors who prefer a containerized development environment, FABulous provides a pre-configured Dev Container setup. This option is intended as a fallback for contributors who cannot use Nix or do not have access to it; Nix remains the preferred method when it is available.

Working in the Container

Once inside the container, the workspace is mounted at /workspaces. You can run FABulous commands directly:

FABulous -h                  # run CLI
pytest                       # run test suite
ruff check                   # lint code
ruff format                  # format code

Note

The Dev Container uses an editable install, so any changes you make to the FABulous source code are immediately reflected without reinstalling.

Alternative: Running the Docker Image Directly

If you prefer to use the Docker image without VS Code, you can run it directly:

# Pull the development image
docker pull ghcr.io/fpga-research/fabulous:dev

# Run interactively with your local repo mounted
docker run -it --rm -v $(pwd):/workspaces ghcr.io/fpga-research/fabulous:dev

# Or use the release image (non-editable install)
docker pull ghcr.io/fpga-research/fabulous:latest
docker run -it --rm ghcr.io/fpga-research/fabulous:latest FABulous -h

Pre-commit Hooks

We use pre-commit hooks to maintain code quality. These hooks automatically run formatters and linters before each commit.

Install pre-commit hooks:

uv run pre-commit install

The hooks will now run automatically on git commit. You can also run them manually:

uv run pre-commit run --all-files

If you need to bypass the hooks temporarily (not recommended):

git commit --no-verify

Task Automation with Taskfile

FABulous includes a root Taskfile to streamline common development and workflow tasks. After setting up the development environment, you can run these tasks using task <task-name>.

task test           # Run the pytest suite (supports forwarded args, see below)
task ci             # Run pre-commit hooks and build docs
task smoke-test     # Full end-to-end check: create demo, generate fabric, run simulation
task docs-build     # Build the documentation
task docs-server    # Serve docs with live-reload
task clean-all      # Remove build artefacts and caches
task sync-demo      # Synchronise demo tile GDS configuration
task upgrade        # Upgrade lockfiles, update Nix flake, run tests

Example Workflows

Before submitting a PR:

task ci

Run tests with custom options:

task test -- -p 8             # 8 parallel groups
task test -- -p auto -k foo   # filter by name
task test -- --runslow        # include slow tests

Full integration smoke test:

task smoke-test

Documentation development:

task docs-server

Note

All available tasks are listed with task --list. Full definitions are in the root Taskfile.yml.

Code Standards

Code Formatting

We use Ruff for both linting and formatting. The configuration is defined in ruff.toml in the repository root.

Format your code before committing:

uv run ruff format

Check for linting issues:

uv run ruff check
uv run ruff check --fix  # auto-fix issues where possible

Documentation Style

  • Follow numpy docstring style

  • Keep docstrings concise but complete

  • Include examples for complex functions

  • Update documentation when changing APIs

Testing

  • Write tests for new functionality

  • Ensure existing tests pass before submitting PRs

  • Run the full test suite: uv run pytest

  • Check test coverage where applicable

Coding Assistants and Generative AI

Using coding assistants or generative AI tools for development is permitted. However, contributors must adhere to the following guidelines:

  • Quality standards apply equally. AI-assisted contributions are held to the same quality standards as manually written code. Low-quality, boilerplate-heavy, or poorly structured code will be rejected regardless of how it was produced.

  • You are responsible for your submissions. Contributors bear full responsibility for the correctness, licensing, and quality of all code they submit, whether it was written manually, generated by AI tools, or created through any other means.

  • Understand what you submit. You must be able to explain and defend every change in your contribution. Submitting code you do not understand is not acceptable.

  • Follow project conventions. AI-generated code must conform to the project’s coding standards, formatting rules, and architectural patterns. Run task ci before submitting.

Contribution Workflow

We follow a standard Git workflow for contributions. Please ensure you’re familiar with this process before contributing.

Getting Started

  1. Check the issues and the latest commits at the FABulous main branch to see if your feature or bug fix has already been reported or implemented.

  2. Fork the repository on GitHub.

  3. Clone your forked repository to your local machine.

  4. Use the latest version of the main branch as base for your work.

Making Changes

  1. Create a new branch for your feature or bug fix:

    git checkout -b feature/your-feature-name
    
  2. Set up the development environment as described above.

  3. Make your changes, following the coding standards outlined in this document.

  4. Write or update tests as necessary.

  5. Ensure all tests pass and code is properly formatted.

  6. Commit your changes with clear, descriptive commit messages using the conventional commits style.

Submitting Changes

  1. Push your changes to your forked repository:

    git push origin feature/your-feature-name
    
  2. Submit a pull request to the main repository.

  3. Ensure your pull request targets the main branch of the original repository.

  4. Check that your pull request passes all CI checks. If it does not, please fix the issues first.

  5. We will review your pull request and may request changes or provide feedback. Please be responsive to these requests.

Commit Message Style

We use the conventional commits style for commit messages and pull requests. This helps us automatically generate changelogs and understand the history of changes better.

Format: <type>[(<optional scope>)]: <description>

Examples:

  • feat: add support for new tile type

  • fix: resolve bitstream generation issue

  • docs: update installation instructions

  • test: add integration tests for fabric generator

  • chore(ci): update workflow

Types:

  • feat: new feature

  • fix: bug fix

  • docs: documentation changes

  • test: adding or updating tests

  • refactor: code refactoring

  • perf: performance improvements

  • chore: maintenance tasks

Development Notes

Environment Management

  • Always use uv for development to ensure dependency resolution is consistent with CI

  • Issues arising only under ad-hoc pip environments may be closed with a request to reproduce under uv

  • The uv.lock file is the authoritative source for exact dependency versions

  • When adding dependencies, prefer adding them via uv add rather than manually editing pyproject.toml

Project Structure

  • Development dependencies are defined in the [dependency-groups] section of pyproject.toml

  • Regular dependencies are in the [project] dependencies list

  • Test configuration is in [tool.pytest.ini_options] in pyproject.toml

  • Pre-commit configuration is in .pre-commit-config.yaml

CI/CD

  • All pull requests must pass CI checks

  • CI runs tests, linting, and formatting checks

  • CI uses the same uv-based environment as local development

  • Lock file changes are automatically validated

License

By contributing to this project, you agree that your contributions will be licensed under the project’s Apache 2.0 License.