CLIから使えるC#のフォーマッターdotnet-formatの紹介

この記事は[PONOS Advent Calendar2021](https://qiita.com/advent-calendar/2021/ponos)の5日目の記事です。

昨日は@FW14Bさんの「VSCodeのインテリセンスが機能しなかったときに確認すること」でした。

---

## 概要

- `dotnet-format`とは
- 何が良いのか
- インストール方法
- 使い方
- 設定
- オプション

## `dotnet-format`とは
C#やF#, VBのコードをフォーマット(整形)してくれるツール(フォーマッター)です。
(私はC#以外で使ったことは無いですが)

設定にもよりますが、こんなコードを

```csharp
// 例: 整形前
using System.Linq;
using System;

namespace FormatSample
{
    class Program
    {
        static void Main(string[] args) { Console.WriteLine("Hello World!");

        foreach(var arg in args){
                Console.WriteLine(arg);
            }
        }
    }
}
```

このように整形してくれます。


```csharp
using System;
using System.Linq;

namespace FormatSample
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");

            foreach (var arg in args)
            {
                Console.WriteLine(arg);
            }
        }
    }
}
```

上記の場合変わったところは
- usingを名前順で並び替え
- インデントの修正
- `foreach`の後ろにスペースを追加
- `{`, `}`の後ろに改行を追加

です。

## 何が良いのか
チーム開発などではコードが決まった形に整形されることで、書いた人間によるコードの書き方の違いが消えるためコードが読みやすくなります。
そのためコードレビューで細かい書き方に注意を払う必要がなくなりロジックなど必要な箇所を見ることだけに集中できます。

またフォーマッターで修正できる範囲であればコーディング規約に従っているかを気にしてコードを書く必要がないので、コードを書く側もコードの内容に集中できます。

個人開発でもフォーマットされたコードのほうが気持ち良いので気分が良くなります。(個人の感想です)

## インストール方法
`dotnet`コマンドがすでに使える状態であれば
`dotnet tool install -g dotnet-format`
でインストール可能です。

プロジェクトのローカルにインストールしたいのであれば
`dotnet tool install --local dotnet-format`
とします。
ただしプロジェクトのローカルにインストールする場合はマニフェストファイルが必要です。ない場合は先に
`dotnet new tool-manifest`
でマニフェストファイルを作成しておきましょう。

## 使い方
`csproj`が1つしか無いディレクトリであれば
`dotnet format`
というコマンドだけでフォーマットしてくれます。

`sln`や`csproj`が複数という構成プロジェクトの場合は
`dotnet format [<PROJECT | SOLUTION>]`
というように引数に`sln`か`csproj`を渡してworkspaceを指定してやる必要があります。
Unityのプロジェクトはまさにそういう構成なので

`dotnet format Assembly-CSharp.csproj`
というようなコマンドを叩く必要があります。

## 設定
`.editorconfig`に`dotnet-format`の設定を書くことでコマンド実行時にその設定を読み込みフォーマットを行ってくれます。
`.editorconfig`ファイルが何かわからない方は`EditorConfig`で調べてみてください。
どのような設定があるかは[dotnet-formatの設定]を確認してください。


`dotnet_sort_system_directives_first = true`
としておくと`using Xxx.Yyy`が名前順にかつ`System.Zzz`が先頭くるようにソートされるのでおすすめです。

[dotnet-formatの設定]の例をほとんどそのままコピーしてくればいい感じにしてくれます。

## オプション
`dotnet format [options] [<PROJECT | SOLUTION>]`
のようにworkspaceの前にオプションを指定することができます。

[dotnet-formatコマンドの説明]に有効なオプションが書いてあります。
よく使いそうなのは

`--include <ファイル or ディレクトリ>`
ファイルかディレクトリを指定してフォーマットの対象にします。スペース区切りで複数指定可能。
単一のファイルだけフォーマットしたいときなどに使えます。

`--exclude <ファイル or ディレクトリ>`
ファイルかディレクトリを指定してフォーマットの対象から除外します。スペース区切りで複数指定可能。
プロジェクト内の自分が書いたものではないコード(Unityのパッケージとか)を除外するのに使えます。

`--check`
フォーマットせずにフォーマットされているかだけを判断できます。
フォーマットされていないプルリクエストを拒否するなどで使えます。


あたりだと思います。

リンク先に`--check`は書いてありませんが`dotnet format --help`で出てきます。

### 注意
`dotnet format --include Bar.cs Foo.csproj`
のように`--include`オプションを使用した場合、最後の引数のworkspaceが`--include`オプションの引数として扱われてしまいます。
(おそらく`--exclude`でも同じことがおきます)

その場合は
`dotnet format --include Bar.cs -v d Foo.csproj`
のように別のオプションを挟むことで解決できます。

## まとめ
- `dotnet-format`はC#/F#/VBのコードをフォーマットしてくれるツール
- 使用することでコードが読みやすくなる
- コードの整形をフォーマッタに任せることでコードを書くことに集中できるようになる
- インストールは`dotnet tool install -g dotnet-format` or `dotnet tool install -g dotnet-format`
- 設定は`.editorconfig`に書く
- オプションは`dotnet format [options] [<PROJECT | SOLUTION>]`の形式で指定する


## 記事中のリンク
[dotnet-format][]
[dotnet-formatの設定][]
[dotnet-formatコマンドの説明][]

[dotnet-format]:https://github.com/dotnet/format
[dotnet-formatの設定]:https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/code-style-rule-options?view=vs-2019
[dotnet-formatコマンドの説明]:https://docs.microsoft.com/ja-jp/dotnet/core/tools/dotnet-format

---
明日は私(@block)です。