CLI系でmyapp.ymlを取得

CLI系のプログラムからmyapp.ymlを読み込みたいってことは多分あると思うけど、みなさんはどうしてるんでしょうね。

僕の場合はとりあえずMyApp::CLI::ConfigLoaderみたいなのを作ってます。

package MyApp::CLI::ConfigLoader;
use strict;
use warnings;
use Catalyst::Utils();
use YAML;
use Path::Class();
use Data::Visitor::Callback;

our $VERSION = 0.02;

sub new {
    my $class = shift;
    bless {@_}, ref $class || $class;
}

sub get_config {
    my $self = shift;
    my $path = $self->get_path(shift);
    my $yaml = YAML::Load( scalar $path->slurp ) || {};
    local $self->{home} = $path->dir;
    $self->_visit($yaml);
    $yaml;
}

sub get_path {
    my $self = shift;
    my $path = shift;
    return $self->{path}   = Path::Class::File->new($path) if $path;
    return $self->{path} ||= Path::Class::File->new(Catalyst::Utils::home(ref $self),'myapp.yml');
}

sub _visit {
    my $self = shift;
    my $v = Data::Visitor::Callback->new(
        plain_value => sub {
            return unless defined $_;
            s{__HOME__}{ $self->_path_to( '' ) }e;
            s{__path_to\((.+)\)__}{ $self->_path_to( split( '/', $1 ) ) }e;
        }
    );
    $v->visit( shift || {} );
}

sub _path_to {
    my ( $self, @path ) = @_;
    my $path = Path::Class::Dir->new( $self->{home}, @path );
    if ( -d $path ) { return $path }
    else { return Path::Class::File->new( $self->{home}, @path ) }
}

1;


### main.pl

use MyApp::CLI::ConfigLoader;

my $config = MyApp::CLI::ConfigLoader->new->get_config;

これで例えばDBの接続情報なんかも

my $info = $config->{'Model::Schema'}->{connect_info};

みたいな感じで取れるので、便利。