プロジェクトのルートディレクトリを探す

2009-04-29 02:27
File tree

ある Perl のプロジェクトで、.t ファイルの冒頭で @INC をいじっているものがあった。曰く

% ls
Changes         MANIFEST        MANIFEST.SKIP   Makefile.PL     lib/            t/
% cd t
% prove header.t

みたいに cwd (current working directory) を考えずにテストを実行したい、というはなしらしい。

たしかに便利そうだけど、個々の .t に書いていくのは嫌なので、こんなものを project-root という名前で $PATH が通ったところに置いてみた。

#! /usr/bin/env perl
use strict;
use warnings;
use Cwd;

my @BASENAMES = qw(.hg .git t);

sub project_root {
    my ($absolute) = @_;

    for (my @list = split '/', $absolute; @list; pop @list) {
        my $result = join '/', @list;
        for (@BASENAMES) {
            if (-e "$result/$_") {
                return $result;
            }
        }
    }
    return;
}

my $path = project_root(cwd());
if ($path) {
    print "$path\n";
} else {
    exit(1);
}

先の例だと、こう使える。

% cd t
% prove -I `project-root`/lib header.t

どこがプロジェクトのルートか、という判断方法はかなり発見的で

  • .hg (Mercurial)
  • .git (Git)
  • t (Perl のテストを置くデファクトスタンダード)

のどれかを探しているだけだ。Subversion で管理された Java のプロジェクトとかだと、また @BASENAMES をいじる必要がある。

ごく小さいスクリプトだけど、cd ../../ のかわりに cd `project-root` とか、エディタのなかから chdir `project-root` && prove -l t/ とか、わりと使い道はあるんじゃないかと思います。

Leave a Reply