2010-06-23

PHPアプリの依存packageをpearで管理する

いつもちゃんと pear で管理しろよと言っている wtnabe です。おはようございます。

以前 pfm を使って pear package を作れるようになってからずいぶん経つんですが、実はこれまで依存 package を管理していませんでした。自分の作っているものはスタート時点では依存 package がややこしくならないようにするためのライブラリだったのですが、だんだんとできることが増えくるにしたがって依存 package も増えてきました。

package.xml を書くのは面倒

そこで pear package で依存 package をどう記述するのかを調べたのですが、当然ながら XML という非人間的なフォーマットで定義されているので、とてもサッと書ける気がしません。どうしよう、YAML で書いて package.xml に merge するツールでも書こうか、とか思ったりもしていたのですが、面倒です。だいたいあんまり生産的な感じがしない。

しかし先日、ついに気がつきました。

pfm に依存 package を定義するインターフェイスがあるじゃん。

使ってなかったから見落としてただけでした。

じゃあ話は簡単、とっとと定義してしまおう。add と delete しかできない豪快仕様だけど、XML 手打ちよりは多少マシ。

で、依存 package を解決できるようになってハタと思いつきました。

これでアプリ(サイト)単位で利用してる package を管理できるじゃん。

複数サイトのメンテナンスは面倒

複数のアプリ(サイト)をメンテしていると環境の準備がだんだん煩雑になってきます。こっちはこれとこれに依存していて、こっちはあれとそれに依存していて、えーとじゃあこの機械には結局何と何が入っていればいいんだっけ?という状態になるわけです。作っているときは気にならないけど、久しぶりにいじらなきゃいけなくなったときにこれではかなり困ります。ドキュメントがあればまだマシですが、手作業で準備しなきゃいけないのは面倒です。常にオリジナルから全 copy というスタイルもあるようですが、portable じゃないのであまり好きになれません。

そこで思いついたのが

依存 package だけを定義した package があればいんじゃね?

という方法だったのですが、結論から言うとこれは無理でした。

ダミーファイルを用意して package を作る

だったら話は簡単、内容のないダミーのファイルを用意すればいいんです。具体的にはアプリ(サイト)を識別する名前で空のファイルを作ります。

<contents>
  <dir baseinstalldir="." name="/">
  <file baseinstalldir="."
        md5sum="d41d8cd98f00b204e9800998ecf8427e"
        name="APP_NAME"
        role="data" />
  </dir>
</contents>

最低一つはこうした形で中身が必要になります。

名前とインストール先

名前はライブラリをインストールしたいアプリケーションの名前でいいんじゃないかと思います。この際、拡張子なしでファイルを作ると pear directory の中の data/ というディレクトリに入ります。

以下のような感じ。

|-- data
 `-- app_name   アプリ名
   `-- APP_NAME ファイル

具体的な pfm での作業の様子

まずは空のファイルを作る

作業のディレクトリを掘って、空のファイルを用意します。

$ mkdir app_name
$ cd app_name
$ touch APP_NAME

pfm で package の基本情報を入力

具体的にどのように作業するのか、ログを晒していきます。

 $ rlwrap pfm .

rlwrap は必須じゃないですが、あるとないとで作業効率が全然違います。ぜひ入れておきましょう。

PEAR Package File Manager Command Line Tool

Please enter the location of your package [.]*: .

Creating a new package file ...

Enter the base install directory*: .

Enter the name of the package [app_name]*:

Channel or URI based package? [c] (c,u)*: u

Enter the package URI*: http://example.com

Enter a 1 line summary*: meta package

Enter a description* (2 blank lines to finish):
meta package for dependency packages


Enter the release version*: 0.1.0

Enter the API version [0.1.0]*:

Choose a release stability [alpha] (alpha,beta,stable)*: beta

Choose an API stability [beta] (alpha,beta,stable)*:

Enter any release notes* (2 blank lines to finish):
initial release


Enter the minimum PHP version [5]*:

Enter the minimum PEAR Installer version [1.4.0]*:

Please choose a license from one of the following options

    1) Apache
    2) BSD Style
    3) LGPL
    4) MIT
    5) PHP

Please choose an option: 2

How many maintainers?*: 1

What type of maintainer is #1? [lead] (lead,developer,contributor,helper)*:

Enter maintainer #1's name*: name

Enter maintainer #1's username*: name

Enter maintainer #1's email [name@php.net]*: name@example.com

ここまでで以下のような package の元データができます。

PEAR Package File Manager Command Line Tool

    1. Package name                 [app_name]
    2. Channel/URI                  [URI: http://example.com]
    3. Summary                      [meta package]
    4. Description                  [meta package for dependency packages]
    5. Maintainers
    6. Version                      [Release: 0.1.0 API: 0.1.0]
    7. Stability                    [Release: beta API: beta]
    8. License                      [BSD Style]
    9. Notes                        [initial release]
   10. Dependencies
   11. Tasks
   12. Regenerate contents
   13. Echo package file to stdout
   14. Save & Quit
   15. Quit without saving          (ctrl-c)

Please choose an option from the menu:

ここで 10 を選んで依存 package を定義していきます。

依存 package の定義

すると dependencies 用の menu が現れます。今回は試しに Pear にある Net_URL_Mapper を定義します。

Edit Dependencies

    1. Return to main menu

    2. Add new dependency
    3. Clear all dependencies

    4. Change PHP >= 5
    5. Change PEAR Installer >= 1.4.0

    Dependencies:


Please choose an option from the menu: 2

Dependency type [pkg] (pkg,ext,php,prog,os,sapi,zend)*:

Dependency name*: Net_URL_Mapper

Is the dependency (o)ptional or (r)equired [r] (o,r)*: r

Package type (c)hannel or (u)ri [c] (c,u)*: c

Dependency channel [pear.php.net]*:

Minimum version:

Maximum version:

Edit Dependencies

    1. Return to main menu

    2. Add new dependency
    3. Clear all dependencies

    4. Change PHP >= 5
    5. Change PEAR Installer >= 1.4.0

    Dependencies:

    Required Package dependency "Net_URL_Mapper" - pear.php.net

こんな感じで依存 package が定義できました。あとはメインメニューに戻って

   14. Save & Quit

を選びます。できあがった package.xml のうち dependencies の部分だけ抜き出すと以下のようになっています。

<dependencies>
 <required>
  <php>
   <min>5</min>
  </php>
  <pearinstaller>
   <min>1.4.0</min>
  </pearinstaller>
  <package>
   <name>Net_URL_Mapper</name>
   <channel>pear.php.net</channel>
  </package>
 </required>
</dependencies>

まぁ慣れれば手でも書けそうですけどね…。一度定義すればそんなに変更することはないですからね。慣れによる精度向上を望めない作業は直接の手書きよりも pfm のようなインターフェイスで制限を設けて作業した方がいいように思います。

URI package は拡張子抜きで

[2010-07-13 追記]

Manual :: package.xml 2.0 における依存性の指定

に書いてある通りなんですが、

<package>
  <name>Foo<name>
  <uri>http://www.example.com/Foo-1.3.0</uri>
</package>

こんな感じですね。恐らくほぼ間違いなく .tgz を省略することになると思います。

beta package の依存性を解決する

pear パッケージマネージャはデフォルトでは beta バージョンについては依存関係を解決できません。一つ一つ手で入れる必要があります。しかしちゃんと検証して使えることが分かっていれば beta でも自動で入ってくれた方が嬉しいです。これは

pear config-show | grep preferred_state

が stable ではなく beta になっていると beta も自動解決できるようになります。

package.xml の中で特定の依存性に関しては beta でも解決するとか、install コマンドのオプションとか、そういう方法がないのが痛いですねぇ、pear は。channel package だけは beta でもインストールを継続するための記法があるんですが、依存 package についても beta でもインストールできるようにするオプションというものがありません。この辺は正直気が効いてない印象ですね。

まぁ、pear は cpan などと違って自由がないのが特徴なんですけど。

About

例によって個人のなんちゃらです