use strict;
use Digest;
for my $ii (qw/fingerprint_digest fingerprint_digester/) {
no strict 'refs';
*$ii = sub {
my $self = shift;
return $self->stash->{$ii} unless @_;
return $self->stash->{$ii} = shift;
};
}
sub signature {
return "collect";
}
my %default = (qw/
skip_single 0
skip_if_exists 0
skip_inline 1
check_content 0
fingerprint_digest 1
check_age 1
/,
);
sub new {
my $class = shift;
my $self = $class->SUPER::new(@_);
local %_ = @_;
while (my ($setting, $value) = each %default) {
$self->cfg->{$setting} = exists $_{$setting} ? $_{$setting} : $value;
}
return $self;
}
sub pre {
my $self = shift;
$self->SUPER::pre(@_);
return 0 if $self->skip_if_exists;
if ($self->cfg->{fingerprint_digest}) {
$self->fingerprint_digester(File::Assets::Util->digest);
}
return 1;
}
sub process {
my $self = shift;
$self->SUPER::process(@_);
if (my $digester = $self->fingerprint_digester) {
my $asset = $_[0];
$digester->add($asset->digest."\n");
}
}
sub post {
my $self = shift;
$self->SUPER::post(@_);
my $matched = $self->matched;
return unless @$matched;
return if $self->cfg->{skip_single} && 1 == @$matched;
if (my $digester = $self->fingerprint_digester) {
$self->fingerprint_digest($digester->hexdigest);
}
return if $self->skip_if_exists;
my $build = $self->should_build;
if ($build) {
$self->build;
}
$self->substitute;
}
sub skip_if_exists {
my $self = shift;
if ($self->cfg->{skip_if_exists} && $self->asset) {
if (-e $self->asset->file && -s _) {
$self->replace;
return 1;
}
}
return 0;
}
sub should_build {
my $self = shift;
# if ($self->cfg->{check_content}) {
# my $digest = $self->fingerprint_digest;
# my $dir = $self->group->rsc->dir->subdir(".check-content-digest");
# my $file = $dir->file($digest);
# unless (-e $file) {
# $file->touch;
# return 1;
# }
# $file->touch;
# }
if ($self->cfg->{check_age}) {
my $mtime = $self->mtime;
return 1 if $mtime > $self->output_asset->file_mtime;
}
# if ($self->cfg->{check_digest}) {
# my $file = $self->check_digest_file;
# unless (-e $file) {
# return 1;
# }
# }
return 0;
}
sub match {
my $self = shift;
my $asset = shift;
my $match = shift;
return $self->SUPER::match($asset, $match &&
(! $asset->inline || ! $self->cfg->{skip_inline}) &&
(! $asset->outside)
);
}
#sub check_digest_file {
# my $self = shift;
# my $key_digest = $self->key_digest;
# my $dir = $self->assets->rsc->dir->subdir(".check-digest");
# $dir->mkpath unless -d $dir;
# my $file = $dir->file($key_digest);
# return $file;
#}
sub build {
my $self = shift;
my $content = $self->build_content;
my $output_asset = $self->output_asset;
$output_asset->write($content) if defined $content;
return $output_asset;
}
sub output_asset {
my $self = shift;
return $self->stash->{output_asset} ||= do {
$self->assets->output_asset($self);
};
}
sub substitute {
my $self = shift;
my $asset = shift || $self->output_asset;
my $slice = $self->slice;
my $matched = $self->matched;
my $top_match = $matched->[0];
my $top_asset = $top_match->{asset};
for my $match (reverse @$matched) {
my $rank = $match->{rank};
splice @$slice, $rank, 1, ();
}
splice @$slice, $top_match->{rank}, 0, $asset;
}
sub fingerprint {
return $_[0]->fingerprint_digest;
}
1;
__END__
sub find_type {
my $self = shift;
my $frob;
return $frob if $frob = $self->type;
return $frob if (($frob = $self->matched->[0]) && ($frob = $frob->{asset}->type));
return undef;
}