File Coverage

blib/lib/Footprintless/Extract.pm
Criterion Covered Total %
statement 77 78 98.7
branch 21 30 70.0
condition 5 12 41.6
subroutine 12 12 100.0
pod 2 2 100.0
total 117 134 87.3


line stmt bran cond sub pod time code
1 3     3   493 use strict;
  3         6  
  3         83  
2 3     3   14 use warnings;
  3         4  
  3         143  
3              
4             package Footprintless::Extract;
5             $Footprintless::Extract::VERSION = '1.26';
6             # ABSTRACT: Extracts data from archives
7             # PODNAME: Footprintless::Extract
8             #
9 3     3   15 use Carp;
  3         5  
  3         172  
10 3     3   19 use Cwd;
  3         5  
  3         152  
11 3     3   13 use File::Path qw(make_path);
  3         6  
  3         123  
12 3     3   15 use File::Spec;
  3         5  
  3         62  
13 3     3   12 use Log::Any;
  3         4  
  3         23  
14              
15             my $logger = Log::Any->get_logger();
16              
17             sub new {
18 8     8 1 85 return bless( {}, shift )->_init(@_);
19             }
20              
21             sub extract {
22 8     8 1 30 my ( $self, %options ) = @_;
23 8   33     29 my $to = $options{to} || getcwd();
24              
25 8         84 my $current_dir = getcwd();
26 8         17 eval {
27 8 50 66     41 croak("$to is not a directory") if ( -e $to && !-d $to );
28 8         676 make_path($to);
29 8         132 chdir($to);
30              
31 8 100       76 if ( $self->{type} eq 'zip' ) {
32 6         23 _unzip( $self->{archive}, $to );
33             }
34 8 100       362 if ( $self->{type} eq 'tar' ) {
35 2         5 _untar( $self->{archive}, $to );
36             }
37             };
38 8         28363 my $error = $@;
39 8         85 chdir($current_dir);
40 8 50       35 die($error) if ($error);
41              
42 8         114 return 1;
43             }
44              
45             sub _init {
46 8     8   33 my ( $self, %options ) = @_;
47              
48 8 50       35 croak('archive required') unless ( $options{archive} );
49 8         54 $self->{archive} = $options{archive};
50              
51 8 100       24 my $dot_extension = $options{type} ? ".$options{type}" : $self->{archive};
52 8 100       44 if ( $dot_extension =~ /\.zip|\.war|\.jar|\.ear|\.twbx$/ ) {
    50          
53 6         74 $self->{type} = 'zip';
54             }
55             elsif ( $dot_extension =~ /\.tar|\.tar\.gz|\.tgz$/ ) {
56 2         6 $self->{type} = 'tar';
57             }
58             else {
59 0         0 croak("unknown archive type");
60             }
61              
62 8         39 return $self;
63             }
64              
65             sub _untar {
66 2     2   5 my ( $archive, $to ) = @_;
67 2         12 $logger->tracef( 'untar [%s] to [%s]', $archive, $to );
68 2         429 require Archive::Tar;
69 2         57823 Archive::Tar->new($archive)->extract();
70             }
71              
72             sub _unzip {
73 6     6   15 my ( $archive, $to ) = @_;
74 6         25 $logger->tracef( 'unzip [%s] to [%s]', $archive, $to );
75 6         1345 require IO::Uncompress::Unzip;
76              
77 6   33     89443 my $unzip = IO::Uncompress::Unzip->new($archive)
78             || croak("unable to open $archive: $IO::Uncompress::Unzip::UnzipError");
79              
80 6         7166 my $status;
81 6         16 eval {
82 6         20 for ( $status = 1; $status > 0; $status = $unzip->nextStream() ) {
83 54         29977 my $header = $unzip->getHeaderInfo();
84 54         855 my ( undef, $path, $name ) = File::Spec->splitpath( $header->{Name} );
85 54         322 my $dest_dir = File::Spec->catdir( $to, $path );
86              
87 54 100       1066 unless ( -d $dest_dir ) {
88 28 50       2857 make_path($dest_dir) || croak("unable to create dir $dest_dir: $!");
89             }
90              
91 54 100       165 unless ($name) {
92 28 50       65 last if ( $status < 0 );
93 28         129 next;
94             }
95              
96 26         181 my $dest_file = File::Spec->catfile( $dest_dir, $name );
97 26         57 my $buffer;
98 26   33     178 my $file = IO::File->new( $dest_file, "w" )
99             || croak("unable to create file $dest_file: $!");
100 26         2779 while ( ( $status = $unzip->read($buffer) ) > 0 ) {
101 26         18036 $file->write($buffer);
102             }
103 26         1126 $file->close();
104 26         761 my $stored_time = $header->{Time};
105 26 50       450 utime( $stored_time, $stored_time, $dest_file )
106             || croak("couldn't set utime on $dest_file: $!");
107             }
108 6 50       1332 croak("error processing $archive: $!") if ( $status < 0 );
109             };
110 6         15 my $error = $@;
111 6         40 $unzip->close();
112 6 50       224 die($error) if ($error);
113 6         36 return;
114             }
115              
116             1;
117              
118             __END__