Senna用パッチ付きlibmecabを自動インストールするスクリプト

| コメント(0) | トラックバック(0)

多分なんらかしらの形でsennaのディストリビューションに入れてもらおうとは思ってるんだけど、とりあえず公開しておくですよ。なるたけモジュール使わないようにするのが大変。一応誰でも持ってそうなヤツだけ使ってやってみた。

パッチ歓迎。

#!perl
use strict;

BEGIN {
    eval <<'    EOM';
        use Cwd;
        use File::Spec;
        use Getopt::Long;
        use LWP::UserAgent();
    EOM
    if ($@) {
        print STDERR <<"        EOM";
Failed to load necessary Perl module to build mte-enabled libmecab.
(Most likely you do not have the necessary modules. You're going to
 have to install them)

The error was:
  $@
        EOM
        exit 1;
    }
}

use constant DEFAULT_MECAB_URI =>
    "http://chasen.org/~taku/software/mecab/src/mecab-0.81.tar.gz";
use constant DEFAULT_MECAB_PATCH_URI =>
    "http://dev.razil.jp/archive/mecab-0.81.mte.patch.20050423";
use constant DEFAULT_IPADIC_URI =>
    "http://chasen.naist.jp/stable/ipadic/ipadic-2.5.1.tar.gz";

sub main
{
    my %opts;

    my %optspec = (
        'mecab-uri|mecab_uri=s', # location of mecab
        'mecab-pacth-uri|mecab_patch=s',
        'mecab-configure-args|mecab_configure_args=s',
        'ipadic-uri|ipadic_uri=s'
    );
    GetOptions(\%opts, %optspec);

    $opts{mecab_uri}  ||= DEFAULT_MECAB_URI;
    $opts{patch_uri}  ||= DEFAULT_MECAB_PATCH_URI;
    $opts{ipadic_uri} ||= DEFAULT_IPADIC_URI;

    $opts{root_dir} = File::Spec->tmpdir;

    my @path          = split(/:/, $ENV{PATH});
    $opts{tar_cmd}    = find_cmd('tar', @path);
    $opts{gunzip_cmd} = find_cmd('gunzip', @path);
    $opts{patch_cmd}  = find_cmd('patch', @path);
    $opts{rm_cmd}     = find_cmd('rm', @path);

    my $ua     = LWP::UserAgent->new;
    my $mecab  = dl_temp($ua, $opts{mecab_uri}, %opts);
    my $patch  = dl_temp($ua, $opts{patch_uri}, %opts);
    my $ipadic = dl_temp($ua, $opts{ipadic_uri}, %opts);

    $opts{mecab_dir} = File::Spec->catdir($opts{root_dir}, (split(/\//, $opts{mecab_uri}))[-1]);
    $opts{mecab_dir} =~ s/\.tar\.gz$//;

    tar_gunzip($mecab, $opts{root_dir}, %opts);
    patch($patch, $opts{mecab_dir}, %opts);
    tar_gunzip($ipadic, File::Spec->catdir($opts{mecab_dir}, 'dic'), %opts);

    my $o_dir = cwd();
    chdir $opts{mecab_dir};
    exec_cmd("./configure $opts{mecab_configure_args}; make; make install");
    chdir $o_dir;

    unlink($mecab, $patch, $ipadic);
    exec_cmd("$opts{rm_cmd} -rf $opts{mecab_dir}");
}

sub find_cmd
{
    my $cmd = shift;
    my @locations = @_;

    my $path;
    foreach my $loc (@locations) {
        $path = File::Spec->catfile($loc, $cmd);
        if (-X $path) {
            return $path;
        }
    }

    while (1) {
        print "Path to your $cmd executable? ";

        $path = <STDIN>;
        chomp($path);

        if (-X $path) {
            return $path;
        }

        print << "        EOM";
'$path' doesn't seem to be an executable file.
        EOM
    }
}

sub dl_temp
{
    my $ua  = shift;
    my $uri = shift;

    my $file = File::Spec->catdir(File::Spec->tmpdir, (split(/\//, $uri))[-1]);
    print " + Downloading $uri to $file...\n";
    my $res = $ua->mirror($uri, $file);
    if ($res->is_error) {
        print STDERR <<"        EOM";
Failed to download $uri. Returned HTTP message follows.

        EOM
        print $res->as_string;

        exit 1;
    }

    return $file;
}

sub exec_cmd
{
    my $cmd = shift;
    my %opts = @_;

    if (system($cmd) != 0) {
        die "Failed to execute $cmd: $!";
    }
}

sub tar_gunzip
{
    my $file = shift;
    my $path = shift;
    my %opts = @_;

    my $o_dir = cwd();
    chdir $path;

    my $cmd = "$opts{gunzip_cmd} < $file | $opts{tar_cmd} xvf -";
    exec_cmd($cmd, %opts);
    chdir $o_dir;
}

sub patch
{
    my $file = shift;
    my $path = shift;
    my %opts = @_;

    my $o_dir = cwd();
    chdir File::Spec->catdir($path, File::Spec->updir);

    my $cmd = "$opts{patch_cmd} -p0 < $file";
    exec_cmd($cmd, %opts);
    chdir $o_dir;
}

main();

Author

Daisuke Maki (a.k.a lestrrat): Perl hacker, Director of Japan Perl Association, YAPC::Asia Tokyo Organizer (2009-2012), Fluent in Japanese, English. Ex-Brazilian (sorta)

#perl #c #ruby #java #mysql #english #japanese #opensource #stf #cooking #scotch #cigar


このエントリーをはてなブックマ
ークに追加

翔泳社よりモダンPerl入門(2010)を出版させていただいております。できれば内容をアップデートしたいので是非皆様・・・現在の在庫処理にお力をお貸しください!><

月別アーカイブ