Aerostack2

DocsDevelop

Setting up

Prepare a clone of Aerostack2 for development, with the git hooks, the linters and your editor.

Authored by
  • @alvgaona

To work on Aerostack2 you need a source checkout, the git hooks that check your code before each commit, and an editor that follows the same style rules. This page sets up all three.

Get the code

If you're not a member of the Aerostack2 organization, clone your fork instead of the main repository, as Opening a pull request explains. How you build it depends on your system.

Build Aerostack2 in a colcon workspace, as in Installation from source. Export the compile commands when you build, so your editor knows how each C++ file is compiled:

cd ~/aerostack2_ws
colcon build --symlink-install --cmake-args -DCMAKE_EXPORT_COMPILE_COMMANDS=ON

Each package then has a compile_commands.json in its build folder. Most editors read a single file at the root of the workspace, so merge them:

jq -s 'add' build/*/compile_commands.json > compile_commands.json

You can also use Pixi on Linux, as described for macOS.

Install the git hooks

Aerostack2 checks style with the same linters ROS 2 uses, from ament_lint. They run as git hooks, managed by lefthook, inside a Pixi environment called lint. That environment holds only the linters, so it installs quickly and doesn't build Aerostack2, whichever way you installed it.

Install Pixi if you don't have it, then install the hooks once in your clone:

cd ~/aerostack2_ws/src/aerostack2
pixi run -e lint lefthook install

From then on, every commit runs these checks on the files you staged.

HookChecksFiles
commitlintThe message follows Conventional CommitsThe commit message
uncrustifyFormattingC++
cpplintThe Google C++ style rulesC++
flake8PEP 8, import order and quotesPython
pep257DocstringsPython
xmllintWell-formed XML that matches its schemaXML

Folders whose names start with _ or ., third-party code and a few generated files are skipped, the same as in the package tests.

Run the linters yourself

uncrustify can fix the formatting it complains about. Pass it the files or folders to fix:

pixi run -e lint ament_uncrustify --reformat as2_core/src

To check the whole repository instead of what you staged:

pixi run -e lint lefthook run pre-commit --all-files

The package tests run a few more linters than the hooks do. as2 test adds copyright, which checks the license header of every file, cppcheck, and lint_cmake for the CMakeLists.txt.

Format with the Pixi uncrustify

The lint environment pins uncrustify 0.72, the version Humble ships. Newer releases, like the ones Jazzy and Homebrew ship, format some code differently, so formatting with your system's uncrustify can produce changes the hooks then reject.

Set up your editor

Your editor can apply the same rules as you type. The configuration files the linters use are inside the lint environment:

find .pixi/envs/lint -name ament_code_style.cfg -o -name ament_flake8.ini
ToolConfiguration
uncrustifyament_uncrustify/configuration/ament_code_style.cfg, run with .pixi/envs/lint/bin/uncrustify
flake8ament_flake8/configuration/ament_flake8.ini, with a line length of 99
cpplintA line length of 100, with the filters in ament_cpplint/main.py

In VS Code, with the C/C++, Flake8 and Uncrustify extensions, these settings point them at the compile commands and the configuration files:

.vscode/settings.json
{
  "C_Cpp.default.compileCommands": "${workspaceFolder}/compile_commands.json",
  "[cpp]": {
    "editor.defaultFormatter": "zachflower.uncrustify",
    "editor.formatOnSave": true
  },
  "uncrustify.executablePath.linux": "<path to .pixi/envs/lint/bin/uncrustify>",
  "uncrustify.configPath.linux": "<path to ament_code_style.cfg>",
  "flake8.args": ["--config=<path to ament_flake8.ini>"]
}

Replace the paths with absolute ones, using what find printed. On macOS the uncrustify settings end in .osx instead of .linux.

Last updated on November 3, 2026

On this page

Last updated on November 3, 2026