【Python】autopep8とflake8を使ってCommit時にコードフォーマットとスタイルチェックを自動化する

株式会社ココロファン - エンジニアリング事業部所属のSassyです。

普段は業務委託で仕事をしながら、自社プロダクトの企画/開発をしています。


## 導入の経緯

現在、自社プロダクトとしてサービス提供していくためにHiramekiというプロダクト管理ツールを開発しています。

https://hirameki.cocolofun.com/

まだプロダクト管理機能の開発が完了していないのでサービス提供までは至っておりませんが、現在はアイデア思考ツールであるバグリストを提供しおります。

https://hirameki.cocolofun.com/buglist/

Web上で無料で使えてアイデア整理のみだけでなくTODO整理にも応用できます。
良ければ以下のブログでバグリストの活用法について記載しておりますので読んでいただければ幸いです。

https://cocolofun.co.jp/buglist-the-way-to-use/

とまぁ、宣伝地味してしまって脱線してしまいそうなので元に戻します。

このアプリはDjangoで開発をしており、最近だんだんコード量が多くなってきて色々いじっていると余計なところで差分が出たり未使用のインポートが多くなってきてしまい、人力で確認するのが手間になってきてしまったのでコードフォーマットとスタイルチェックを自動化する仕組みを入れようと考えました。

現在、設計とコーディングは1人でやっているのですが、今後人を増やしたときにコードスタイルを統一できたほうが良いので今のうちから入れておくべきだと考えてます。


## 環境と必要なソフトウェア

* Windows10
* pre-commit (2.13.0)
* autopep8 (1.5.7)
* flake8 (3.9.2)
* pycodestyle (2.7.0)

※バージョンに関しては2021/7/6現時点での最新版をインストールしています。

## pre-commitとは

https://pre-commit.com/

Gitフックスクリプトを作成してくれて、コミット毎にフックを実行してくれるツールです。
今回の自動化ではこのフックをセットアップしてPythonのコードフォーマッタである**autopep8**とスタイルチェッカーであるflake8を実行して細かい部分のミスを自動でチェックしてくれる仕組みを作ります。

## autopep8とは

https://pypi.org/project/autopep8/

自動でPEP8スタイルガイドに準拠するようにするフォーマッタツールです。
pycodestyleに依存しており、pycodestyleを使って度のコードをフォーマットするのかを判断してくれます。

pythonのコードフォーマッタの中でも特にPEP8に準拠しているのがautopep8であると思います。

蛇足ですがautopep8がPEP8にしっかり準拠しているかはautopep8に加えてそれ以外でのフォーマッタライブラリでフォーマットをかけた後にflake8でチェックしてもらうとよりautopep8がPEP8に準拠しているかがわかります。

また以下DjangoでのPythonコードスタイルは特に指定が無い限りPEP8に準拠すべきだそうです。

> Unless otherwise specified, follow PEP 8.
> 
> 出典：https://docs.djangoproject.com/ja/3.1/internals/contributing/writing-code/coding-style/

このことからHiramekiではautopep8を採用していこうと思います。



## flake8とは

https://pypi.org/project/flake8/

Pythonのコードチェックツールです。
以下のツールのラッパーであるそうです。

> PyFlakes
> pycodestyle
> Ned Batchelder’s McCabe script
>
> 出典：https://pypi.org/project/flake8/

flake8はPEP8に準拠しているかをチェックしてくれるのでautopep8ととの相性はいいかと思います。

## 手順

では早速上記ツールを使っての手順を紹介していきます。

### pre-commitをインストールする

まずは下記のコマンドで`pre-commit`をインストールしてください。

```shell
$ pip install pre-commit
```

### 設定ファイルを作成する

設定ファイルはyaml形式で書いていきます。

まずはプロジェクトのルートで`.pre-commit-config.yaml`というファイルを作成してください。

そしたら中に以下のように書いていきます。
※**ちなみにhooksのargsの部分はご自身のプロジェクトに合わせて記載お願いします。**

```yaml
repos:
- repo: https://github.com/pre-commit/mirrors-autopep8
  rev: v1.5.7
  hooks:
  - id: autopep8
    args: [--in-place, -r, --aggressive, --exclude, "manage.py,./*/migrations,./*/snapshots,./*,./**/__init__.py,hirameki/asgi.py", --max-line-length, "120"] 
- repo: https://gitlab.com/pycqa/flake8
  rev: 3.9.2
  hooks:
  - id: flake8
    args: [--statistics, --exclude, "manage.py,./*/migrations,./*/snapshots,./**/__init__.py,hirameki/asgi.py", --max-line-length, "120", --per-file-ignores, "./hirameki/settings/local.py,./hirameki/settings/prod.py:F403,F401"]
```

Hiramekiでの設定はこんな感じです。

自動生成されるディレクトリと何も記載されていないファイル、それ以外ですと順序が関係するコードを書いているファイルは-`--exclude`してます。

また「prod.py」と「local.py」は「base.py」を読み込んでいるので「from .base import *」の行で発生するエラーを抑えるため`--per-file-ignores`を使って除外しています。

### git-hookのセットアップをする

下記のコマンドを実行して、gitフックスクリプトを設定します。

```shell
$ pre-commit install
```

これで完了です。

## 動作確認

では実際にファイルに変更を行って、コミットしてみましょう。

```shell
$ git commit -m "test commit."
```

以下のような出力が確認できればautopep8とflake8がコミット直前に実行されていて、問題があった場合はエラーを表示してコミットできないように防いでくれます。

```shell
$ git commit -m "test commit."
autopep8.................................................................Passed
flake8...................................................................Passed
```

エラーが表示された場合は確認して修正を行い、再度コミットして問題なくコミットできれば完了です！

## 最後に

結構簡単に導入できました。
これで自動でフォーマットしてスタイルチェックも行ってくれるので、コーディング作業が捗ります！

株式会社ココロファンでは自社プロダクトの開発も行なっており、やってよかったこと、やってわかったこと、便利なノウハウを皆さんに共有できるように、これからも積極的に技術記事をアップしていきたいと思います。

https://cocolofun.co.jp

## 関連情報

今回記事中にGitフックという言葉が出てきて、Gitフックについての説明が無かったのですが、以下にGitフックについての情報を掲載しておきます。

https://git-scm.com/book/ja/v2/Git-%E3%81%AE%E3%82%AB%E3%82%B9%E3%82%BF%E3%83%9E%E3%82%A4%E3%82%BA-Git-%E3%83%95%E3%83%83%E3%82%AF

https://qiita.com/noraworld/items/c562de68a627ae792c6c