Beam-Make
view release on metacpan or search on metacpan
lib/Beam/Make/Cache.pm view on Meta::CPAN
use File::stat;
use Time::Piece;
use Scalar::Util qw( blessed );
use YAML ();
#pod =attr file
#pod
#pod The path to a file to use for the cache. Defaults to C<.Beamfile.cache> in
#pod the current directory.
#pod
#pod =cut
has file => ( is => 'ro', default => sub { '.Beamfile.cache' } );
has _last_read => ( is => 'rw', default => 0 );
has _cache => ( is => 'rw', default => sub { {} } );
#pod =method set
#pod
#pod $cache->set( $name, $hash, $time );
#pod
#pod # Update modified time to now
#pod $cache->set( $name, $hash );
#pod
#pod Set an entry in the cache. C<$name> is the recipe name. C<$hash> is an identifier
#pod for the content (usually a base64 SHA-1 hash from L<Digest::SHA>). C<$time> is a
#pod L<Time::Piece> object to save as the last modified time. If C<$time> is not provided,
#pod defaults to now.
#pod
#pod =cut
sub set( $self, $name, $hash, $time=Time::Piece->new ) {
my $cache = $self->_fetch_cache;
$cache->{ $name } = {
hash => $hash,
time => blessed $time eq 'Time::Piece' ? $time->epoch : $time,
};
$self->_write_cache( $cache );
}
#pod =method last_modified
#pod
#pod my $time = $cache->last_modified( $name, $hash );
#pod
#pod Get the last modified timestamp (as a L<Time::Piece> object) for the
#pod given recipe C<$name>. If the C<$hash> does not match what was given to
#pod L</set>, or if the recipe has never been made, returns C<0>.
#pod
#pod =cut
sub last_modified( $self, $name, $hash ) {
my $cache = $self->_fetch_cache;
return Time::Piece->new( $cache->{ $name }{ time } )
if $cache->{ $name }
&& $cache->{ $name }{ hash } eq $hash
;
return 0;
}
sub _fetch_cache( $self ) {
my $last_read = $self->_last_read;
if ( -e $self->file && ( !$last_read || stat( $self->file )->mtime > $last_read ) ) {
$self->_last_read( stat( $self->file )->mtime );
$self->_cache( YAML::LoadFile( $self->file ) );
}
return $self->_cache;
}
sub _write_cache( $self, $cache ) {
my $old_cache = $self->_fetch_cache;
$cache = { %$old_cache, %$cache };
YAML::DumpFile( $self->file, $cache );
$self->_cache( $cache );
$self->_last_read( stat( $self->file )->mtime );
return;
}
1;
__END__
=pod
=head1 NAME
Beam::Make::Cache - Store information about recipes performed
=head1 VERSION
version 0.003
=head1 SYNOPSIS
my $cache = Beam::Make::Cache->new;
# Update the cache and track what the content should be
$cache->set( 'recipe', 'content hash' );
# Set the last modified time to a specific time by passing
# a Time::Piece object
$cache->set( 'recipe', 'content hash', $timestamp );
# Get a Time::Piece object if the content hashes match
# Otherwise returns 0
my $time = $cache->last_modified( 'recipe', 'content hash' );
=head1 DESCRIPTION
This class provides an API to access timestamps and content hashes to validate
recipes and determine which recipes are out-of-date and should be re-run.
=head2 Limitations
The cache file cannot be accessed by more than one process. This limitation may
be fixed in the future. Other cache modules that use distributed databases may
also be created in the future.
=head1 ATTRIBUTES
=head2 file
The path to a file to use for the cache. Defaults to C<.Beamfile.cache> in
the current directory.
=head1 METHODS
=head2 set
$cache->set( $name, $hash, $time );
# Update modified time to now
$cache->set( $name, $hash );
Set an entry in the cache. C<$name> is the recipe name. C<$hash> is an identifier
( run in 1.525 second using v1.01-cache-2.11-cpan-99c4e6809bf )