pre-commitとvenvとPyCharm(困ったな?)

Posted by johtani on Monday, July 10, 2023

目次

最近、趣味(検索エンジンに関する趣味プロジェクト)で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というツールとgitpre-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-commitblackなどのコマンドが見つかりました。 pre-commitツールが設定ファイルを基に、必要なコマンドをgithubからダウンロードしてきて実行時に利用しているようです。 pre-commitは便利なのだけど、せっかくPythonのプロジェクトだしそれぞれのツールはpoetryでpyproject.tomlでバージョンや設定を管理したほうがすっきりするのではないか?ということで、少し調べてみました。

同じようなことを考えている方がブログを残していてくれました(Pythonレポジトリ用のpre-commit環境を整える)。 設定をpyproject.tomlに移行し、そのあと、ローカルのpetryでblackなどのコマンド類をインストールして利用する設定に書き換えています。 先人の肩に乗っかって、手元で同じようにpre-commitの設定ファイルのrepolocalに書き換えていき(その時のコミット)、ターミナルで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を実行していない状態だとコマンドが見つからないというエラーが出ました。

対処方法は?

ということで、今考えられる対処方法としては次の通りです。

  1. .git/hooks/pre-commitのスクリプトを修正して、<プロジェクトのディレクトリ>/.venv/binのパスを見えるようにする
  2. PyCharmで何かしらの設定を探す
  3. PyCharmではgit操作しない
  4. repo:localはあきらめて、.pre-commit-config.yamlblackなどは管理して、pyproject.tomlからは除外する

1.ですが、.git/hooks/pre-commitprecommit intallを実行すると自動で生成されるスクリプトです。自分の環境で書き換えたとしても他の人が同じ環境を作るときにパッチを当てるなどをしないといけなくなります。

2.はそれらしい設定を見つけることができませんでした。

3.はめんどくさいですよね。。。ターミナルでgitのコメントを日本語で書くためにいくつか他の設定を考えないといけないです。。。

ということで、今回は4.の対処をとりました。やりたいことは、ツールや環境をそろえるのではなく、プロジェクトでやりたいことをやることなので。。。

まとめ

最終的には元に戻ってしまいました(pyproject.tomlに設定周りは移動した)。 Windows環境がちょっとややこしくしてるかもな?というのと、個人のプロジェクトなのでそこまで気にしなくてもいいのでは?というのもありそうです。 それにしても、世の中の皆さんはフォーマッターとかどのタイミングで動かしてるんだろう?とかどういう環境構築してるんだろう?とか気になってます。 最近だとこういうディレクトリ構造にする、こういうツールを使うと便利などあれば、コメントいただけると嬉しいです。

教えてもらったISIDのブログ(Dev Containerを使ってステップバイステップで作るPythonアプリケーション開発環境 - ISID テックブログ)も参考にさせてもらおうと思ってるところです。Pythonの環境をコンテナに移動したいなぁというのもあるので。ただ、PyCharmだからこのブログの通りには行かないけど(VS Codeに移るのも検討したほうがいいのかなぁ)。

参考サイト


comments powered by Disqus

See Also by Hugo


Related by prelims-cli