Alien-Build
view release on metacpan or search on metacpan
lib/Alien/Build/Interpolate.pm view on Meta::CPAN
package Alien::Build::Interpolate;
use strict;
use warnings;
use 5.008004;
# ABSTRACT: Advanced interpolation engine for Alien builds
our $VERSION = '2.84'; # VERSION
sub new
{
my($class) = @_;
my $self = bless {
helper => {},
classes => {},
}, $class;
$self;
}
sub add_helper
{
my $self = shift;
my $name = shift;
my $code = shift;
if(defined $self->{helper}->{$name})
{
require Carp;
Carp::croak("duplicate implementation for interpolated key $name");
}
my $require;
if(ref $_[0] eq 'CODE')
{
$require = shift;
}
else
{
$require = [];
while(@_)
{
my $module = shift;
my $version = shift;
$version ||= 0;
push @$require, $module => $version;
}
}
$self->{helper}->{$name} = Alien::Build::Helper->new(
$name,
$code,
$require,
);
}
sub replace_helper
{
my $self = shift;
my($name) = @_;
delete $self->{helper}->{$name};
$self->add_helper(@_);
}
sub has_helper
{
my($self, $name) = @_;
return unless defined $self->{helper}->{$name};
lib/Alien/Build/Interpolate.pm view on Meta::CPAN
sub _get_prop
{
my($name, $prop, $orig) = @_;
$name =~ s/^\./alien./;
if($name =~ /^(.*?)\.(.*)$/)
{
my($key,$rest) = ($1,$2);
return _get_prop($rest, $prop->{$key}, $orig);
}
elsif(exists $prop->{$name})
{
return $prop->{$name};
}
else
{
require Carp;
Carp::croak("No property $orig is defined");
}
}
sub interpolate
{
my($self, $string, $build) = @_;
my $prop = defined $build && eval { $build->isa('Alien::Build') }
? $build->_command_prop
: {};
$string =~ s{(?<!\%)\%\{([a-zA-Z_][a-zA-Z_0-9]+)\}}{$self->execute_helper($1)}eg;
$string =~ s{(?<!\%)\%\{([a-zA-Z_\.][a-zA-Z_0-9\.]+)\}}{_get_prop($1,$prop,$1)}eg;
$string =~ s/\%(?=\%)//g;
$string;
}
sub requires
{
my($self, $string) = @_;
map {
my $helper = $self->{helper}->{$_};
$helper ? $helper->require : ();
} $string =~ m{(?<!\%)\%\{([a-zA-Z_][a-zA-Z_0-9]+)\}}g;
}
sub clone
{
my($self) = @_;
require Storable;
my %helper;
foreach my $name (keys %{ $self->{helper} })
{
$helper{$name} = $self->{helper}->{$name}->clone;
}
my $new = bless {
helper => \%helper,
classes => Storable::dclone($self->{classes}),
}, ref $self;
}
package Alien::Build::Helper;
sub new
{
my($class, $name, $code, $require) = @_;
bless {
name => $name,
code => $code,
require => $require,
}, $class;
}
sub name { shift->{name} }
sub code
{
my($self, $code) = @_;
$self->{code} = $code if $code;
$self->{code};
}
sub require
{
my($self) = @_;
if(ref $self->{require} eq 'CODE')
{
$self->{require} = [ $self->{require}->($self) ];
}
@{ $self->{require} };
}
sub clone
{
my($self) = @_;
my $class = ref $self;
$class->new(
$self->name,
$self->code,
[ $self->require ],
);
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Alien::Build::Interpolate - Advanced interpolation engine for Alien builds
=head1 VERSION
version 2.84
=head1 CONSTRUCTOR
=head2 new
my $intr = Alien::Build::Interpolate->new;
=head2 add_helper
( run in 1.050 second using v1.01-cache-2.11-cpan-9bca49b1385 )