Archive-Libarchive-Compress
view release on metacpan or search on metacpan
lib/Archive/Libarchive/Compress.pm view on Meta::CPAN
if defined($options{filename}) && defined($options{memory});
if(defined $options{memory} && !(is_plain_scalarref $options{memory} && defined $options{memory}->$* && !is_ref $options{memory}->$*)) {
Carp::croak("Option memory must be a scalar reference to a plain non-reference scalar");
}
Carp::croak("Entry is not a code reference")
if defined $options{entry} && !is_plain_coderef $options{entry};
my $self = bless {
filename => delete $options{filename},
entry => delete($options{entry}) // sub ($e) { return 1 },
memory => delete $options{memory},
prep => delete($options{prep}) // sub ($ar) { $ar->set_format_pax_restricted },
}, $class;
Carp::croak("Illegal options: @{[ sort keys %options ]}")
if %options;
return $self;
}
sub filename ($self) { return $self->{filename} }
sub from ($self) { return $self->{from} }
sub _archive ($self) {
my $w = Archive::Libarchive::ArchiveWrite->new;
my $e = Archive::Libarchive::Entry->new;
$self->{prep}->($w);
my $ret;
if($self->filename) {
$ret = $w->open_filename($self->filename);
} else {
$ret = $w->open_memory($self->{memory});
}
if($ret == ARCHIVE_WARN) {
Carp::carp($w->error_string);
} elsif($ret < ARCHIVE_WARN) {
Carp::croak($w->error_string);
}
return($w,$e);
}
sub _iterate ($self, $w, $e, $path) {
if(-d $path) {
foreach my $child (sort { $a->basename cmp $b->basename } $path->children) {
$self->_iterate($w, $e, $child);
}
} elsif(-f $path) {
$e->clear;
$e->set_pathname("$path");
$e->set_filetype('reg');
my $stat = FFI::C::Stat->new("$path");
$e->copy_stat($stat);
if($self->{entry}->($e)) {
my $ret = $w->write_header($e);
if($ret == ARCHIVE_WARN) {
Carp::carp($w->error_string);
} elsif($ret < ARCHIVE_WARN) {
Carp::croak($w->error_string);
}
$ret = $w->write_data(\$path->slurp_raw);
if($ret == ARCHIVE_WARN) {
Carp::carp($w->error_string);
} elsif($ret < ARCHIVE_WARN) {
Carp::croak($w->error_string);
}
}
}
}
sub compress ($self, %options) {
Carp::croak("Already compressed") if defined $self->from;
my $from = Path::Tiny->new($options{from} // $CWD);
my($w, $e) = $self->_archive;
local $CWD = $from;
$self->_iterate($w, $e, Path::Tiny->new("."));
$w->close;
}
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Archive::Libarchive::Compress - Recursively archive a directory (using libarchive)
=head1 VERSION
version 0.01
=head1 SYNOPSIS
use Archive::Libarchive::Compress;
my $w = Archive::Libarchive::Compress->new( filename => 'foo.tar' );
$w->compress( from => '.' );
( run in 1.702 second using v1.01-cache-2.11-cpan-97f6503c9c8 )