欧米の非常に多くのホスティング事業者や大手制作会社において、WordPressのメンテナンスの自動化にかかせないものとなった WP-CLI ですが、その仕組みや構造については日本国内ではあまり知られていません。
タイトルはやや大げさな気がしますが、今回は、WP-CLI の仕組みや今後の動向について解説して行きます。
WP-CLI は WordPress 本体の関数を直接コール
WP-CLI は、WordPress の管理画面等でできるほぼ全て、もしくはそれ以上の機能をコマンドラインで提供していますが、これらの機能はすべて WordPress の既存の関数を require
して実行されています。
もう少し詳しくいうと、WordPress 本体には wp-settings.php
というファイルがあり、これは WordPress 本体の心臓部とも言える重要なファイルですが、WP-CLIにはこれをフォークした wp-settings-cli.php
というファイルがあります。
https://github.com/wp-cli/wp-cli/blob/master/php/wp-settings-cli.php
これがまさに WP-CLI の心臓部といもいえるファイルで、このファイルから WordPress 本体の様々な機能を読み込んで、WordPress の管理画面と同じ機能を提供しています。
このことによって、WP-CLI は無駄に車輪を再発明することなく、さらに複数のバージョンの WordPress とスムーズに互換性を維持しながら、WordPress の機能をコマンドラインで利用可能にすることを実現しています。
すべてのサブコマンドは独立したファイル
WP-CLI のすべてのコマンンドは、php/commands
というディレクトリ以下にあり、サブコマンドごとにそれぞれ別のファイルになっています。
https://github.com/wp-cli/wp-cli/tree/master/php/commands
たとえば wp plugin
というコマンドであれば、php/commands/plugin.php
というファイルといった感じです。
このファイル内にはさらにそのサブコマンドがメソッドとして保存されており、このメソッドのメソッド名がコマンドの名前という構造になっています。
以下は、wp core xxxx というコマンドが保存されているファイルです。
https://github.com/wp-cli/wp-cli/blob/master/php/commands/core.php
拡張可能な構造
WP-CLI は拡張可能な構造になっており、サードパーティのコマンドを比較的簡単に追加することができます。
プラグインから追加
WP-CLI コマンドは、WordPress プラグインから追加することもできます。
この方法は、そのプラグイン固有の機能、たとえばバックアップやキャッシュのパージなど、特定のプラグインに依存する機能を実装する際に使用され、そのプラグインに同梱された状態で配布されます。
ためしに以下のコードをWordPressプラグインとしてインストールし有効化すると、そのWordPress ディレクトリ以下でのみ wp hello
というコマンドが利用可能なことがお分かりいただけると思います。
<?php /* Pugin Name: Hello Command */ if ( defined('WP_CLI') && WP_CLI ) { function hello_command() { WP_CLI::success( 'Hello!' ); } WP_CLI::add_command( 'hello', 'hello_command' ); }
既存のプラグインで、WP-CLI 用のコマンドラインインターフェースを持っているプラグインは意外とたくさんあります。
https://make.wordpress.org/cli/handbook/tools/
パッケージコマンド
WP-CLI コマンドは、Composer のライブラリとして開発し、単体のコマンドとして配布することも可能です。
これらはパッケージコマンドと呼ばれています。
パッケージコマンドは、特定の WordPress プラグインに依存せず、サーバーや開発環境などの環境そのものに依存する機能を提供するときに使用します。
たとえばみなさんのインフラでバーチャルホストを使用している際に、そのサーバー全体の WordPress で使用可能なコマンドを作りたいときはこの方法を使うべきです。
そうすることで、ひとつひとつの WordPress に特定のプラグインをインストールする必要がなくなります。
パッケージコマンドの開発には、専用のパッケージコマンドが用意されており、これを使用すると以下のような簡単なコマンドで、コマンドの雛形を作ることができます。
$ wp scaffold package hello-command
https://github.com/wp-cli/scaffold-package-command
アノテーション
WP-CLI のコマンドには、引数やコマンドラインオプションを指定することもできます。
WP-CLI のコマンドで引数やオプションを使用するには、アノテーションというコメントブロックを記述します。
<?php /** * Implements example command. */ class Example_Command extends WP_CLI_Command { /** * Prints a greeting. * * ## OPTIONS * * <name> * : The name of the person to greet. * * [--type=<type>] * : Whether or not to greet the person with success or error. * --- * default: success * options: * - success * - error * --- * * ## EXAMPLES * * wp example hello Newman * * @when after_wp_load */ function hello( $args, $assoc_args ) { list( $name ) = $args; // Print the message with type $type = $assoc_args['type']; WP_CLI::$type( "Hello, $name!" ); } } WP_CLI::add_command( 'example', 'Example_Command' );
このアノテーションを適切に記述することで、必須の引数やオプションとか、引数のフォーマットなどを自動的に WP-CLI が解釈し、エラー処理などを行ってくれます。
テスト
WP-CLI には、サブコマンドや、さらにそのサブコマンド、数々のオプションなど膨大な組み合わせのコマンドパターンがあります。
これらをひとつひとつ手作業で確認するのは不可能なので、PHPUnit と Behat というツールをつかってテストの自動化を行っています。
Behat によるテストは、以下のようなとても読みやすいフォーマットになっており、Trais CI 上で実際にそれぞれのコマンドを実行することで動作確認を行っています。
Scenario: Install a plugin, activate, then force install an older version of the plugin Given a WP install When I run `wp plugin install akismet --version=2.5.7 --force` Then STDOUT should not be empty When I run `wp plugin list --name=akismet --field=update_version` Then STDOUT should not be empty And save STDOUT as {UPDATE_VERSION} When I run `wp plugin list --fields=name,status,update,version,update_version` Then STDOUT should be a table containing rows: | name | status | update | version | update_version | | akismet | inactive | available | 2.5.7 | {UPDATE_VERSION} |
現在テストのバリエーションが膨大な量になっており4,000通り以上のパターンでテストされています。
Behat によるテストファイルは、features ディレクトリ以下にあり、コマンド用のファイルと同様にコマンドごとに別々のファイルとして保存されています。
https://github.com/wp-cli/wp-cli/tree/master/features
WP-CLI プロジェクトでは、コマンドの追加のプルリクエストの際には、かならずこのテストの追加も求められます。
一方で、コマンドの挙動を知りたい場合には、ほとんどのユースケースがこのテストの中に含まれていますので、そこでそのコマンドがどんな振る舞いをするかを確認することもでき、ある意味仕様書としても有用なものとなっています。
プロジェクトを分割する方向で検討中
上述しましたが、WP-CLI コマンドのバリエーションは膨大なものとなっており、Travis CI 上でのテストケースが今の時点ですでに4,000通り以上あります。
このことは開発にそれなりのストレスになりつつあり、現在サブコマンドごとにプロジェクトを分割する方向で検討が進んでいます。
一方で、あたらしいサブコマンドもパッケージコマンドとしてリリースすることになると思われます。
またコマンドを分割することでさらに積極的に多様なサブコマンドの開発にフォーカスすることも考慮されており、以下のリポジトリで様々なアイディアのディスカッションが行われています。
https://github.com/wp-cli/ideas
開発メンバー
WP-CLI のGitHubプロジェクトには現在55人のメンバーがおり、筆者も日本人としては唯一のチームメンバーです。
実質的にはリード開発者の Daniel Bachhuber が唯一のコミッターであり、彼が中心になって開発が行われています。
プルリクエストや Issue を見ていると、海外のホスティング会社のエンジニアがアクティブに関わっているように見受けられます。
ちなみに現在 WP-CLI チームでは、週に5-10 時間ほどのパートタイムでの有償メンテナーを募集しているようです。
週5-10時間というのがすごく曲者で、僕が間近で見た限りではリード開発者のDanielさんの感覚での5-10時間というのはかなりやばそうですが。。。