Technote

by sizuhiko

PHP Conference 2014で「擬人化から始めるPHPerのためのオブジェクト指向超入門」を発表してきました

2014/10/11 に行われたPHPカンファレンス2014で発表をしてきました。

Photo by gihyo.jp

スライドは以下の内容です。

PHPカンファレンスでは公募セッションは最大30分のため、なぜ今回このようなタイトルを発表しようと思ったか、という背景については話ことができませんした。こちらのブログでは、スライドの共有と共に、その辺りの経緯について書いておきたいと思います。

なぜ今オブジェクト指向か?

オブジェクトデザインは原著から数えると、もう12年になろうとする訳です。これはセッションの中でも話したのですが、2003年当時はまだWebのフレームワークもまだ今日のようなものでなく、多くの会社は各社オレオレフレームワークを作っていた時代です。 オブジェクト指向が必要ないような使い捨てサイトならまだしも、受託やサービスなどソースコードを維持したり、機能アップをするような場面ではオブジェクト指向が必要だと考え、今のアジャイルムーブメントかそれ以上に語られていたはずです。

オレオレフレームワークを作ったことがある人は、オブジェクト指向やデザインパターンをよく勉強してそのあり方を議論したものです。 そのような人たちが、現在の入門プログラマーに「オブジェクト指向がわかってない」と言っても、そもそも通じないと思ったのがきっかけでです。

ここ4,5年の間にWebからプログラミングを始めた人(Webフレームワーク世代)は、すでに素晴らしいWebフレームワークがあり、その上でプログラミングをすることを要求されます。言語そのもの、たとえばPHPなら「イラストでよくわかるPHP はじめてのWebプログラミング入門」や「よくわかるPHPの教科書」あたりを読んでから、各フレームワークの本や公式チュートリアルを片手にアプリケーション開発を始めています。 つまりオレオレフレームワーク世代のオッサンが通過したオブジェクト指向やデザインパターンの経験に基づいてソースコードに手厳しいコメントを付けても、受けた方も辛いだけなのです。

今どのような弊害が起きているのか

で、このようなWebフレームワーク世代はCakePHPやその他のWebフレームワーク(MVC的なもの)を使って、MVCの枠に収めようとしてFatコントローラになったりしやすいのです。 なぜなら特定のディレクトリにフレームワークが指定した方法で書いていれば、良くわかんないけどうまく動いてしまうのです。フレームワークすげーな!という訳です。 それ以外の書き方は知らないし、どこにも書いてないのです。 結局、適切にクラス分割ができないため、結果として与えられた範囲の枠組みで問題はない、と考えているような状況を見かけるのです。 classってPHPの文法です、キリッ!とか言われたことはないですが、まぁ無くはないのかな…と。

じゃぁフレームワークの本に、その概念や考え方を書くべきだという声もあるかもしれません。私もCakePHP本の執筆に携わったことがあり、耳の痛い話です。しかしフレームワークの本では、すべてのフレームワークについての説明もページ数的に困難な中、OOPやMVCの概念のような内容を解説するのは困難なことも事実です。

そこで話してみようと思った

もちろん、オブジェクト指向ムーブメント世代のオッサンであってもオブジェクト指向をみんな理解しているかというと、そういう訳ではありません(まぁ少なくともみんな読書会なんかして勉強はしていたような気がします)。 今時のWebフレームワーク世代だって、しっかり勉強している意識高い人はいっぱいいるし、知っています。 ただ最近プログラミングを始めた人は、技術の移り変わりが激しいし、言語やフレームワークはどんどんバージョンアップするし、なかなか基礎的な事に対する勉強時間を作るのが難しいのではないかな、と思うのです。 しかもオブジェクト指向の勉強って難しいし「銀の弾丸」は無いわけです。最近そういった勉強会の話もあまり聞きません。 ではどのあたりから始めると良いだろう?という当たりを付けられるセッションをしてみたいと思ったのです。

私が技術支援で入った中で良く感じている問題はオブジェクト指向プログラミングというより、そもそものオブジェクト指向がうまく理解されていないと思ったので以下のポイントに絞った内容にしたいと思いました。

  • オブジェクトとは何なのか
  • オブジェクトを導出するにはどうしたら良いのか
  • 今回のPHPカンファレンスのテーマは「知りたい,があなたを変えていく」

これらの要件に合うのは、責務駆動設計の中心的原理とテクニックを解説した「オブジェクトデザイン」の紹介が最適で、30分という時間に適している(知りたい==何か持ち帰って始めることができる)と思ったのです。

どうだったか

セッションをやっている間、いつも盛り上がっていないと不安なので、小ネタを差し込むのですが、皆さん真面目に聞きに来ていただいたので、講演者から見るとダダ滑りでした(個人的な感想です)。ただjoind.inのコメントを読ませていただいたり、顔見知りの方に確認した範囲では何かしら体験を持ち帰っていただけたようで「知りたい」につながったのかな、と思っています。

もし私の講演を聴いていただいてコメントまだな方は、コチラに一言いただけると嬉しいです。joind.inは匿名でのコメントもできますので、ご安心ください。

また、今回の目玉?!セッションであった「ウェブエンジニアに必要なセキュリティスキルとは 徳丸浩 x 大垣靖男」の対談セッションでも思ったのですが、お二人の話の大きな相違点のベースである現実論理想論のケースはセキュリティだけではなく、オブジェクト指向についても同じだな、と思いました。 私はすべての人がオブジェクト指向を理解して進めるのが理想だと思うし、アジャイル原則の私たちはオブジェクト指向を理解しているプログラマーであるべき、と思っています。ただすべての人がそうでないというのも理解できるので、理解度はともかくオブジェクト指向と向き合って欲しいなと思っています。そこから何かが変わると良いな、と。

裏話

実は、セッションを応募するとき、PHPカンファレンスでは重複して申し込めると聞いていたので、オブジェクト指向超入門(上)と、オブジェクト指向超入門(下)の2セッションにして合わせて60分で申し込もうと思ったのですが、それは通らなそう(www)と思って自重しました。 またどこかで60分セッションやれる機会があれば、やってみたいなと思うのでした。

CakeFest2014に参加しました

9/19に茅場町Co-Edoで行われたCakeFest2014報告会でも話した内容をベースに記事にしました。

すでに同日に発表された@yandoさんの記事「マドリードで見たCakePHP3の明るい未来」が秀逸なので、CakePHP3の動向についてはその記事をご覧ください。

では私は何を書くかというと、報告会でも話したCakeFest2014の全体感と、来年10周年を迎えるCakePHPを盛り上げる為にみんなでCakeFestに行こう!という気分になってもらえると良いな、というまとめになっています(ちょっとはCakePHP3についても書くよ)。

CakeFestの歴史

CakeFestは2008年に始まって、今回で8回目になります。 参考URL:lanyrd.com

  • 2008/02 フロリダ・オーランド
  • 2008/12 ブエノスアイレス(参考URLの年は間違っています)
  • 2009/07 ベルリン
  • 2010/09 シカゴ
  • 2011/09 マンチェスター
  • 2012/08 マンチェスター
  • 2013/08 サンフランシスコ
  • 2014/08 マドリッド

初年度を除いて、およそ1年に1回世界中からコミュニティのメンバーが集まるお祭りです。

2回目のブエノスアイレスを除いてアメリカとヨーロッパで開催されており、私が始めて参加した4回目のシカゴからは8月終わりor9月初めに開催されるようになりました。 コアデベロッパーは家族や彼女と来ていたりするので、夏休みも兼ねているのではないか、という緩いイベントだった..だったのです。

緩い理由は例えば2012年(マンチェスター)のスケジュールを見てもらえるとわかりますが、9時に始まって16時ぐらいには終了です。このときは2トラックだったこともあり、セッション数としては少なくはないのですが、泊まりのカンファレンスイベントとしては割とあっさり終了する感じです。このあとはLTやりたい人がいればやるみたいな、日本のキッチリしたイベントの仕切りやテキパキ感というよりは参加者がお茶やビールを片手に交流する時間がたっぷり取られているという感じだったのです。

2014年は違っていた

私もCFP(Call For Paper)にセッションの応募をしたのですが、落選してしまいました。 で、確定したスケジュールを見て、ビックリしたのです。 朝は9時からと例年通りですが、終わる時間が!!なんと21時ですよ。つまり12時間。これはちょっとしたPHP Matsuri状態ではないですか。

今年はシングルトラックでしたが、あんまりBreakタイムがなかったので、各自の判断でカンファレンスルームの外で話したりしていた状況ではありました。

なお私が知る限りのCakeFestの中では、最もイベントとしてのテキパキ感とかはあったように思います。これもコミュニティマネージャであるJames Watts氏の活躍があってこその事。CakeFestの仕切りも3回目という事でだいぶ慣れてきたのかなーとも思います。

CakePHPの中の人たち

そういえば、あまりCakePHPの中の人たちって使っていてもCakeFestに参加しないと知らないのではないかと思い、コアチームのメンバーの顔と名前が一致するように、2枚の写真で紹介します。

photo by Anna Fillina.

左からJames Watts、Jose Gonzalez(@savant)、Larry Masters(@phpnut)(敬称略)

こちらの写真は私がスペインに到着した夜の出来事なのですが、まぁお酒もだいぶ入っているところでの余興みたいな感じだったのでしょう。私はフライトの疲れでビールを1杯飲んで部屋に戻ってしまったので見ていなかったのですが、こんな感じでホテルのバースペースで盛り上がったり、そのあと朝4時まで繁華街へ飲みに行ったりしていたみたいです。 毎年朝方まで飲んでいる参加者がいるのもCakeFestの一部です(その影響か午前中はホテルの部屋から出て来ない人も多数ですがw)。

で、写真の後どうなったか、というとコチラの動画から確認できます。

ここ数年はコアチームへのQ&Aセッションがあります。こちらでもCakePHPの中の人たちを確認することができます。

photo by Anna Fillina.

左からMarc Ypes(@ceeram)、Mark Story、Mark Scherer(@dereuromark)、Larry Masters(@phpnut)、José L. Rodríguez(@josezap)、Jose Gonzalez(@savant)、Renan Gonçalves(@renansaddam)、James Watts(敬称略)

CakePHP1.3の終了と2系の今後

Q&Aセッションはカンファレンス1日目のお昼直後に実施されたのですが、午前中にMark Story氏からCakePHP3の話と、1.3のサポート終了の話があったので、その2つについて質問が集中していました。1.3のサポート終了に関しては、何とちょうど先週顧客にCakePHP1.3を使った案件の提案をしたばかりなのに、どうしたら良い?何とかならないの?!というビックリするようなQを聞きました。先日も1.3のアップデートがあったり、1.3自体非常に長い間使われているのだなぁと思いました。その後、質問をした人になんでこれから1.3使うの?と聞いたら、資産があるから、という事でした。 こちらのAは、ベストな方法はマイグレーションすることだけど、3ではなくCakePHP2にするのが良いという話と、1.3の件は通常のCakePHPとしてはムリだけど、CakeDCとして考えられなくもない。まぁビジネスだね、という回答でした。 とはいえ、たぶんCakeDCも1.3の面倒を見続けるのは現実解ではないので、マイグレーションのサポートをする事で解決をするのではないかなーと思われます。

日本でもまだCakePHP1.xを使っているサイトなど残っていると思いますが、3へのジャンプは難しいと思うので、まず2系にしておくことが重要になるでしょう。 2系についてはまだ3年はサポートと今回明言されています。じゃぁまた3年後には3にしないといけないの?!という話はあるかもしれませんが、1から2系へはアップグレードシェルがあるのと、3のアップグレードシェルができたとして、2系からのアップグレードのみ対応であると推測されるので、まずは2系なのかなと思います。これは上記のコアチームのQ&Aでの回答からも妥当な判断と思います。

CakePHP3で気になっていたこと

CakePHP3のもくもく会で、何度もCakePHP3を試しているのですが、昨年ビヘイビアって無くなるって言ってなかったか?と思い、ORM担当の大きいJoseこと@jose_zapに確認しました。答えとしては、いろいろ考えたけど、コールバックの関係もあって互換性を考え残すことにした。もちろんTraitにしてEventマネージャを使うアプローチは素晴らしいし、できればそちらを使ってほしいけど、コアとしてはビヘイビアも残すよ、ということでした。

恒例のリアルケーキ

今となっては恒例となったリアルケーキ。実はCakeFestで始めてケーキが登場したのは、2010年のシカゴだったと記憶しています。 キッカケは日本で開催されたCakePHPカンファレンス東京で、当時のCakePHP開発マネージャだった@gwoo氏を招いてCakePHP型のケーキを出したのがとてもウケが良く、それが本家でも採用されたと。CakeFestには日本コミュニティのDNAが含まれています!

この直後、コアチームとして新しく入った@dereuromarkがファーストバイトならぬカップケーキ投げの手荒い歓迎を受けたり、サプライズイベントがあったり、楽しくケーキを食べながら交流を深めて解散となりました。

CakeFest2014で感じたこと

CakeFestに参加すると、良く知った常連さんと、始めての人がいて、なるべく始めて会った人と話すようにいつも心がけています。

各国でのCakePHPの普及状況や、コミュニティの活動などの話を聞くのですが、ドイツから参加してきていた人の話によると、CakePHP(PHP)のイベントをやりたいけど、なかなか人が集まらなくて苦労している。日本ではどうなの?という話から、日本の状況を説明すると、とても日本のコミュニティが羨ましいという感想をもらいました。これはドイツ以外の参加者からも同様の反応をもらったのですが、まぁ日本というか東京など都市部には人が密集していてやりやすい状況なのかな、とも思います。そういった環境面やコミュニティ活動を積極的にやってくれる人がいるので都市部のエンジニアは特に恵まれた状況だと思います。もっと勉強会やイベントに出て交流しましょう!

今年は(も)シングルトラックだったのでほぼ全てのセッションを見る事ができたのですが、CakePHPと関連するセッションは、コアチームに集中していて、他のセッションはPHP全般だったり、JavaScriptだったり、HTML(CSS)だったりとCakePHPに関する話題は例年以上に少なかったような気がします。 これはCakePHP2のライフサイクルがだいぶ長くなっていて新しい話題が少なめなのと、まだ3は早すぎるという状況もあったのではないかと思います。 来年はコアチーム以外からも3の話題がもっと出てくるのではないかと思います。

CakeFest2014のjoind.inにスライドのリンクがあるので、ぜひCakePHP3のセッションについては見て欲しいのと、公式のPodCastが配信されているので、そちらも聞くとCakePHP3について理解が深まると思います。

CakePHPに関する話題以外で、ぜひスライドをチェックして欲しいのは

  • Writing code that lasts presented by Rafael Dohms
  • Why You Can’t Test presented by Chris Hartjes

どちらもPHP界では有名人で、同じ内容を各国のカンファレンスで講演しているので、どこかで見ているかもしれませんが、一度はチェックしてみてください。

LTもやったし、BDDプラグインの人として声をかけられたり、交流できた

また初日のLTでData Generator for Testing CakePHP Application(いつものテストデータの作り方の英語バージョンです)をやりまして、反響もたくさんもらいました。 CakeFestのスピーカーの中には、特にCakeと関係ないけどPHPのセッションとして応募してくる人もいるので、他のフレームワークには対応しないの?とか、Fakerと連動するにはどうするの?などなど。 CakeFestではLTは当日募集で、手を挙げればもれなく喋れるので、海外カンファレンスでのプレゼン登竜門としては最適と思います。

それと自分の自己紹介スライドのアイコンから、BDDプラグインの人でしょ?と声をかけられたりもして、Breakタイム少なかった割によく話したなーという印象でした。

また例年以上?に日本自体に関心がある人がいて、日本語喋れるノルウェーからの参加者(漫画大好き)だったり、日本食について聞いてくる地元スペインの人だったり、3次会でカラオケ行こうと誘われたり、フクシマの話をしたり、PHP以外の話でも交流ができました。

「海外のカンファレンスとか行ったことないし、大変そう」という方がほとんだと思います。私もお世辞にも英語得意でない(割と適当)けど、何とか交流できています。CakeFestであれば、ここ数年@yandoさんや私が参加していますし、行きたいと宣言すれば一緒に行く人が見つかるかもしれません。

もし会社勤めのエンジニアだと休みが取れない、経費出ない、など難しい事情があるかもしれないのですが、ぜひ上司と交渉して来れるようになると良いなと思っています。参加して得られることは文章では書けないぐらい大きいです。

コミュニティマネージャからのメッセージ

最後にコミュニティマネージャであるJames Watts氏から、キーノートに関連して日本のコミュニティへメッセージをいただきましたので、動画をシェアします。 では来年のCakeFestで会いましょう!

最初のトラブルは、テラスの石畳と砂利の間に足を取られて転びそうになったのです…

CakePHP3(Beta1)のDebugKitではSQLiteが必要になります

CakePHP 3.0.0 もくもく会(勉強会) #7 に参加してCakePHP3ベータ1を早速試しました。

ベータ1はアルファ版からディレクトリの変更も多く、CakePHP本体をcomposer updateしてもダメなので、再度 composer create-project でテンプレートから生成しなおします。

最新のcakephp/appテンプレートにはDebugKitプラグインが依存関係に入っています。

    "require": {
        "php": ">=5.4.19",
        "cakephp/cakephp": "3.0.*-dev",
        "mobiledetect/mobiledetectlib": "2.*",
        "cakephp/debug_kit": "3.0.*-dev"
    },

require-devではないのですね、と思ったり。。

以下のコマンドでCakePHP3アプリケーションのプロジェクトスケルトンを作ります。

composer create-project -s dev cakephp/app dev-cake3 app

ブラウザでアクセスすると、以下のような画面が表示されます。

なんかDebugKitがSQLiteを参照しているみたいなんですよ。

そこで、DebugKitの設定を見てみます

app/plugins/DebugKit/config/bootstrap.php

if (!ConnectionManager::config('debug_kit')) {
    ConnectionManager::config('debug_kit', [
        'className' => 'Cake\Database\Connection',
        'driver' => 'Cake\Database\Driver\Sqlite',
        'database' => TMP . 'debug_kit.sqlite',
        'encoding' => 'utf8',
        'cacheMetadata' => true,
        'quoteIdentifiers' => false,
    ]);
}

そうですか、そうですか…

githubのCakePHP3用ブランチもチェックしてみました。

Requirements

The 3.0 branch has the following requirements:

CakePHP 3.0.0 or greater. PHP 5.4.19 or greater. SQLite or another database driver that CakePHP can talk to. By default DebugKit will use SQLite, if you need to use a different database see the Database Configuration section below.

そうですか、そうですか….

でもなんか別のDB接続も可能みたいに書いてあるよ

Database Configuration

By default DebugKit will store panel data into a SQLite database in your application’s tmp directory. If you cannot install pdosqlite, you can configure DebugKit to use a different database by defining a debugkit connection in your config/app.php file.

ふむふむ

config/app.php のDatasourceに以下のようなdebug_kit接続を追加してみます。

        'debug_kit', [
            'className' => 'Cake\Database\Connection',
            'driver' => 'Cake\Database\Driver\Mysql',
            'persistent' => false,
            'host' => 'localhost',
            'login' => 'hoge',
            'password' => 'fuga',
            'database' => 'database_name',
            'prefix' => false,
            'encoding' => 'utf8',
            'timezone' => 'UTC',
            'cacheMetadata' => true,
            'quoteIdentifiers' => false,
        ],

ブラウザをリロード

ぎゃー、DebugKitの該当箇所のコードを見てみると、そんなに変じゃないように見えますが、

        $configs = ConnectionManager::configured();
        foreach ($configs as $name) {
            $connection = ConnectionManager::get($name);

このときの$configをwatchしてみると

array (size=5)
  0 => string 'default' (length=7)
  1 => string 'test' (length=4)
  2 => int 0
  3 => int 1
  4 => string 'debug_kit' (length=9)

上記のようになっています。2と3誰よ….

ということで、まだベータ1だからねー。はははーという事で、現時点はSQLiteのextension入れて試しましょう。

例えば、friendsofcakeのvagrant-chef使っているなら、cookbooks/php/recipes/install.rbに追加します。

  "php5-mysql",
  "php5-sqlite",

mysqlの下あたりに追加します。vagrant destroy/upを実行して環境を作り直したら、もう一度ブラウザをリロードします。

おなじみの青いバーの画面が表示されました。画面の右下に出ているCakePHPアイコンがDebugKitです。 アイコンをクリックすると以下のようにデバッグ情報を参照可能になります。

DebugKitも使えるし、どんどんCakePHP3のアプリケーション開発がやりやすくなっていると思います。 CakePHP3.0.0 もくもく会で情報交換しながら、楽しく新機能を試してみませんか?

CakePHPで学ぶ継続的インテグレーションが発売されます

先日の記事にも書きましたが、

春先ぐらいからBlogの更新が滞っていましたが、その要因となったアレが大分落ち着いてきたので、たまっていたネタを順番に書き出します。

アレが出ます。

ババーン ww とでかい画像を付けましたよ。

CakePHPで学ぶ継続的インテグレーション

共著者の

でも既に紹介されていますので、そちらを一読いただくと理解が深まります。

私は主に以下のあたりを担当しました。

  • Chapter 5 開発工程(1)
    • 5-1 開発の進め方
    • 5-2 ユーザーストーリーの定義
    • 5-3 機能実装
  • Chapter 6 開発工程(2)
    • 6-1 ステップの定義
    • 6-2 継続的インテグレーションの定義

上記以外でも、おおよそCakePHPに関連するところを書いたと思っていただければ。

これは何の本

タイトルの通り、と言いたいところですが、わからないという人のために補足すると

  • 継続的インテグレーションの入門書です
  • CakePHPでのアプリケーションの作り方を解説した本ではありません
  • サンプルアプリケーションの構築、自動テストの作成方法の解説にCakePHPを使っています

タイトルや見出しから内容が想像しずらいと思うので、私が書いた部分の継続的インテグレーションに関する技術的キーワードを列挙すると、以下のとおりです。

上記以外にアプリケーション構築用にBoostCake、CakeDC Usersプラグインも使っています。 自分が作ったプラグインであるBDDとFabricateを採用していますが、これは現在支援を行っている現場でも活躍しているので手前味噌というだけでなく、自動テストを継続していく上で役立つと思います。

私の記述したところの、ざっくりした解説は以下のとおりです。

  • ComposerとMigrationsプラグインを使うと、誰でも簡単に同じ環境を構築することができるようになります。
  • Environmentsプラグインを使うと、環境毎の設定切り替えや、振る舞いの制御を容易にできるようになります。
  • BDDプラグインを使うとCakePHPからBehatとの連携が容易になり、受入テストの自動化に取り組みやすくなります。
  • Fabricateプラグインを使うとFixtureを使ったテストデータの呪縛から解放されます。

これらは過去から現在に至るまで、私が様々なプロジェクトで経験したことを背景にしています。 もちろんプロジェクトごとに様々な背景があると思いますが、一度実践していただければ効果を体感していただけるのではないかと思っています。

また、PHP界隈ではまだBDDやATDDに関して、解説する本がなかったり、実践的な解説がなかったのですが、本書がこれらを導入するきっかけになると嬉しいなと思っています。

CakePHP以外ではどうなの

サンプルアプリケーションの構築にはCakePHPを利用していますが、上記の技術要素に関しては他のPHPフレームワークでも同様のものがあると思います。 もし、CakePHP以外のフレームワークに精通していれば、Behatを直接使ったり、データジェネレータにFakerの機能を使ったり、各フレームワークのマイグレーションや環境切り替えプラグインを使ったりできるのではないかと思います。 皆様の現場の状況に合わせて読み替えて、継続的インテグレーションを導入する参考にしていただければ幸いです。

いつ発売なの?

amazonでは2014/09/19(金)に発売です。

書店などでは多少前後することがあると思いますが、ぜひ一度手に取ってみてください。

また9/19は、茅場町Co-EdoにてCakeFest2014報告会を実施します。本会には共著者である@kaz_29さんも参加予定なので、著者サインを集めるチャンスです! 先月実施されたCakeFestではどんな事があったのか、CakePHP3の動向などを話しますので、ぜひこちらにも参加ください。

お知らせと感謝(追記)

CakePHP3の話題もあるなか、まだまだ現場ではCakePHP2を利用するケースもあると思います。 本書をきっかけにCakePHPをより学んでみたいなと思っていただけたら、私も共著者で参加したCakePHP2実践入門(amazonでチェック)を参考文献として手に取ってみてください。

こちらはちょうど2年ほど前の2012/09/29に発刊となったのですが、このたび 第3刷 の増刷が決まりました。

長い間CakePHP2の参考書として手に取っていただいているようで、本当に嬉しいです。ありがとうございます。

CakePHP2のプラグインをTravis.ciで継続的インテグレーションする

春先ぐらいからBlogの更新が滞っていましたが、その要因となったアレが大分落ち着いてきたので、たまっていたネタを順番に書き出します。

CakePHP2のプラグインを作成/公開していて、継続的インテグレーションってどうするの?と思っていました。 もちろんユニットテスト書いてあるし、素晴らしい協力者の方がPull Requestを送ってくれれば、developブランチに取り込んでテストしたりします。

Githubを徘徊していると、よく見る

これを表示したいと思ったのです。

ただCakePHP2のプラグインは当然それだけではユニットテストを実行できません。CakePHPのアプリケーションがあって、テスト用データベースとその設定があって…、ぬーん。 早い話、テスト用のアプリケーション作って、そこからテスト実行すれば良いの?ということをずっと思っていました。

CakePHPの有名プラグインはどうしているのだろう?

と思い、最初にチェックしたのはCakeDC/searchプラグイン。 大抵のアプリケーションで使う、もっともメジャーなプラグインではないかと思います。 Searchプラグインにも、あのビルド成功やダウンロード数、バージョン番号の画像が表示されています。

.travis.yml ファイルがあるので、内容を確認してみます。 すると、

before_script:
  - git clone https://github.com/burzum/travis.git --depth 1 ../travis
  - ../travis/before_script.sh
  - if [ "$PHPCS" != 1 ]; then
            echo "
                require_once APP . DS . 'vendor' . DS . 'phpunit' . DS . 'phpunit' . DS . 'PHPUnit' . DS . 'Autoload.php';
            " >> ../cakephp/app/Config/bootstrap.php;
    fi

https://github.com/burzum/travis.gitをcloneしてきて、何かやっているようです。

CakePHPプラグインを簡単にTravis.ciで継続的インテグレーションできる

早速、ページにアクセスしてみると、どうもそれはあのFriendsOfCakeからForkされたもののようです。 FriendsOfCake元リポジトリを確認します。

Easy travis setup for CakePHP plugins This repository helps easy travis integration for CakePHP plugins, primarily focused on FriendsOfCake projects, but can be used within any plugin when satisfying the requirements.

おぉ、正に私の求めていたもの。

Fabricateに導入してみた

最近作った中で、最も思い入れのあるCakePHPプラグインFabricateを継続的インテグレーションするため、上記のFriendsOfCake/travisを導入してみます。

Quick Installに書いてるとおり、以下の手順で進めます。

cd ~/develop/fabricate

git clone https://github.com/FriendsOfCake/travis.git

export PLUGIN_NAME="Fabricate"

travis/setup.sh

rm -rf travis

私がやったときはこの手順ではなかったのですが、最近変わったみたいです… まぁ細かい事は気にせずですね。

実行すると、以下のファイルが自動生成されます。

  • .travis.yml : Travis.ciで継続的インテグレーションを実行するための設定ファイル
  • Test/Case/AllFabricateTest.php : プラグインのユニットテストをすべて実行するテストスイート。すでにこの命名規則で生成されていれば作られません。

以前のバージョンでは

  • .editorconfig
  • .semver
  • .travis.yml
  • .AllPluginNameTest.php
  • composer.json
  • CONTRIBUTING.markdown
  • LICENSE.txt
  • README.markdown

が生成されていましたが、継続的インテグレーションには必要がないファイルも混在していたので、整理されたものと思います。

後はTravis.ciにサインアップして、リポジトリを追加するだけです。

実は、これが最初のビルド。PLUGIN_NAMEをexportしていなかったので、正しくテストの実行が動いていませんでした。PLUGIN_NAMEはちゃんとexportするようにした方が良いです。 .travis.ymlのPLUGIN_NAMEFabricateに設定して実行した結果が以下の画面です。

現在のtravis.gitではPHP5.4以上のようなので、問題ないのですが、当時(と言っても数ヶ月前)はPHP5.3もテスト対象になっていたので、ショートArrayシンタックスを使っている私のコードはテストが失敗していました。.travis,ymlのPHP部分を以下のように変更して

php:
  - 5.4
  - 5.5

pushすると、ビルド結果は以下のようになります。

PHPCS以外は成功しています。

PHPCSではCakePHPのコード標準がチェックされます。 CakePHPの標準コードチェックだと厳しい部分だったり、パラメータを変更してチェックさせたくないディレクトリがあったりすると思うので、PHPCS_ARGSでphpcsを実行するときのパラメータを上書きできるようになっています。

matrix:
  include:
    - php: 5.4
      env:
        - COVERALLS=1
    - php: 5.4
      env:
        - PHPCS=1
        - PHPCS_ARGS="-p -s --extensions=php --standard=ruleset.xml --ignore='*/Test/*,*/Vendor/*' ."

拡張子phpのファイルを対象とし、TestやVendorのディレクトリを対象外として実行します。 ruleset.xmlは以下のようにしました。

<ruleset name="Custom Standard">
    <rule ref="CakePHP">
        <exclude name="CakePHP.NamingConventions.ValidVariableName.PrivateNoUnderscore" />
        <exclude name="CakePHP.NamingConventions.ValidFunctionName.PrivateNoUnderscore" />
        <exclude name="CakePHP.NamingConventions.ValidVariableName.ProtectedNoUnderscore" />
        <exclude name="CakePHP.NamingConventions.ValidFunctionName.ProtectedNoUnderscore" />
        <exclude name="CakePHP.NamingConventions.ValidFunctionName.ScopeNotCamelCaps" />
        <exclude name="CakePHP.NamingConventions.ValidVariableName.MemberVarNotCamelCaps" />
        <exclude name="CakePHP.WhiteSpace.TabAndSpace" />
    </rule>
</ruleset>

CakePHPのコード標準ではprivateやprotectedの変数、関数の先頭にアンダースコアが求められるので、それを無効にしたのと、キャメルケースではない変数や関数名を使いたい箇所があったので、それを無効にしています。 最後のCakePHP.WhiteSpace.TabAndSpaceでは、以下のように=のインデント位置を合わせたコードがエラーになってしまうので、無効にしています(わかりづらいですが、=の位置が揃っています)。

public function __construct($name) {
    $this->name  = $name;
    $this->items = [];
}

どうなっているのか?

プラグインのリポジトリには.travis.ymlが追加されるぐらいです。 この設定内で、FriendsOfCakeのtravisリポジトリがcloneされ、以下に記述されている手順が実行されます。

before_script:
  - git clone -b master https://github.com/FriendsOfCake/travis.git --depth 1 ../travis
  - ../travis/before_script.sh

script:
  - ../travis/script.sh

after_success:
  - ../travis/after_success.sh

実行されるパターンは.travis.ymlに記述されているphpenv-matrixの組み合わせと、matrixのパターンになります。

  • PHP5.4, DB=mysql CAKE_VERSION=2.4
  • PHP5,4, DB=mysql CAKE_VERSION=2.5
  • PHP5.5, DB=mysql CAKE_VERSION=2.4
  • PHP5,5, DB=mysql CAKE_VERSION=2.5
  • PHP5.4, COVERALLS=1
  • PHP5.4, PHPCS=1

この6パターン毎に、before_scriptscriptafter_successが呼び出されます。

事前準備

before_script.shは実行準備のためのスクリプトで、PHPCSが1にセットされている場合は、以下のとおりpearチャンネルからCakePHPのコード標準とphpcsが依存関係としてインストールされます。

if [ "$PHPCS" = '1' ]; then
    pear channel-discover pear.cakephp.org
    pear install --alldeps cakephp/CakePHP_CodeSniffer
    phpenv rehash
    exit 0
fi

続いて、CakePHP本体が1つ親のディレクトリにインストールされます。Travis.ciではプラグインのリポジトリが最初にcloneされるのですが、結果として以下のようなディレクトリ構成となります。

  • $HOME/sizuhiko/Fabricate : プラグイン本体
  • $HOME/sizuhiko/travis : FriendsOfCakeのtravis.gitクローン先
  • $HOME/sizuhiko/cakephp : CakePHP本体
  • $HOME/sizuhiko/cakephp/app/Plugin/$PLUGIN_NAME : プラグイン本体がコピーされる先

上記ディレクトリ構成ができた後で、composer で依存関係を解決します。COVERALLS用のカバレッジレポートも生成されるようにファイルが準備されます。

実行

script.shがPHPCSが1の場合はphpcsを、それ以外の場合はユニットテストを実行します。

実行が成功したら

after_success.shがCOVERALLSのカバレッジレポートを生成します。

そして現在

最初のスクリーンショットがFabricateの現在の状態です。すべて成功しています。

最後にREADMEにバッジを表示させる方法を紹介します。

Travis.ciのバッジを表示する

Travis.ciの画面にアクセスして

build:failingのように表示されている画像をクリックします。

ブランチを選択して、表示形式からマークダウンを選択したら、表示内容をREADME.mdに貼り付けます。

カバレッジのバッジを表示する

カバレッジはCOVERALLSというサービスを使って表示します。

サイトにアクセスして、サインアップはGithubのアカウントでできるの簡単です。

サインアップ後に、上部のメニュー表示からREPOSを選択して、

ADD REPOをクリックしてリポジトリを追加します。 その後、追加したリポジトリのページを表示します。

今度は表示される画像ではなく、GET BADGE URLというボタンをクリックします。このあたりのUIは統一されると嬉しいですね…

いろいろな記述形式のコードが表示されるのでマークダウンのコードを選択してREADME.mdに貼り付けます。

ダウンロード数、バージョンを表示する

ここからはCIとは関係ないのですが、よく見るバッジであるダウンロード数とバージョン番号も表示してみたいと思います。

Badge Poserというサイトにアクセスします。

ダウンロード数やバージョン番号は、Packagistで表示されている情報を画像に変換するので、リポジトリがPackagistに登録されていることが条件となります。 Show the markdown for your Badgesにダウンロード数を表示したいPackagistのパッケージ名を入力します。

表示形式からマークダウンを選択して、コードをREADME.mdに貼り付けます。

最後に

CakePHPのプラグインを継続的インテグレーションする方法は、実はとても簡単でした。 これを機に、まだプラグインを継続的インテグレーションしていないそこのあなたも、Travis.ciとCOVERALLSを使って継続的インテグレーションをしてみましょう。