PDM スクリプト#
PDM を使用すると、npm run
のように、ローカルパッケージが読み込まれた状態で任意のスクリプトやコマンドを実行できます。
任意のスクリプト#
1 |
|
これにより、プロジェクト環境内のパッケージを認識した環境で flask run -p 54321
が実行されます。
単一ファイルスクリプト#
Added in version 2.16.0
PDM は、インラインスクリプトメタデータ を使用して単一ファイルスクリプトを実行できます。
以下は、埋め込みメタデータを含むスクリプトの例です:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
これを pdm run test_script.py
で実行すると、指定された依存関係がインストールされた一時環境が作成され、スクリプトが実行されます:
1 2 3 4 5 6 7 8 9 10 11 12 |
|
--reuse-env
オプションを追加します。
また、スクリプトメタデータに [tool.pdm]
セクションを追加して PDM を構成することもできます。例えば:
1 2 3 4 5 6 7 8 9 10 11 12 |
|
詳細については、仕様 を参照してください。
ユーザースクリプト#
PDM は、pyproject.toml
のオプションの [tool.pdm.scripts]
セクションでカスタムスクリプトショートカットもサポートしています。
[project.scripts]
と混同しないでください
pyproject.toml
には別のフィールド [project.scripts]
があり、スクリプトは pdm run
で実行できます。これは、パッケージと一緒にインストールされるコンソールスクリプトエントリポイントを定義するために使用されます。したがって、プロジェクト自体が環境にインストールされた後にのみ実行可能です。つまり、distribution = true
である必要があります。
対照的に、[tool.pdm.scripts]
はプロジェクトで実行するタスクを定義します。これは、distribution
が true
か false
かに関係なくプロジェクトに対して機能します。タスクは主に開発およびテスト目的のためのものであり、後で示すように、より多くのタイプと設定をサポートします。Makefile
の代替として考えることができます。プロジェクトをインストールする必要はありませんが、pyproject.toml
ファイルが存在する必要があります。
[project.scripts]
についての詳細な説明はこちら を参照してください。
次に、pdm run <script_name>
を実行して、PDM プロジェクトのコンテキストでスクリプトを呼び出すことができます。例えば:
1 2 |
|
そして、ターミナルで:
1 2 |
|
後続の引数はコマンドに追加されます:
1 2 |
|
Yarn のようなスクリプトショートカット
スクリプトが組み込みまたはプラグイン提供のコマンドと競合しない限り、すべてのスクリプトをルートコマンドとして利用できる組み込みショートカットがあります。
つまり、start
スクリプトがある場合、pdm run start
と pdm start
の両方を実行できます。
ただし、install
スクリプトがある場合、pdm run install
のみがそれを実行し、pdm install
は組み込みの install
コマンドを実行します。
PDM は 4 種類のスクリプトをサポートしています:
cmd
#
プレーンテキストスクリプトは通常のコマンドとして扱われますが、明示的に指定することもできます:
1 2 |
|
場合によっては、パラメータ間にコメントを追加したい場合など、コマンドを配列として指定する方が便利です:
1 2 3 4 5 6 7 |
|
shell
#
シェルスクリプトを使用して、パイプラインや出力リダイレクトなどのシェル固有のタスクを実行できます。
これは基本的に subprocess.Popen()
を shell=True
で実行します:
1 2 |
|
call
#
スクリプトは <module_name>:<func_name>
の形式で Python 関数を呼び出すように定義することもできます:
1 2 |
|
関数にリテラル引数を渡すこともできます:
1 2 |
|
composite
#
このスクリプトは他の定義されたスクリプトを実行できます:
1 2 3 4 |
|
pdm run all
を実行すると、最初に lint
が実行され、次に lint
が成功した場合に test
が実行されます。
Added in version 2.13.0
デフォルトの動作を上書きして、失敗後に残りのスクリプトの実行を続行するには、keep_going
オプションを true
に設定します:
1 2 3 4 5 |
|
keep_going
が true
に設定されている場合、複合スクリプトの戻りコードはすべて成功した場合は '0'、または最後に失敗した個々のスクリプトのコードになります。
呼び出されたスクリプトに引数を提供することもできます:
1 2 3 4 |
|
Note
コマンドラインで渡された引数は、呼び出された各タスクに渡されます。
複数のコマンドを組み合わせるために composite
スクリプトを使用することもできます:
1 2 3 4 5 |
|
スクリプトオプション#
env
#
現在のシェルで設定されたすべての環境変数は pdm run
によって参照され、実行時に展開されます。
さらに、pyproject.toml
にいくつかの固定環境変数を定義することもできます:
1 2 3 |
|
複合辞書を定義するために TOML の構文 を使用する方法に注意してください。
環境変数の置換について
スクリプト仕様の変数はすべてのスクリプトタイプで置換できます。cmd
スクリプトでは、すべてのプラットフォームで ${VAR}
構文のみがサポートされますが、shell
スクリプトでは構文はプラットフォーム依存です。たとえば、Windows の cmd は %VAR%
を使用し、bash は $VAR
を使用します。
Note
複合タスクレベルで指定された環境変数は、呼び出されたタスクによって定義されたものを上書きします。
env_file
#
すべての環境変数を dotenv ファイルに保存し、PDM に読み取らせることもできます:
1 2 3 |
|
dotenv ファイル内の変数は既存の環境変数を上書きしません。 既存の環境変数を上書きするために dotenv ファイルを使用する場合は、次のようにします:
1 2 3 |
|
環境変数の読み込み順序
異なるソースから読み込まれる環境変数は次の順序で読み込まれ、最終的なソースリストが構築されます:
- OS 環境変数
- プロジェクト環境変数(
PDM_PROJECT_ROOT
、PATH
、VIRTUAL_ENV
など) env_file
で指定された dotenv ファイルenv
で指定された環境変数マッピング
後のソースからの環境変数は、前のソースからのものを上書きします。 複合タスクレベルで指定された dotenv ファイルは、呼び出されたタスクによって定義されたものを上書きします。
環境変数は、前のソースから読み込まれた別の環境変数を参照することができます。たとえば:
1 2 |
|
FOO=hello-42
になります。参照には ${VAR:-default}
構文を使用してデフォルト値を含めることもできます。
working_dir
#
Added in version 2.13.0
スクリプトの現在の作業ディレクトリを設定できます:
1 2 3 |
|
相対パスはプロジェクトルートに対して解決されます。
site_packages
#
実行環境が外部の Python インタープリターから適切に分離されていることを確認するために、
選択されたインタープリターの site-packages は sys.path
に読み込まれません。ただし、次のいずれかの条件が満たされる場合を除きます:
- 実行可能ファイルが
PATH
から取得され、__pypackages__
フォルダー内にない場合。 -s/--site-packages
フラグがpdm run
に続く場合。- スクリプトテーブルまたはグローバル設定キー
_
にsite_packages = true
がある場合。
PEP 582 が有効になっている場合(pdm run
プレフィックスなしで実行される場合)、site-packages は常に読み込まれます。
共有オプション#
pdm run
で実行されるすべてのタスクにオプションを共有したい場合は、
[tool.pdm.scripts]
テーブルの特別なキー _
の下に書くことができます:
1 2 3 4 |
|
さらに、タスク内では、PDM_PROJECT_ROOT
環境変数がプロジェクトルートに設定されます。
引数プレースホルダー#
デフォルトでは、すべてのユーザー提供の追加引数はコマンドに単純に追加されます(または composite
タスクの場合はすべてのコマンドに追加されます)。
ユーザー提供の追加引数をより詳細に制御したい場合は、{args}
プレースホルダーを使用できます。
これはすべてのスクリプトタイプで利用可能であり、それぞれに適切に補間されます:
1 2 3 4 |
|
次の補間が生成されます(これらは実際のスクリプトではなく、補間を説明するためのものです):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
ユーザー引数が提供されていない場合に使用されるデフォルト値をオプションで提供できます:
1 2 |
|
次のようになります:
1 2 3 4 |
|
Note
プレースホルダーが検出されると、引数は追加されなくなります。
これは composite
スクリプトにとって重要です。なぜなら、サブタスクの 1 つでプレースホルダーが検出されると、引数はサブタスクに追加されなくなるためです。
引数が必要なすべてのネストされたコマンドにプレースホルダーを明示的に渡す必要があります。
Note
call
スクリプトは {args}
プレースホルダーをサポートしていません。これらは sys.argv
に直接アクセスして複雑なケースを処理できます。
{pdm}
プレースホルダー#
複数の PDM インストールがある場合や、pdm
が異なる名前でインストールされている場合があります。
これは、たとえば CI/CD の状況や、異なるリポジトリで異なる PDM バージョンを使用する場合に発生する可能性があります。
スクリプトをより堅牢にするために、スクリプトを実行している PDM エントリポイントを使用するために {pdm}
を使用できます。
これは {sys.executable} -m pdm
に展開されます。
1 2 |
|
次の出力が生成されます:
1 2 3 4 5 |
|
Note
上記の例では PDM 2.8 を使用していますが、この機能は 2.10 シリーズで導入され、ショーケースのためにのみバックポートされました。
スクリプトのリストを表示する#
利用可能なスクリプトショートカットのリストを表示するには、pdm run --list/-l
を使用します:
1 2 3 4 5 6 7 8 |
|
スクリプトの説明を含む help
オプションを追加すると、上記の出力の Description
列に表示されます。
Note
名前がアンダースコア(_
)で始まるタスクは内部(ヘルパーなど)と見なされ、リストには表示されません。
プレ & ポストスクリプト#
npm
のように、PDM もプレおよびポストスクリプトによるタスクの構成をサポートしており、プレスクリプトは指定されたタスクの前に実行され、ポストスクリプトは後に実行されます。
1 2 3 4 |
|
この例では、pdm run compress
はこれらの 3 つのスクリプトを順番に実行します。
パイプラインは早期に失敗します
プレ - 自身 - ポストスクリプトのパイプラインでは、失敗が発生すると後続の実行がキャンセルされます。
フックスクリプト#
特定の状況下で PDM はいくつかの特別なフックスクリプトを実行します:
post_init
:pdm init
の後に実行pre_install
: パッケージのインストール前に実行post_install
: パッケージのインストール後に実行pre_lock
: 依存関係の解決前に実行post_lock
: 依存関係の解決後に実行pre_build
: ディストリビューションのビルド前に実行post_build
: ディストリビューションのビルド後に実行pre_publish
: ディストリビューションの公開前に実行post_publish
: ディストリビューションの公開後に実行pre_script
: 任意のスクリプトの前に実行post_script
: 任意のスクリプトの後に実行pre_run
: スクリプトの呼び出し前に一度実行post_run
: スクリプトの呼び出し後に一度実行
Note
プレ & ポストスクリプトは引数を受け取ることができません。
名前の競合を避ける
[tool.pdm.scripts]
テーブルに install
スクリプトが存在する場合、pre_install
スクリプトは pdm install
と pdm run install
の両方によってトリガーされる可能性があります。したがって、予約された名前を使用しないことをお勧めします。
Note
複合タスクもプレおよびポストスクリプトを持つことができます。 呼び出されたタスクはそれぞれのプレおよびポストスクリプトを実行します。
スクリプトのスキップ#
スクリプトを実行するが、そのフックやプレおよびポストスクリプトを実行しない場合があるため、
すべてのフック、プレおよびポストを無効にする --skip=:all
があります。
また、すべての pre_*
フックをスキップする --skip=:pre
とすべての post_*
フックをスキップする --skip=:post
もあります。
プレスクリプトは必要だがポストスクリプトは不要な場合や、
複合タスクのすべてのタスクを実行するが、1 つのタスクは実行しない場合があります。
これらのユースケースのために、スキップするタスクやフックの名前のリストを受け入れるより詳細な --skip
パラメータがあります。
1 |
|
このコマンドは my-composite
タスクを実行し、pre_task1
フックと task2
およびそのフックをスキップします。
スキップリストを PDM_SKIP_HOOKS
環境変数に提供することもできますが、--skip
パラメータが指定されると上書きされます。
フックとプレ/ポストスクリプトの動作に関する詳細は専用のフックページ を参照してください。