コンテンツにスキップ

Pants で adhoc tool を使ってみた

adhoc tool とは

adhoc_toolは、既存のコマンドやスクリプトを Pants のビルド工程に組み込むためのターゲットだ。処理は Pants のサンドボックス内で実行される。次のような特徴がある。

  • 実行可能なターゲットには、次のようなものが含まれる。
    • pants runで実行できるファーストパーティのソース
    • python_requirementやjvm_artifactなどのサードパーティの依存関係
    • システム外で管理されている実行可能ファイル
  • adhoc_toolはプラグインを開発・メンテナンスする必要なく、カスタムビルドプロセスを組み立てるための基本要素を提供する。
  • adhoc_toolを構築するハードルは、プラグインの開発よりも低い。そのため、一時的なスクリプトを利用したり、プラグインを実際に開発する前にプロセスのプロトタイプを迅速に作成したりするのに適している。
    • ただし、ビルドプロセスを定義するために手動で作業する必要があり、利用するツールを定義するターゲットは再利用しにくいというトレードオフがある。
  • adhoc_toolターゲットは、Pants サンドボックス内で実行可能なターゲットとして利用できる。通常はpants run goal で実行できる。

キャッシュと冪等性

runnable targetsは、副作用のない純粋な関数である必要がある。Pants は、プロセスへの入力だけで出力が決まると仮定して結果をキャッシュする。したがって、入力だけではプロセスの振る舞いを定義しきれない場合、Pants の振る舞いは予測不可能になったり、一貫しなくなったりする可能性がある。

  • runnable targetsは冪等である必要があり、何度実行しても副作用がないようにする
  • キャッシュ効率を向上させるには、adhoc_toolを小さな増分ステップに分割するのが理にかなっている。依存関係の取得とライブラリのビルドを別々のadhoc_toolにすれば、依存関係の取得ステップは要件が変わったときだけ再実行され、ファーストパーティのソースファイルを変更しても再実行されない。

plugin との比較

Pants のプラグイン開発には手間がかかる。adhoc_toolならビルド工程を手軽に定義できる一方、再利用性はプラグインほど高くない。

adhoc tool を使ってみる

Pants が公式に提供している adhoc tool の例(pantsbuild/example-adhoc)を使ってみる。この例では、次の 3 つのビルドを試せる。

Antlr パーサージェネレータのビルド

jvm_artifactを使用して Antlr パーサージェネレータに依存を宣言し、adhoc_toolを使用して Antlr 依存性をビルドステップとして実行し、Python バインディングを含むファイルを出力する。

yarn によるフロントエンドビルド

system_binaryを使用して node および yarn のバイナリに依存関係を宣言し、adhoc_toolを使用してyarn installおよびyarn parcelコマンドを実行する。

webapp.py と OpenAPI クライアントの生成

python_sourceで実行可能な Python ソースであるwebapp.pyを宣言し、jvm_artifactで JVM ベースの OpenAPI クライアントジェネレータへの依存を宣言する。そのうえでadhoc_toolを使ってwebapp.pyを実行し、stdout=フィールドでその出力をファイルに保存してから、JVM クライアントジェネレータを実行する。

system_binary による外部ツール依存の宣言

system_binaryを使用すると、バージョン制約による基本的な互換性チェックなど、Pants の外部で管理されるツールへの依存関係を宣言できる。apt や homebrew などのパッケージマネージャーを使って Pants システムの外側にインストールしたツールも、Pants から利用できるようになる。system_binaryの主なフィールドは次のとおり。

フィールド 用途
fingerprint* バージョン制約を設定し、ビルドが複数の実行環境にわたって再現可能であることを保証する
extra_search_paths バイナリが見つからない場合に、システムバイナリの検索パスを追加する

使ってみての感想

公式ドキュメントにあるように adhoc tool は再利用性が低い。それでも、一時的なスクリプトを利用したり、プラグインを実際に開発する前にプロトタイプを素早く作ったりするには適していると感じた。

まとめ

adhoc tool を使うと、プラグイン開発の手間をかけずにカスタムビルドプロセスを組み立てられる。ただし、ビルドプロセスを手動で定義する必要があり、再利用性はプラグインほど高くない。恒久的な仕組みとして育てたいならプラグイン化を、まずは動くものを素早く試したいなら adhoc tool を選ぶという使い分けが実用的だと感じた。