読者です 読者をやめる 読者になる 読者になる

理系学生日記

おまえはいつまで学生気分なのか

忍者TOOLS

モジュールインストールのタイミングでタグテーブルファイル (TAGS) を作りなおしたい

perl

モジュールをインストールしたら早速そのモジュールを使いたいですし、モジュールを使うってことは当然その実装を読む必要がありますし、実装を読むためには etags を使ってタグジャンプさせたいです。
というわけで、モジュールをインストールしたタイミングで、ローカルにインストールしている全モジュールのメソッドが含まれたタグテーブルファイルを作り直し、新規インストールしたモジュールについても即座にタグジャンプできるようにします。

方針

cpanm でインストールしたときは、$HOME/.cpanm/build.log に更新がかかるので、この更新を監視しておけば良いのではないかと思います。
監視デーモンを実装するのも良いですが、Mac には launchd デーモンがあり、launchd デーモンはファイルやディレクトリの監視機能が最初から備わっている (Mac の cron なんかもこの機能を利用してますね) ので、launchd に build.log を監視させておき、更新がかかったタイミングでタグテーブルファイルを更新するスクリプトを起動させれば良い。

plist

ファイルの監視は WatchPaths で指定できるので、それを使えばよいです。
WatchPaths は Value として array of strings をとり、個々の string に監視対象のパスを記述しておけば、そのどれかに更新がかかったときに、スクリプトが起動されることになります。
こんなかんじの plist (xxx.xxx.cpanetags.plist) を作成し、$HOME/Library/LaunchAgents に放りこんでおきます。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
        <key>Label</key>
        <string>xxx.xxx.cpanetags</string>
        <key>ProgramArguments</key>
        <array>
                <string>/Users/kiririmode/bin/cron2etags</string>
        </array>
	<key>RunAtLoad</key>
	<true/>
        <key>KeepAlive</key>
        <false/>
        <key>WatchPaths</key>
        <array>
                <string>/Users/kiririmode/.cpanm/build.log</string>
        </array>
</dict>
</plist>

更新スクリプト

更新はみてのとおりこんなかんじにしました。
perlbrew list で現在使用している Perl 実装が取得できるので、それを元にモジュールの絶対パスを組み立て、.pm の拡張子を持つ全ファイルに対して etags を走査させます。

perlbrew で alias 使っていないの前提なのが苦しいところなのですが、良い方法がおもい浮かびませんね。

#!/bin/bash
sleep 30

PERL5DIR=$HOME/perl5/perlbrew
PERL5BASHRC=$PERL5DIR/etc/bashrc

# read perlbrew function
. $PERL5BASHRC || exit 1

# perl5 module directory
PERL5MODDIR=$PERL5DIR/perls/$(perlbrew list | grep ^\* | cut -c3-)/lib

# create TAGS
TAGDIR=$HOME/.tags
TAGFILE=$TAGDIR/cpan.tags

[ -d $TAGDIR ] || mkdir -p $TAGDIR
rm -f $TAGFILE
find $PERL5MODDIR -name \*.pm | xargs etags --append --output $TAGFILE