invokeで実行されるコマンドをプロジェクトルートから実行する方法
invoke(pyinvoke)というプロジェクト管理用のツールを使っていたときに出た疑問の解決方法を説明します。 とはいえ、私自身もまだこの方法で良いのか疑問なので、より良い方法を知っている人はぜひ教えてください。
invoke(pyinvoke)とは
プロジェクトでの開発を進める際に、よくあるコマンド操作をまとめておくことがよくあります。 例えば不要なファイルを削除したり、フォーマッターを適用したり、本番用にビルドしたりなどがあります。 invoke(pyinvoke)を使うとPythonでシェルでのコマンド操作を簡単に書けるようになります。
Welcome to Invoke! — Invoke documentationwww.pyinvoke.org
invokeでプロジェクトルートから実行する
invoke でコマンドを実行(c.run(...))するときは、invoke ... を実行したパスでコマンドが実行されます。
invoke のタスクを定義したファイルは以下のように走査されますが、実行パスは変わりません。
Loading collections — Invoke documentationdocs.pyinvoke.org
ですが、例えばフォーマッターを全体に適応したいときなどはプロジェクトルートからコマンドを実行したくなります。
例えば以下のようなプロジェクト構成のとき、 mymodule 以下で invoke ... としても、 tasks.py を含むディレクトリーから実行したいときです。
+- tasks.py
+- setup.py
+- mymodule
+- foo.py
+- bar.py
そういう場合は、以下のように tasks.py を書くと良いでしょう。
import os from invoke import task HERE = os.path.dirname(__file__) @task def mytask(c): c.run("...")
こうすると、 invoke mytask はプロジェクトルート(tasks.py を含むディレクトリー)で実行されます。
私はプロジェクト全体のフォーマットを整えるタスクに活用しています。
@task def format(c): c.run("black .") c.run("isort -rc .")
このプロジェクトルートから実行する方法については、invokeのドキュメントやIssueを調べても良い回答は見つかりませんでした。 唯一近そうなのがこのIssueでした。
No equivalent of Fabric's env.real_fabfile? · Issue #634 · pyinvoke/invokegithub.com
もしより良い方法を知っている方がいれば教えてください。