codometer-configure について
Codometer の設定ファイルを作成するためのスキルです。入力、除外、出力形式、メトリクスの上限やカスタム統計を設定し、宣言数やコメント予算の計測方法も扱います。
主な機能
- 01計測対象の入力と除外の設定
- 02レポート形式と出力先の設定
- 03メトリクス上限と重要度の定義
- 04カスタムカウンターの宣言
- 05宣言数とコメント予算の計測
活用シーン
- 01生成されたビルド出力の計測
- 02実行時のコードベース指標のゲート設定
- 03指定した宣言やコメントの追跡
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ organizzolini/ codebase --skill codometer-configureインストール後、Claude Code で/codometer-configureを入力して読み込まれたか確認します。
詳細
codometer の設定を書く
codometer.config.{ts,mts,cts,js,mjs,cjs,json,jsonc} は、実行時に --config <path> で指定されたパスから読み込まれます。この指定は必須です。ファイルの検索は行われず、デフォルトのファイルもありません。このリポジトリでは、ワークスペースの設定ファイルは configuration/codometer.config.ts、各プロジェクトの設定ファイルはそのプロジェクトの codometer.config.ts です。指定したファイルが別のファイルとマージされることはありません。このフォルダーには適用されないマージ済みの制限も、実際に適用される制限と見分けがつかなくなるためです。format はすべての設定で指定が必要な唯一のフィールドです。コード側にフォールバックはありません。それ以外のフィールドはすべて省略可能です。
import { type CodometerConfiguration } from "@codometer/configuration";
const codometerConfiguration: CodometerConfiguration = {
format: "markdown",
exclude: ["notepads/**"],
excludeFrom: ["configuration/.codometerignore"],
defaultInput: "codebase",
limits: [{ metric: "typescript.interfaces", severity: "warn", value: 500 }],
inputs: [
{
analyses: ["size"],
include: ["dist/**/*.js", "!dist/**/*.map.js"],
name: "compiled",
},
],
outputs: [{ path: "README.md", type: "markdown" }],
};
export default codometerConfiguration;
出力パスは設定ファイルの場所ではなく、プロセス自身の作業ディレクトリを基準に解決されます。そのため、configuration/ フォルダーに置かれた設定ファイルでも、実行時に指定した場所に出力されます。設定ファイルは常にプレーンなオブジェクトとして読み込まれます。設定を関数として記述する方法はないため、1つのファイルだけでワークスペース内のすべてのプロジェクトを記述することはできません。多数のプロジェクトがあるリポジトリでは、各プロジェクトに独自の codometer.config.ts を用意し、このリポジトリの configuration/codometer.config.ts と同様に、共通のオブジェクトをそれぞれに展開します。
除外
ファイルの検出時にはすでに .gitignore が適用されるため、exclude と excludeFrom は、残すファイルのうち、手作業で書かれたものではないファイル(ロックファイル、ベンダー提供のバンドル、生成されたドキュメントなど)に使用します。
| オプション | 構文 | 用途 |
|---|---|---|
exclude | グロブ | インラインで指定する少数のパス |
excludeFrom | gitignore 構文のファイルへのパス | リポジトリ内のファイルに記述しておきたいリスト |
既存の無視ファイルを再利用する際は、注意が必要です。多くの場合、そのファイルは別のツールの用途に合わせて書かれています。フォーマッターが処理しないという理由で Markdown をすべて除外する .prettierignore を codometer にも指定すると、Markdown の指標がすべて失われます。通常は、別のツールが管理するファイルを流用するのではなく、専用の .codometerignore を使うのが適切です。
入力
入力とは、グロブで照合される名前付きのファイルセットであり、そのセットに対して分析が実行されます。測定対象のディレクトリは常に codebase という名前の独立した入力になります。inputs ではそれ以外の入力を宣言します。多くの場合、これはすべての .gitignore で除外されているビルド出力です。ビルド出力にアクセスするには、除外ではなく入力として指定する必要があります。
| フィールド | 必須 | デフォルト | 説明 |
|---|---|---|---|
name | はい | — | この入力の一意な名前 |
include | はい | — | ファイルを追加するグロブ。少なくとも1つは、除外だけでなくファイルを追加する必要があります |
exclude | いいえ | なし | ファイルを除外するグロブ |
analyses | はい | — | "language"、"size"、または両方 |
compression | いいえ | gzip | size 分析で使う gzip、brotli、または none |
directory | いいえ | . | この入力のグロブを開始する場所。プロセスの作業ディレクトリからの相対パス |
include の ! 接頭辞はファイルを除外します。配列内のすべての否定指定は、入力全体に適用される1つの集合を形成するため、配列の順序を変えても照合結果は変わりません。exclude に ! を付けることはできません。すでに除外する指定であり、そこで否定する対象はないためです。宣言された入力には無視ファイルは適用されません。これにより、コンパイル済みの出力も照合できます。
入力に codebase という名前を付けると、組み込みのツリー全体のスキャンが置き換えられ、その横に追加されるわけではありません。読み込まれるのは compression と analyses だけで、include と exclude は参照されません。ツリー全体のスキャンは、グロブとの照合ではなく、無視ファイルをたどって検出されるためです。ツリーの一部を測定するには、別の名前で入力を宣言してください。
上限
上限は、測定対象の指標がどこまで大きくなり得るかを制限します。圧縮後のサイズ、行数、宣言されたカウンターの数など、どの指標にも設定できます。上限がない指標は、これまでどおり何にも制限されず、測定・報告されます。
defaultInput: "codebase",
limits: [
{ metric: "compiled.size", value: "8 KB" },
{ label: "Interfaces", metric: "typescript.interfaces", value: 500 },
{ metric: "linesOfCode", severity: "warn", value: 100_000 },
],
| 項目 | 必須 | 既定値 | 意味 |
|---|---|---|---|
metric | はい | — | 上限を設定する指標のドット区切りパス |
value | はい | — | 数値、または単位を含む文字列で指定する上限値 |
severity | いいえ | fail | 超過時に fail は実行を停止し、warn は報告のみ行います |
label | いいえ | パス | レポートでこの上限を示す名前 |
指標は、入力名の後にその入力内のパスを続けて指定します。defaultInput を設定すると、接頭辞のないパスはその入力の指標として解決されます。ただし、同じ名前を持つ別の入力が存在しない場合に限ります。入力名と指標グループ名が重複する可能性がある場合は、入力名を常に省略せずに記述してください。パスが曖昧な場合は推測せず、必ず拒否されます。指標が存在しないパスや、入力で実行されていない分析の指標を指定した場合も同様に拒否されます。
文字列で指定する値の単位は 10 進数で、末尾の b が必須です。"8 KB" は 8000 バイト、"1 MB" は 1000000 バイトです。"8 K" は何かの値として解釈されず、拒否されます。どのファイルにも一致しない入力があっても、その入力に対して上限が設定されている場合に限り実行が失敗します。上限を宣言することは、対象のファイルが存在するべきだと表明することです。
違反を通過させるために、上限の value を引き上げないでください。 設定した上限はコードベースの状態に関する約束です。その約束を破った変更で上限を引き上げると、上限が保持しようとしていた証拠が失われます。違反が実際のリグレッションである場合は、測定対象を減らしてください。指標の値を減らす、ファイルを分割する、不要なコードを削除するなどの方法があります。今後この指標が保持すべき値に対して上限自体が不適切だった場合も、意図的に判断して説明する価値があります。約束を破った変更と同時に、ひそかに数値を引き上げるべきではありません。違反がほかの原因による可能性がある場合は、codometer-triage スキルを利用してください。
カスタム統計
トップレベルの custom 配列は、カウンターを測定するためのものです。ここで宣言すると、出力のどこに表示されるか、あるいは表示されるかどうかに関係なく、カウンターが計算されます。
custom: [
{ label: "Service Files", patterns: ["**/*.service.ts"] },
{ label: "Unit Tests", patterns: ["**/*.unit.test.ts"] },
{ color: "16a34a", label: "Migrations", patterns: ["**/migrations/*.sql"] },
],
各エントリは、選択されたすべての場所に、設定順で 1 つのバッジとして表示されます。color は shields.io 形式の 16 進数 3 桁の色です。省略すると、グループごとに組み込みパレットから次の色が使われるため、カウンターの色は実行ごとに変わりません。カウンターの集計対象は、patterns、symbols、comment の 3 つのフィールドのうち、いずれか 1 つで指定します。これらをどれも指定していないエントリは、常に 0 として報告されるのではなく、拒否されます。
outputs エントリ独自の custom 配列は、それとは別の後続処理で使用されます。トップレベルのカウンターのうち、その出力先に表示するものをラベルで選択します。カウンター自体を宣言するものではないため、JSON レポートと Markdown レポートでそれぞれ異なるラベルを選択できます。
outputs: [
{ custom: ["Service Files"], path: "codometer-report.json", type: "json" },
{ custom: ["Unit Tests"], path: "README.md", type: "markdown" },
],
トップレベルの custom で宣言されていないラベルを出力が選択した場合、設定の読み込み時に拒否されます。選択によって、まだ測定されていないカウンターを作り出すことはできません。custom で宣言されたものの、どの出力にも選択されていないカウンターも測定され、上限の判定対象になります。ただし、どこにも表示されません。
宣言のカウント
symbols は、ファイルではなく TypeScript および JavaScript のソース内の宣言をカウントします。
custom: [
{ group: "typescript", label: "Static Methods", symbols: { kinds: ["method"], modifiers: ["static"] } },
],
kinds は class、enum、function、getter、interface、method、property、setter の 1 つ以上です。modifiers は、abstract、async、export、override、private、protected、public、readonly、static のうち指定されたすべての修飾子を持つ宣言に絞り込みます。どちらも構文から文字どおりに判定されます。クラスメンバーは method で、それ以外の呼び出し可能なものはすべて、アロー関数を含めて function です。また、アロー関数を格納するクラスフィールドは property となり、そのフィールド自体の修飾子は付きません。
シンボルカウンターの patterns は、カウント対象ではなく、検索するファイルを絞り込みます。group は、指定したグループの組み込み項目の後にバッジを配置します。デフォルトは conventions で、組み込みの言語グループも指定できます。それ以外の名前を指定すると、何も表示されないのではなく、設定エラーになります。
コメント予算の選択
comment は、ファイルや宣言の数を数えるのではなく、カウンターで計測するコメント予算を選択します。独自の comments/documentation の仕組みはもうありません。コメント予算は通常のカスタム統計であり、その custom.<label> メトリックに対する limits[] エントリーによって、カウントがゲートになります。これは、ほかのすべてのカウンターと同じ統合の仕組みです。
custom: [
{ comment: { language: "yaml", maximumWords: 128 }, label: "YAML Comment Budget" },
{ comment: { kind: "class", maximumLines: 24 }, label: "Class Comment Budget" },
],
limits: [{ metric: "custom.YAML Comment Budget", value: 0 }],
| フィールド | 必須 | デフォルト | 意味 |
|---|---|---|---|
language | いいえ | コメントを含むすべての言語 | css、hcl、python、shell、sql、toml、typescript、yaml のいずれかに絞ります |
kind | いいえ | 通常のコメントブロック | この宣言種別のドキュメント化された宣言にある、JSDoc 形式のコメントに絞ります |
maximumCharacters | いいえ | — | マーカーや改行などをすべて含めた、ブロックが保持できる文字数 |
maximumLines | いいえ | — | ブロックがまたぐことのできる行数 |
maximumWords | いいえ | — | マーカーを除去した後に、ブロックが保持できる文章の単語数 |
severity | いいえ | fail | 違反時に fail は実行を停止し、warn は報告のみを行います |
カウントは、セレクター独自の上限を超えたブロックの数です。instances には、違反した各ブロックの file と1始まりの line に加え、計測値が記録されます。予算内に収まったブロックは、どちらにも加算されません。
comment セレクターは継承を行いません。 言語ごとのエントリーがマージされるトップレベルのデフォルトはありません。そのため、「すべての言語で128語、ただし shell は256語」とするには、共有予算に上書きを加えるのではなく、言語ごとにセレクターを1つずつ記述します。このリポジトリの configuration/codometer.config.ts では、CODOMETER_COMMENT_LANGUAGES からその一覧を導出し、スキーマに追加された言語がこのリポジトリの一覧で網羅されるまでコンパイルエラーになるよう型付けしています。コメントの計測を始める言語も、その一覧に追加されるまではゲートされません。スキーマに言語を追加しても、自動でゲートされることはありません。
3つの上限は、unit で切り替える1つの maximum ではなく、別々のフィールドです。なぜなら、これらは代替関係ではないからです。 ブロックは行数の予算内でありながら、単語数の予算を超えることがあります。省略したフィールドは計測されず、数値がデフォルトで設定されることもありません。誰も記述していない予算は、誰も選んでいない予算です。
予算はブロック単位であり、ファイル全体ではありません。 ブロックとは、読み手がひとまとまりの考えとして捉えるコメント行の連続です。空行でブロックは終わり、値の後ろにあるコメントがその上のブロックに含まれることはありません。また、#! のシバンはコメントではありません。comment セレクターにファイル全体を対象とする機能はありません。適切なサイズのコメントが40個あるファイルと、1つの長い論説文があるファイルは別の問題ですが、現在の codometer には後者を計測する方法がありません。
リンターがすでに行の長さを列数の上限内に抑えている場合は、文字数よりも単語数の予算を優先してください。文字数のカウントは、フォーマットで既に強制されていることを言い換えるだけですが、単語数の予算ならコメントの内容を制限できます。デフォルトでは JSDoc はゲートされません。kind を指定した comment セレクターで対象にできますが、これを宣言するのは意図的な選択であり、言語名を指定しただけで対象になるわけではありません。
違反とは何か、また何ではないか
違反にはファイル名と行番号が示されます。該当箇所を短くするか、詳細を記載する余地のあるドキュメントに移してください。実行を通すために 上限値を引き上げてはいけません。上限の value を引き上げないのと同じ理由です。
件数を信頼する前に知っておくべき、精度に関する注意点が 2 つあります。
- 実際のパーサーを使う言語もあれば、行スキャナーを使う言語もあります。 CSS
(postcss)、Python(
tokenize)、YAML(その CST)、TypeScript/JavaScript(コンパイラーのスキャナー)は、文字列リテラル内のコメント記号と実際のコメントを区別できます。Shell、TOML、SQL、HCL は行スキャナーを使うため区別できません。文字列内の#や--はコメントとして読み取られます。これは、各言語の既存のコメントカウンターが読み取る方法とまったく同じです。HCL は 3 つの構文、つまり#、//、/* */で測定される唯一の言語です。 - Python のコメントを測定するには、到達可能なインタープリターが必要です。他の Python メトリクスと同様です。インタープリターが実行できない場合、誤って数えるのではなく、該当箇所は未測定のままになります。
違反への対処方法については、codometer-triage スキルを利用してください。
出力先
outputs は型付き出力先の配列です。必要な数だけ宣言できますが、型ごとに指定できるエントリーは最大 1 つです。json 出力を 2 つ指定する構成や、markdown 出力を 2 つ指定する構成は、コマンドラインから 2 つ目を指定する方法がないため、重複した型を示して読み込み時に拒否されます。
outputs: [
{ indentation: 2, path: "output/codometer.json", type: "json" },
{
description: "Measured on every push.",
path: "README.md",
type: "markdown",
},
],
JSON エントリーには path が必要です。indentation の既定値は 2 です。Markdown エントリーには path、write 関数、またはその両方が必要です。どちらも指定していない出力先は、構成の読み込み時に拒否されます。
Markdown の書き込み
カスタマイズ可能な動作はすべて write に集約されています。レポートの内容と書き込み先の両方を決定し、以前は別々だった render と write の 2 つのコールバックを置き換えます。
{
path: "README.md",
type: "markdown",
write: ({ anchors, renderBadges, statistics }) =>
anchors.syncAnchoredBlock({
content: `Lines of code: ${statistics.linesOfCode}\n\n${renderBadges()}`,
}),
}
| 引数 | 意味 |
|---|---|
description | 設定された説明です。ライター側で配置したい場合に使用します |
renderBadges() | 同じ統計情報を組み込みの方法でバッジに描画します。既定の内容を作成したり、内容に追加したりする場合に呼び出します |
statistics | 測定された統計情報です |
check | 何も書き込んではならず、ファイルの検査のみを行う場合は True です |
path | 設定されたパスを、プロセスの作業ディレクトリを基準に解決したものです |
anchors | マーカーの仕組みです。syncAnchoredBlock、wrapInAnchors、startMarker/endMarker が含まれるため、別のファイルを選んでも、差し込み処理を再実装する必要はありません |
write を設定しない場合は、組み込みの描画と書き込みが維持されます。write 関数は、出力先が古くなっていることを報告する場合に false を返します。これにより --check reports の実行は失敗します。それ以外の戻り値は、すべて最新であるものとして扱われます。
作成時には入力、レポートではターゲット
inputs は構成で宣言する項目です。この再設計では、作成時に targets を inputs に、defaultTarget を defaultInput に変更しました。一方、測定結果の JSON レポートでは、従来の用語が維持されています。つまり、CodometerReport.targets はそのままで、メトリクスも引き続き codebase.typescript.interfaces や Compiled JavaScript.size のように指定します。入力名が、レポートでターゲットと呼ばれるものに相当します。この使い分けは意図的なものであり、用語の不統一ではありません。CodometerReport.targets はこの再設計より前から存在し、レポートを読み取る下流の処理を変更する必要がなかったため維持されています。また、Measured Targets バッジグループにも、その名前を維持している理由を説明するコードコメントがあります。構成には inputs を記述し、レポート、configuration --limits の一覧、またはバッジグループの見出しでは targets を参照してください。