5分でできるRuffによる高速Pythonコードリント 

---

## 目次
1. [はじめに](#はじめに)
2. [Ruffとは](#ruffとは)
3. [インストール方法](#インストール方法)
4. [基本的な使い方](#基本的な使い方)
    - [Ruffの基本コマンド](#ruffの基本コマンド)
    - [設定ファイルの作成](#設定ファイルの作成)
5. [Ruffの実行例](#ruffの実行例)
6. [まとめ](#まとめ)
7. [参考にしたもの](#参考にしたもの)
8. [ソースコード](#ソースコード)
9. [補足説明](#補足説明)

---

## はじめに

Ruffを導入する目的は『綺麗なソースコードを書くこと』です。  
綺麗なソースコードを書くためには、FormatterやLinterの導入が有効です。これらのツールにはさまざまな選択肢がありますが、すべてを別々にインストールして設定するのは手間です。特にチーム開発では、統一された環境を構築することが難しいこともあります。

そんな煩雑な環境構築をシンプルにまとめて解決できるのが**Ruff**です。

---

## Ruffとは  

**Ruff**は、Pythonのコード品質を維持するために使用される高速なコードリントツールです。Flake8やPylintと同様に、コード内のスタイルや構文エラーを検出し、修正案を提案します。Ruffの最大の特徴は、その処理速度で、特に大規模プロジェクトでのリントにおいて強力です。以下の利点があります：

- **高速なリント**：従来のツールよりも圧倒的に速い。
- **統一的な設定管理**：1つのツールでスタイルと品質を一貫して管理可能。
- **簡単なセットアップ**：インストールしてすぐに利用可能。

---

## インストール方法  

Ruffは`pip`を使用してインストールできます。以下のコマンドを実行してください：

```bash
pip install ruff
```

バージョンは下記を使用しています。
```bash
$ ruff --version
ruff 0.6.4
```

インストール後、プロジェクトディレクトリで`ruff check`コマンドを実行すれば、コードに対するスタイルチェックが行われます：

```bash
ruff check .
```

上記のコマンドで、プロジェクト全体のPythonコードに対してリントが行われます。

---

## 基本的な使い方  

### Ruffの基本コマンド  

Ruffを実行する際の基本的なコマンドは以下の通りです：

```bash
ruff check .  # 現在のディレクトリ全体をチェック
ruff check path/to/file.py  # 特定のファイルをチェック
```

これらのコマンドを実行すると、コード内のエラーや警告が一覧表示され、どこを修正すべきか簡単に確認できます。

### 設定ファイルの作成  

Ruffの設定は、プロジェクトディレクトリに`pyproject.toml`を作成することで管理できます。以下は[デフォルトの設定](https://docs.astral.sh/ruff/configuration/)です：

```pyproject.toml
[tool.ruff]
# 一般的に無視されるディレクトリを除外します。
exclude = [
    ".bzr",               # Bazaarリポジトリ
    ".direnv",            # direnvの環境ディレクトリ
    ".eggs",              # Pythonパッケージのビルドディレクトリ
    ".git",               # Gitリポジトリ
    ".git-rewrite",       # Gitの書き換え履歴
    ".hg",                # Mercurialリポジトリ
    ".ipynb_checkpoints", # Jupyter notebookのチェックポイント
    ".mypy_cache",        # mypyのキャッシュディレクトリ
    ".nox",               # noxの環境ディレクトリ
    ".pants.d",           # Pantsビルドシステムのディレクトリ
    ".pyenv",             # pyenvの環境ディレクトリ
    ".pytest_cache",      # pytestのキャッシュディレクトリ
    ".pytype",            # Pytypeのタイプキャッシュ
    ".ruff_cache",        # Ruffのキャッシュディレクトリ
    ".svn",               # Subversionリポジトリ
    ".tox",               # toxの仮想環境ディレクトリ
    ".venv",              # Python仮想環境ディレクトリ
    ".vscode",            # VSCodeの設定ディレクトリ
    "__pypackages__",     # PEP582準拠のパッケージディレクトリ
    "_build",             # ビルド成果物ディレクトリ
    "buck-out",           # Buckビルドシステムの成果物ディレクトリ
    "build",              # ビルドディレクトリ
    "dist",               # 配布物ディレクトリ
    "node_modules",       # Node.jsの依存パッケージ
    "site-packages",      # Pythonの依存パッケージ
    "venv",               # 仮想環境ディレクトリの別名
]

# Blackと同じ設定で、1行の長さを88文字に設定
line-length = 88
# インデントの幅を4スペースに設定
indent-width = 4

# Python 3.8をターゲットバージョンとして設定
target-version = "py38"

[tool.ruff.lint]
# Pyflakes（`F`）とpycodestyle（`E`）の一部（E4, E7, E9）を有効化
# Ruffでは、pycodestyleの警告（`W`）やMcCabeの複雑度（`C901`）はデフォルトで無効
select = ["E4", "E7", "E9", "F"]
ignore = []

# `--fix`が指定された場合、すべてのルールに対して自動修正を許可
fixable = ["ALL"]
# 自動修正ができないルールは設定しない
unfixable = []

# アンダースコアで始まる変数は未使用変数として扱わない設定
dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"

[tool.ruff.format]
# Blackと同様に、文字列はダブルクォートで囲む
quote-style = "double"

# Blackと同様に、インデントはスペースを使用
indent-style = "space"

# Blackと同様に、トレーリングカンマ（最後のカンマ）は尊重する
skip-magic-trailing-comma = false

# Blackと同様に、適切な改行を自動的に検出
line-ending = "auto"

# ドキュメントストリング内のコード例を自動フォーマットする設定
# 現在はデフォルトで無効ですが、将来的にはデフォルトで有効になる予定
docstring-code-format = false

# ドキュメントストリング内のコードスニペットに適用される行長制限
# `docstring-code-format`が有効な場合にのみ適用されます
docstring-code-line-length = "dynamic"
```


---

## Ruffの実行例  

### Ex1. Linterによる不要なインポートの検出
```src/sample1.py
import os
import sys


def greet(name):
    print(f"Hello, {name}")
```
このコードでは、`os`と`sys`がインポートされていますが、使用されていません。Linterはこれを検出し、次のような警告を出します：

```bash
$ ruff check src/sample1.py 
src\sample1.py:2:8: F401 [*] `os` imported but unused
  |
1 | # sample1.py
2 | import os
  |        ^^ F401
3 | import sys
  |
  = help: Remove unused import: `os`

src\sample1.py:3:8: F401 [*] `sys` imported but unused
  |
1 | # sample1.py
2 | import os
3 | import sys
  |        ^^^ F401
  |
  = help: Remove unused import: `sys`

Found 2 errors.
[*] 2 fixable with the `--fix` option.
```

下記のコマンドにより、修正できます。
```bash
$ ruff check src/sample1.py --fix
Found 2 errors (2 fixed, 0 remaining).
```

```src/sample1.py
def greet(name):
    print(f"Hello, {name}")
```

```bash
$ ruff check src/sample1.py 
All checks passed!
```


### Ex2. Formatterによる不要なスペースの削除
```src/sample2.py
def greet ( name ):
    print( f"Hello, { name }" )
```
Formatterを使用すると、このコードは次のように自動的に整形されます：

```bash
$ ruff format src/sample2.py
1 file reformatted
```

```src/sample2.py
# sample2.py (After Formatting)
def greet(name):
    print(f"Hello, {name}")
```



---

## まとめ  

Ruffは、軽量かつ高速なPythonのリントツールであり、特に大規模なプロジェクトで効率的にコードスタイルを管理できます。本記事では、Ruffのインストール方法や基本的な使い方、設定ファイルのカスタマイズ方法について紹介しました。Ruffを使うことで、プロジェクトの品質向上に貢献できると思います。

---

## 参考にしたもの  
- [1] [Ruff公式ドキュメント](https://beta.ruff.rs/docs/)
- [2] [Ruff vs Flake8: A performance comparison](https://dev.to/)
- [3] [Pythonコード品質向上のためのRuff入門](https://zenn.dev/)

---

## ソースコード  
この記事で使用したソースコードは[こちら](https://github.com/Isaka-code/ruff-in-5-minutes)から入手できます。

---

## 補足説明  

<details><summary>補足説明：リントとは</summary><div>

### Linterとは  
Linterとは、ソースコード内のスタイル違反やバグの可能性がある箇所を検出する自動チェックのことです。コードをリント(lint)することで、潜在的なバグを早期に発見し、コード品質を維持することができます。Linterツールを使用することで、効率的にコード品質を向上させることができ、特に大規模なプロジェクトでは重要な役割を果たします。 

#### 利点
- **バグの早期発見**: 実行前にコードのエラーを発見できます。
- **コーディングスタイルの統一**: 一貫したコーディングスタイルが保たれ、チーム開発が円滑になります。

#### Formatterとの違い
- **Linter**は、不要なインポートやスタイルガイド違反を指摘します。
- **Formatter**は、コードのインデントやスペースを自動で整形し、クリーンなコードに修正します。

</div></details>  

<details><summary>補足説明：pyproject.tomlとは</summary><div>

`pyproject.toml`は、Pythonプロジェクトの設定を一元管理する標準ファイルです。RuffやBlack、mypyなど多くのツールが対応しており、設定の簡素化を実現できます。

#### Ruffの設定を行うpyproject.tomlの例
```toml
[tool.ruff]
line-length = 88
exclude = [".git", ".venv"]
target-version = "py38"
```

</div>
</details>