0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ROS 2のament_lintシリーズのCLIとTEST(CMakeLists.txt)とGithub Actions

Posted at

まえがき

lint/formatは複数人で作業するときに重要ですが,開発環境を整えるのが少し煩わしかったり種類がいっぱいあればセットアップの方法もいっぱいあります.
ros2 pkg create <pakage_name> --build-type ament_cmakeで生成されるCMakeLists.txtやpackages.xmlにはちょこっと書かれていますが,自分はこれが何者なのか全くわかっていませんでした.
せっかくなので,この方法を出来るだけ活用できないか模索することにしました.

筆者環境

architecture amd64
(Host OS) Ubuntu24.04
OS ros:jazzyベースのdocker container上
rosdistro jazzy

以下では例として主にclang-formatを扱っていきます.
他のlinterを選択する場合はclang-formatの部分を置き換えてください

CLI

純粋にコマンドラインをたたいてlint/formatを実行する方法です.

インストールは以下の通りです.

command
sudo apt install ros-<rosdistro>-ament-clang-format

そして以下のように実行します

command
ament-clang-format .

どのlinter/formmaterが用意されているかはament-lintのリポジトリを参照します.
あるいはapt list ros-<rosdistro>-ament-*でも確認できます(こちらだとclang-formatのバージョン指定ができることもわかる)

オプション指定などは各lint packageのdocs/index.rstを読みます
clang-format(https://github.com/ament/ament_lint/blob/rolling/ament_clang_format/doc/index.rst) の場合version指定などができることがわかります

TEST (CMakeLists.txt)

(これが自分にとっては理解まで時間がかかりました)
順番に説明していきます.

最小構成

ある一つのament_lintを使いたい場合は以下のように記述します

package.xml
  <test_depend>ament_cmake_clang_format</test_depend>
CMakeLists.txt
find_package(ament_cmake REQUIRED)
if(BUILD_TESTING)
  find_package(ament_cmake_clang_format REQUIRED)
  ament_clang_format()
endif()

これでcolcon testを実行するとlintも一つのtestとして実行されます.

ament_lint_common

よく使うであろうlinter/formatterをまとめたものです.ちなみにclang_formatは含まれていないのでこんな記述になります.

package.xml
  <test_depend>ament_lint_common</test_depend>
  <test_depend>ament_cmake_clang_format</test_depend>

(CMakeLists.txtの記述は一旦省略)
これで下記リンク先に書かれている複数のament_lintを<test_depend>で追加しているのと同じになります.

ament_lint_auto

CMakeLists.txt内のlint関係の記述を簡潔にするためのツールです(自分はament_cmake_autoと混同していました)
ament_lint_auto_find_test_dependencies()を実行することで,package.xmlに書かれたament_lint系を見つけてきて実行するようになっています.
これらament_lint_commonとament_lint_autoを含んだものがros2 pkg createしたときに生成されてます.

package.xml
  <test_depend>ament_lint_auto</test_depend>
  <test_depend>ament_lint_common</test_depend>
  <test_depend>ament_cmake_clang_format</test_depend>
CMakeLists.txt
if(BUILD_TESTING)
  find_package(ament_lint_auto REQUIRED)
  set(ament_cmake_copyright_FOUND TRUE)
  set(ament_cmake_cppcheck_FOUND TRUE)
  set(ament_cmake_cpplint_FOUND TRUE)
  set(ament_cmake_uncrustify_FOUND TRUE)
  set(ament_cmake_clang_format_CONFIG_FILE .clang-format)
  ament_lint_auto_find_test_dependencies()
endif()

ちなみにここでしれっとset(ament_cmake_clang_format_CONFIG_FILE .clang-format)と.clang-formatファイルを参照するように指定しています.
また自分の環境では.clang-formatでカスタマイズした部分がcpplintやuncrustifyと衝突するので,これらのlintをset(ament_cmake_xxx_FOUND TRUE)で実行しないようにしています.
(こんなに無効化するならament_lint_commonを指定せず個別に設定するほうが良かったかも…などと思っているところです)

pre-commit

これはnav2の記述にならいます.
ament_lintに関係する部分だけ抜粋するとこんな感じ

.pre-commit-config.yaml
repos:
  - repo: local
    hooks:
      - id: ament_clang_format
        name: ament_clang_format
        description: Code style checking using clang-format.
        language: system
        types: [c++]
        entry: ament_clang_format --config .clang-format --reformat   # gitリポジトリルートのの設定ファイルを参照する場合
      - id: ament_flake8
        name: ament_flake8
        description: Check Python code style using flake8.
        language: system
        types: [python]
        entry: ament_flake8
      - id: ament_lint_cmake
        name: ament_lint_cmake
        description: Check CMake code style using cmakelint.
        language: system
        types: [cmake]
        entry: ament_lint_cmake
      - id: ament_pep257
        name: ament_pep257
        description: Check Python code style using pep257.
        language: system
        types: [python]
        entry: ament_pep257
      - id: ament_xmllint
        name: ament_xmllint
        description: Check XML markup using xmllint.
        language: system
        types: [xml]
        entry: ament_xmllint

つまりはCLIの使い方をしています
ほかのlinter/formatterを使いたい場合も同様です

Github Actions

前章でTestに組み込んだのでCIでTestを回せばよいですが,Testのworkflowとは別に作っておきたい気持ちがありました.
無課金のprivateリポジトリなので

  • なるべくworkflowにかかる時間を減らしたい(apt installなどの環境セットアップを最小限に)
  • ある程度管理されてそう(公式?)なものを選ぶ

あたりを気にした結果,やはりnav2やturtlebot3と同じようにします.
利用するciはこれ

/github/workflows/check.yml
  ament_lint:
    name: ament_${{ matrix.linter }}
    runs-on: ubuntu-latest
    container:
      image: rostooling/setup-ros-docker:ubuntu-noble-ros-jazzy-ros-base-latest
    strategy:
      fail-fast: false
      matrix:
        linter: [clang-format, flake8, lint_cmake, pep257, xmllint]
    steps:
      - uses: actions/checkout@v5
      - uses: ros-tooling/action-ros-lint@0.1.4
        with:
          linter: ${{ matrix.linter }}
          distribution: jazzy
          package-name: "*"
          arguments: ${{ matrix.linter == 'clang-format' && '--config .clang-format' || '' }}

clang-formatのconfigファイルを参照するためにargumentsを記述しています

おまけ:testをactionsで実行するよさげな方法

ちょっと脱線ですが,テストも実行しておきたかったのでこのCIを利用します.

.github/workflows/ci.yml
name: Check Build Test and Coverage

on:
  pull_request:
  push:
    branches:
      - master

jobs:
  build_and_test:
    runs-on: ubuntu-latest
    container:
      image: rostooling/setup-ros-docker:ubuntu-noble-ros-jazzy-ros-base-latest
    steps:
      - uses: actions/checkout@v5
      - name: Build and run tests
        uses: ros-tooling/action-ros-ci@v0.4
        with:
          import-token: ${{ secrets.GITHUB_TOKEN }}
          target-ros2-distro: jazzy
          colcon-mixin-repository: https://raw.githubusercontent.com/colcon/colcon-mixin-repository/master/index.yaml
          colcon-defaults: |
            {
              "build": {
                "mixin": ["coverage-gcc", "coverage-pytest"]
              },
              "test": {
                "mixin": ["coverage-pytest"]
              }
            }

lintに関しては二重に実行されることになりますが…
workflow起動ごとにROS 2をインストールするのを出来るだけ減らせるはずです.

参考リンク集

ROS 2のコードスタイルの推奨が書かれているところ

ament_lintについて説明しているROS 2のページ

ament_lintのリポジトリ

具体的にどう使っているのか知るために
navigation2(nav2)とturtlebot3のリポジトリも参考にしました.

日本語記述だとこのスライドが参考になりました

おわりに

パラメータファイルなどROSで多用するyamlのlintはamentシリーズになさそうで,探しているとPRはありました.

なんだか凍結状態ですが…
ament_lint_yamllintほしい!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?