エラー逃さずYARDドキュメントをCIで検証する
この記事について
こんにちは、okumudです。Rubyのドキュメンテーションに使われるYARDをCIチェックするヒントをお伝えします。執筆時のYARDバージョンは0.9.34
です。
ソースコードを読むことが多いため、YARDドキュメントを記載しています。しかし、記載ミスなどがよくあるため、CIでチェックしたいと考えていました。
課題1: CIでYARDエラーを検知できない
ありがちな間違いを含むコードでチェックを試みます。
# frozen_string_literal: true
# Personクラスは人の情報を表します
class Person
# Personオブジェクトを初期化します
#
# @params name [String] 人の名前 <= 誤ってsをつけてしまっている
# @param [Integer] 人の年齢 <= 変数名の記載漏れ
def initialize(name, age)
@name = name
@age = age
end
# @!attribute [r] name
# @returns [String] 人の名前 <= 誤ってsをつけてしまっている
# @!attribute [r] age
# @return [Integer] 人の年齢
attr_reader :name, :age
# 人の情報を文字列で返します
#
# @return [String] 人の名前と年齢を含む文字列
def to_s
"#{@name}, #{@age}歳"
end
end
警告があるにも関わらず、exit codeが0
(正常)となり、CIがエラーになりません。
$ bundle exec yard stats ./person.rb
[warn]: Unknown tag @params in file `person.rb` near line 9
[warn]: @param tag has unknown parameter name: 人の年齢
in file `person.rb' near line 9
[warn]: Unknown tag @returns in file `person.rb` near line 18
[warn]: Unknown tag @returns in file `person.rb` near line 18
...中略...
80.00% documented
$ echo $?
0
--fail-on-warning
オプションを使い、YARDエラーを検知する
解決方法: --fail-on-warning
を付与してチェックを行うと、exit codeが1
となり、エラーを検知できます。
$ bundle exec yard stats ./person.rb --fail-on-warning
...中略...
$ echo $?
1
参考: `yard stats`のヘルプに`--fail-on-warning`オプションの記載がありました
$ bundle exec yard stats --help
Usage: yard stats [options] [source_files]
(if a list of source files is omitted, lib/**/*.rb ext/**/*.{c,rb} is used.)
General Options:
-b, --db FILE Use a specified .yardoc db to load from or save to
(defaults to .yardoc)
--[no-]single-db Whether code objects should be stored to single
database file (advanced)
-n, --no-output Only generate .yardoc database, no documentation.
-c, --use-cache [FILE] Use the cached .yardoc db to generate documentation.
(defaults to no cache)
--no-cache Clear .yardoc db before parsing source.
--[no-]yardopts [FILE] If arguments should be read from FILE
(defaults to yes, FILE defaults to .yardopts)
--[no-]document If arguments should be read from .document file.
(defaults to yes)
--no-save Do not save the parsed data to the yardoc db
--exclude REGEXP Ignores a file if it matches path match (regexp)
--fail-on-warning Exit with error status code if a warning occurs
--list-undoc List all undocumented objects
--compact Compact undocumented objects listing
Rails.application.routes.url_helpers
等でYARDエラーとなる
課題2: 前述の例では問題の箇所を修正することで対応できますが、エラーとなることをわかっていて無視したいことがあります。特にシリアライザ等で、 Rails.application.routes.url_helpers
を使っている場合、エラーとなって、CIが通らない状態となってしまいます。
class StatusUrlSerializer < ActiveModel::Serializer
include Rails.application.routes.url_helpers
attributes :identifier, :status_url
def status_url
external_service_status_url(identifier: object.identifier)
end
end
[warn]: in YARD::Handlers::Ruby::MixinHandler: Undocumentable mixin: YARD::Parser::UndocumentableError for class StatusUrlSerializer
in file 'app/serializers/status_url_serializer.rb':4:
4: include Rails.application.routes.url_helpers
find
とsed
で無視したい行を削除する
解決方法: 設定等では回避することが難しいので、 該当行のコメントで、# yard:ignore
などを記述し、 YARD のチェックを行う時は該当行を削除した状態にする方法があります。
find . -type f -name "*.rb" -print0 | xargs -0 sed -i -e '/ yard:ignore/s/.*//'
注意: 上記コマンドを実行した後は該当行が消えてしまうので、後続の処理が無いことを確認してから組み込むようにしてください。
まとめ
yard stats --fail-on-warning
のように、--fail-on-warning
を指定すると、コマンドの実行結果がエラーとして返ってきます。# yard:ignore
などが含まれる行を除外してからチェックすると、YARDのエラーを許容することができます。
付録
GitHub ActionsでYARDドキュメントをチェックする
ほぼGitHub Actionsのサンプル通りですが、次のように記述することで、確認が可能になります。
name: Ruby
on:
push:
pull_request:
branches: [ "main" ]
permissions:
contents: read
jobs:
yard:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Ruby
uses: ruby/setup-ruby@v1.147.0
with:
ruby-version: '3.2'
bundler-cache: true # runs 'bundle install' and caches installed gems automatically
- name: Clean up ignored yard
run: find . -type f -name "*.rb" -print0 | xargs -0 sed -i -e '/ yard:ignore/s/.*//'
- name: Run tests
run: bundle exec yard stats --fail-on-warning ./*.rb
ワークフローの実行結果
失敗時の結果:ワークフローがエラーとなっている
成功時の結果:ワークフローが成功している
.yardopts
へ記載する
よく使用するオプションは設定ファイルYARD ドキュメントを生成するときにprivateメソッドも常に出力したい場合は、オプションに ---private
等を追加しますが、毎回書くには長すぎるので、 .yardopts
へ記載しましょう。
--private
--markup markdown
--plugin activesupport-concern
--tag override:Overridden Method
-
README.md
Discussion