コンテンツにスキップ

Pants で adhoc tool を使ってみた

adhoc tool とは

adhoc_tool ターゲットを使用して Pants サンドボックス内で実行可能なターゲットを実行できる。次のような特徴がある。

  • 実行可能なターゲットには、pants run で実行できるファーストパーティのソースや、python_requirementjvm_artifact などのサードパーティの依存関係、システム外で管理されている実行可能ファイルなどが含まれる。
  • adhoc_tool はプラグインを開発・メンテナンスする必要なく、カスタムビルドプロセスを組み立てるための基本要素を提供する。
  • adhoc_tool の構築するハードルはプラグインの開発よりも低く、一時的なスクリプトの利用やプラグインの実際の開発前にプロセスのプロトタイプを迅速に作成するのに適している。
    • ただし、ビルドプロセスを定義するために手動で作業する必要があり、利用するツールを定義するターゲットは再利用しにくいというトレードオフがある。
  • adhoc_tool ターゲットは Pants サンドボックス内で実行可能なターゲットとして利用でき、通常は pants run goal で実行できるもの。
  • runnable targets は副作用がない純粋な関数である必要がある。Pants は入力がプロセスの出力を完全に記述すると仮定し、結果をキャッシュする。したがって、プロセスの振る舞いが入力だけでは完全に定義されていない場合、Pants の振る舞いは予測不可能または一貫性がない可能性がある。
    • runnable targets は冪等である必要があり、何度実行しても副作用がないようにする
  • キャッシュ効率を向上させるために、adhoc_tool を小さな増分のステップに分割することが理にかなっている。例えば、依存関係を取得し、それらの依存関係と一部のファーストパーティのソースファイルに基づいてライブラリをビルドする必要がある場合、各ステップごとに 1 つの adhoc_tool を持つことで、依存関係の取得ステージは要件が変更されたときにのみ再実行され、ファーストパーティのソースファイルが変更されたときに再実行されない。

簡単にまとめると Pants には plugin を記述できるが、plugin を記述するのは手間がかかる。adhoc tool は plugin を記述するよりも簡単にビルドプロセスを定義できるが、再利用性が低い。

adhoc tool を使ってみる

Pants が adhoc tool のを提供しているので、それを使ってみる。

この例には次のようなものがある。

  • jvm_artifact を使用して Antlr パーサージェネレータに依存を宣言し、adhoc_tool を使用して Antlr 依存性をビルドステップとして実行し、Python バインディングを含むファイルを出力
  • system_binary を使用して node および yarn のバイナリに依存関係を宣言し、adhoc_tool を使用して yarn install および yarn parcel コマンドを実行
  • python_source を使用して実行可能な Python ソースである webapp.py を宣言し、jvm_artifact を使用して JVM ベースの OpenAPI クライアントジェネレータに依存を宣言する。adhoc_tool を使用して webapp.py ソースを実行し、stdout=フィールドを使用してその出力をファイルに保存し、JVM クライアントジェネレータを実行

system_binary を使用すると、バージョン制約による基本的な互換性チェックなど、Pants の外部で管理されるツールへの依存関係を宣言できる。apt や homebrew などのパッケージマネージャーを使って Pants システムの外側でインストールされたツールを Pants から利用できるようになる。 fingerprint*フィールドは、ビルドが複数の実行環境にわたって再現可能であることを保証するために使用できるバージョン制約を設定できる。

system_binary からバイナリが見つからない場合は、extra_search_pathsフィールドを使用して、システムバイナリの検索パスを追加できる。

使ってみての感想

公式ドキュメントに書かれているように adhoc tool は再利用性が低い。adhoc tool は一時的なスクリプトの利用やプラグインの実際の開発前にプロセスのプロトタイプを迅速に作成するのに適していると感じた。