/usr/local/CPAN/VCI/VCI/VCS/Cvs/Directory.pm
package VCI::VCS::Cvs::Directory;
use Moose;
extends 'VCI::Abstract::Directory';
use File::Path qw(mkpath);
use List::Util qw(maxstr);
use Path::Abstract::Underload;
has 'x_cvs_dir' => (is => 'ro', isa => 'Str', lazy_build => 1);
sub _build_revision { 'HEAD' }
sub _build_revno { shift->revision }
# XXX This should be optimized.
sub _build_time {
my $self = shift;
my @files = grep($_->isa('VCI::Abstract::File'), @{$self->contents});
my @times = map { $_->time } @files;
return maxstr(@times) || 0;
}
# XXX Currently this may not return things with the proper revision.
sub _build_contents {
my $self = shift;
my $output = $self->vci->x_do(
args => ['-n', 'update', '-d'],
fromdir => $self->x_cvs_dir);
my @lines = split("\n", $output);
my @contents;
foreach my $line (@lines) {
next if $line =~ /^cvs update: Updating \.$/;
if ($line =~ /^U (.*)$/) {
my $path = Path::Abstract::Underload->new($self->path, $1);
push(@contents, $self->file_class->new(
path => $path, project => $self->project,
parent => $self));
}
elsif ($line =~ /New directory .(.+). -- ignored$/) {
my $path = Path::Abstract::Underload->new($self->path, $1);
push(@contents, $self->directory_class->new(
path => $path, project => $self->project,
parent => $self));
}
else {
warn "Unparseable line during contents: $line";
}
}
return \@contents;
}
# CVS doesn't really support listing files and directories from a remote
# connection. However, we can trick it into doing so with fake "CVS" dirs.
sub _build_x_cvs_dir {
my $self = shift;
my $dir = Path::Abstract::Underload->new($self->project->x_tmp, $self->path);
my $cvsdir = Path::Abstract::Underload->new($dir, 'CVS')->stringify;
if (!-d $cvsdir) {
mkpath($cvsdir);
open(my $root, ">$cvsdir/Root")
|| confess "Failed to open $cvsdir/Root: $!";
print $root $self->repository->root;
close($root);
my $repo_name = $self->project->name . '/' . $self->path->stringify;
# For local repos, you have to specify the full absolute path.
if ($self->repository->x_is_local) {
$repo_name = $self->repository->x_dir_part . '/' . $repo_name;
}
open(my $repository, ">$cvsdir/Repository")
|| confess "Failed to open $cvsdir/Repository: $!";
print $repository $repo_name;
close($repository);
# Create a blank Entries file, or CVS complains.
open(my $entries, ">$cvsdir/Entries")
|| confess "Failed to create $cvsdir/Entries: $!";;
close($entries);
}
return $dir->stringify;
}
sub DEMOLISH {
my $self = shift;
File::Path::rmtree($self->x_cvs_dir) if defined $self->{x_cvs_dir};
}
__PACKAGE__->meta->make_immutable;
1;