目次
最近、趣味(検索エンジンに関する趣味プロジェクト)でPythonのプログラムを書き始めました。
きちんとPythonのプログラムをプロジェクトとして書いたことがないので、
Pythonのプロジェクトのディレクトリ構成などを手探りで進めているところです。
コードのフォーマットとかもやらないとなぁ?と知り合いのいるSlackでつぶやいたところ、gitのpre-commitフェーズでblack
などのフォーマットやスタイルを修正してくれるツールを実行する方法を教えてもらいました(PRまで送ってもらえたのでありがたい)。
で、pre-commit周りの設定などを変えている段階で遭遇した問題点についてログを残しておこうと重いブログを書いています。 残念ながら現時点では解決してないんですけどね。。。
手元の環境
簡単に環境を書いておくとこんな感じです。
- Windows上のPyCharmを開発で使用
- プロジェクトのディレクトリはWSL2のUbuntu上
- Python、gitはUbuntuのものを利用
- プロジェクトのルートディレクトリにある
.venv
にvenvでPythonの仮想環境を作成してある
問題点
遭遇したpre-commit
の問題点は次の通りです。
- pre-commitの設定で
repo:local
でローカルのプロジェクトにインストールしたコマンドを利用するように変更 - すると、PyCharmでコミットすると、
black
などのコマンドが見つからない - ターミナルでコミットするときはきちんと動作する
色々調べて試行錯誤した結果、現在はrepo:local
でのローカルコマンドを使用する方法はあきらめました。
移行は、作業記録みたいなものです。どういう流れでpre-commitを取り込み、ローカルに切り替え、切り戻したかという話です。
pre-commitとpre-commit
最初に少し戸惑ったのは、pre-commit
というツールとgit
のpre-commitフック
です。
gitのpre-commitのフックのために作られたPython製のpre-commit
というツールがあります。
このPython製のツールを利用することで、プロジェクトに.pre-commit-config.yaml
という設定ファイルを置けば設定に記述されたツールをgit commitのタイミングで実行してくれます。
実際には、pre-commit
というツールの初期設定のタイミングでpre-commit install
というコマンドを実行して
.git/hooks/pre-commit
というスクリプトが生成されます。
gitコマンドはcommitされた時に(commit前のフェーズ)でこのスクリプトを実行し、そこで.pre-commit-config.yaml
が参照されています。
.pre-commit-config.yaml
の記述は次のようなものになります(最初にもらったPRより)。
repos:
- repo: https://github.com/psf/black
rev: 23.3.0
hooks:
- id: black
args: ["--line-length", "120", "."]
- repo: https://github.com/pycqa/flake8
rev: 6.0.0
hooks:
- id: flake8
- repo: https://github.com/pycqa/isort
rev: 5.12.0
hooks:
- id: isort
args: ["--profile", "black", "--filter-files", "--multi-line", "3"]
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.4.1
hooks:
- id: mypy
実際に、PRを取り込んで動かしてみたところ、black
などが動いて行末のスーペースの除去や未使用のimportについて指摘をしてくれました。
便利だなと思ったのですが、ここで疑問が。
今回は対象とするプロジェクトはpoetry
で依存パッケージの管理を行っています。
今回、上記を動かすためにpoetry
に追加されたものはpre-commit
だけでした。
「あれ?black
とかはどこにあって、どうやって動いてるんだ?」という疑問が出てきます。
コンフィグファイルにはパスなどの記載をせず、それぞれのgithubリポジトリの記載とバージョンがあるからです。
pre-commitが使用するツールのインストール先
調べてみたところ、どうやらホームディレクトリにある.cache/pre-commit
にblack
などのコマンドが見つかりました。
pre-commit
ツールが設定ファイルを基に、必要なコマンドをgithubからダウンロードしてきて実行時に利用しているようです。
pre-commitは便利なのだけど、せっかくPythonのプロジェクトだしそれぞれのツールはpoetryでpyproject.tomlでバージョンや設定を管理したほうがすっきりするのではないか?ということで、少し調べてみました。
同じようなことを考えている方がブログを残していてくれました(Pythonレポジトリ用のpre-commit環境を整える)。
設定をpyproject.tomlに移行し、そのあと、ローカルのpetryでblack
などのコマンド類をインストールして利用する設定に書き換えています。
先人の肩に乗っかって、手元で同じようにpre-commit
の設定ファイルのrepo
をlocal
に書き換えていき(その時のコミット)、ターミナルでpoetry run pre-commit run -a
で動作確認できました。
PyCharmでコミットしたらエラー
ですが、実際に変更した状態でPyCharmからコミットしたら、コマンドが見つかりませんというエラーが出ます。。。
WSL2のターミナルでgit commit
した場合は問題ありません。
どうして?となりますよね。。。。
.git/hooks/pre-commit
はPyCharm、ターミナルのどちらからも実行されています。
ですが、PyCharmではblackなどが見つからないというエラーが出ました。
.git/hooks/pre-commit
を見てみると、python実行するためのpythonのパスはプロジェクトにある.venv/bin/python
を指定しています。
デバッグのために、このスクリプトにecho $PATH
を差し込んで、git commitをPyCharmとターミナルからそれぞれ実行してみたところ、大きな違いがあります。
ターミナルで実行した場合は、<プロジェクトのディレクトリ>/.venv/bin
もPATH環境変数に存在していました。このため、.venv/bin
にあるblack
などを実行できています。
PyCharmはWindowsから起動しています。プロジェクトのインタプリタとしては、WSL2のUbuntuにある.venv/bin/python
を指定しているためもあり(?)、出力されたパスは/mnt/c/
などのWindowsのパスなども入っていたりしますが、<プロジェクトのディレクトリ>/.venv/bin
は見つかりません。
ここからはソースコードは読んでいないので憶測ですが、.git/hooks/pre-commit
で呼び出されているpre-commit
ツール(Python製)は、設定ファイルで指定されたコマンド(black
など)を、コマンドとして今の呼び出されたコンテキストで実行しているのではないかということです。
実際、ターミナル上でもsource .venv/bin/activate
を実行していない状態だとコマンドが見つからないというエラーが出ました。
対処方法は?
ということで、今考えられる対処方法としては次の通りです。
.git/hooks/pre-commit
のスクリプトを修正して、<プロジェクトのディレクトリ>/.venv/bin
のパスを見えるようにする- PyCharmで何かしらの設定を探す
- PyCharmではgit操作しない
repo:local
はあきらめて、.pre-commit-config.yaml
でblack
などは管理して、pyproject.toml
からは除外する
1.ですが、.git/hooks/pre-commit
はprecommit intall
を実行すると自動で生成されるスクリプトです。自分の環境で書き換えたとしても他の人が同じ環境を作るときにパッチを当てるなどをしないといけなくなります。
2.はそれらしい設定を見つけることができませんでした。
3.はめんどくさいですよね。。。ターミナルでgitのコメントを日本語で書くためにいくつか他の設定を考えないといけないです。。。
ということで、今回は4.の対処をとりました。やりたいことは、ツールや環境をそろえるのではなく、プロジェクトでやりたいことをやることなので。。。
まとめ
最終的には元に戻ってしまいました(pyproject.toml
に設定周りは移動した)。
Windows環境がちょっとややこしくしてるかもな?というのと、個人のプロジェクトなのでそこまで気にしなくてもいいのでは?というのもありそうです。
それにしても、世の中の皆さんはフォーマッターとかどのタイミングで動かしてるんだろう?とかどういう環境構築してるんだろう?とか気になってます。
最近だとこういうディレクトリ構造にする、こういうツールを使うと便利などあれば、コメントいただけると嬉しいです。
教えてもらったISIDのブログ(Dev Containerを使ってステップバイステップで作るPythonアプリケーション開発環境 - ISID テックブログ)も参考にさせてもらおうと思ってるところです。Pythonの環境をコンテナに移動したいなぁというのもあるので。ただ、PyCharmだからこのブログの通りには行かないけど(VS Codeに移るのも検討したほうがいいのかなぁ)。
参考サイト
- Git - Git フック
- pre-commit
- Pythonレポジトリ用のpre-commit環境を整える
- Dev Containerを使ってステップバイステップで作るPythonアプリケーション開発環境 - ISID テックブログ
comments powered by Disqus
See Also by Hugo
- VS CodeとDev Containerの導入(まだ途中)
- Apache LuceneのKuromojiのUniDicビルド対応パッチについて
- search-UIとSearchkitと検索画面
- ブログ記述環境としてのDev Container
- VS CodeとDev Container(docker-compose.yml対応)