カラクリスタ

『輝かしい青春』なんて失かったヒトのブログ

設定ファイルをPerlとmakeとSubversionを使って管理する:複数環境対応編

概要: 複数の環境の設定ファイルを Perl + make + Subversionで管理する


えーっと、前回三月の月末に設定ファイルをPerlとmakeとSubversionを使って管理する という記事を書いたわけですが、この記事を書いた段階では、Makefileを生成するMakefile.PLは複数の環境に対応していませんでした。

で、前にVMware上のUbuntuからCygwinに環境を移した際にいい加減なまま放置していた設定ファイルの管理を今回やり直したときに、 環境固有の設定と複数の環境共有の設定を分けたい!ということで、 前回書いたMakefile.PLを複数の環境に対応できるように改良してみました。

で、以下改良したMakefile.PL

#!perl

use strict;
use warnings;

use File::Find;
use FindBin ();
use POSIX qw( uname );

my $source      = $FindBin::Bin;
my $username    = $ENV{'USER'} || $ENV{'USERNAME'} || 'default' ;
my $machine     = [uname]->[1];

my %files;

for my $root ( 'share', "${username}\@${machine}" ) {
    my $parent = "${source}/${root}";
    find(
        sub {
            my $path = $File::Find::name;

            return if ( -d $path );

            if ( $path =~ m{^$parent/(.+)$} ) {
                my $filename = $1;

                return if ( $filename eq 'Makefile.PL' );
                return if ( $filename eq 'Makefile' );
                return if ( $filename =~ m{~$} );

                $files{$filename} = $path;
            }
        },
        $parent,
    );
}

my $makefile;

   $makefile .= qq{TARGETS = };
   $makefile .= join( qq{ \\\n\t}, map { "/$_" } keys %files );
   $makefile .= qq{\n\n};

   $makefile .= qq{INSTALL = sudo /usr/bin/install -o root -m 0644\n\n};
   $makefile .=  q{all: ${TARGETS}} . qq{\n\n};

for my $filename ( sort keys %files ) {
    my $path = $files{$filename};
    $makefile .= qq{/${filename}: ${path}\n};
    $makefile .= qq{\t} . q{${INSTALL} $? $@} . qq{\n\n};
}

if ( open( my $fh, '>', 'Makefile' ) ) {
    print $fh $makefile;
    close($fh);
}

改良点としては、前回のMakefile.PLは実行したディレクトリをrootと見立ててファイルを配置するMakefileを生成していましたが、 今回はshare{username}@{hostname}をルートと見立てるようにしました。

どういうことかって言うと、前は

~/config
    Makefile.PL     # Makefile.PL
    home/
        nyarla/
            .zshrc  # /home/nyarla/.zshrcに配置される

という感じだったのが、今回は

~/config
    Makefile.PL             # Makefile.PL
    share/                  # 複数の環境で共有の設定ファイル
        home/
            nyarla/
                .zshrc      # /home/nyarla/.zshrcに配置される
    {username}@{hostname}/  # 環境固有の設定ファイル
        home/
            nyarla/
                .zshenv     # /home/nyarla/.zshenvに配置される

という感じになります。

で、{username}はログインユーザー名、{hostname}はマシンのホスト名に対応してます。 あと{username}@{hostname}ディレクトリとshareディレクトリに同じパスのファイルがあった場合、 {username}@{hostname}ディレクトリ以下のファイルが優先されます。

でまあ使い方は前回のスクリプトと同じで、

$ perl Makefile.PL

してから、

$ make

するだけでOKです。

ちなみに僕が実際の環境で使用しているMakefile.PLsudoを使わないようになってます。(Cygwinにsudoがないからね)

でまあ、僕が使ってる実際の設定ファイルでは、共有の設定ファイルから環境固有の設定ファイルを読み込む、 みたいな感じの処理をしてたりします。

例を上げると~/.zshrcでは

# global な設定

PROMPT="%(!.#.$) "
RPROMPT='[%~]'

# local な設定
sourcefile=~/.zsh.d/${USER}@`uname -n`/.zshrc
if [ -r $sourcefile ] ; then;
    source $sourcefile;
fi;

という感じです。

まあでも設定ファイルをincludeできない場合のアプリケーションだと、ちょっと困ったことになりそうな予感ですが。 まあ今のところは困ってないので、その辺り放置です><

まあ今回の改良で複数の環境の設定ファイルをまとめて管理できるようになったので、 良かったら使ってみてください。