File Coverage

blib/lib/TAP/DOM/Archive.pm
Criterion Covered Total %
statement 61 63 96.8
branch 13 20 65.0
condition 2 3 66.6
subroutine 5 5 100.0
pod 1 1 100.0
total 82 92 89.1


line stmt bran cond sub pod time code
1             package TAP::DOM::Archive;
2             our $AUTHORITY = 'cpan:SCHWIGON';
3             # ABSTRACT: Handle TAP:Archive files
4             $TAP::DOM::Archive::VERSION = '0.95';
5 2     2   57523 use 5.006;
  2         16  
6 2     2   10 use strict;
  2         4  
  2         44  
7 2     2   9 use warnings;
  2         3  
  2         1103  
8              
9             sub new {
10             # hash or hash ref
11 7     7 1 16983 my $class = shift;
12              
13 7 50       48 my %args = (@_ == 1) ? %{$_[0]} : @_;
  0         0  
14              
15 7         543 require TAP::DOM;
16              
17             # Drop arguments which don't make sense here and would confuse
18             # TAP::Parser called via TAP::DOM later.
19 7         16 delete $args{tap};
20 7         14 delete $args{sources};
21 7         12 delete $args{exec};
22              
23 7         17 my %tap_dom_args = ();
24 7         21 foreach (@TAP::DOM::tap_dom_args) {
25 98 100       174 if (defined $args{$_}) {
26 4         9 $tap_dom_args{$_} = $args{$_};
27 4         9 delete $args{$_};
28             }
29             }
30              
31 7         63 my $tap_documents = _read_tap_from_archive(\%args, \%tap_dom_args);
32              
33             my $tap_dom_list = {
34             meta => $tap_documents->{meta},
35             dom => [
36 28         139 map { TAP::DOM->new(tap => $_, %tap_dom_args) }
37 28         43 grep { defined $_ }
38 7         606 @{$tap_documents->{tap}}
  7         20  
39             ],
40             };
41 7         415 return bless $tap_dom_list, $class;
42             }
43              
44             sub _read_tap_from_archive
45             {
46 7     7   18 my ($args, $tap_dom_args) = @_;
47              
48 7         1313 require Archive::Tar;
49 7         152890 require YAML::Tiny;
50 7         9601 require IO::String;
51 7         23 require IO::Zlib;
52 7         23 require Scalar::Util;
53              
54 7         16 my $content;
55 7 50 66     122 if ($args->{filecontent}) {
    100          
56 0         0 $content = $args->{filecontent};
57             } elsif (-z $args->{source} and $tap_dom_args->{noempty_tap}) {
58             return ({
59 1         17 meta => {
60             file_order => [ 't/error-tap-archive-was-empty.t' ],
61             file_attributes => [{
62             start_time => '1.0',
63             end_time => '2.0',
64             description => 't/error-tap-archive-was-empty.t'
65             }],
66             'start_time' => '1',
67             'stop_time' => '2',
68             },
69             tap => [ $TAP::DOM::noempty_tap ],
70             });
71             } else {
72 6         13 $content = do {
73 6         26 local $/;
74 6         26 my $F = Scalar::Util::openhandle($args->{source});
75 6 100       20 if (!defined $F) {
76 2 50       89 open $F, '<', $args->{source} or die 'Can not read '.$args->{source};
77             }
78             <$F>
79 6         222 };
80             }
81              
82             # some stacking to enable Archive::Tar read compressed in-memory string
83 6         53 my $TARSTR = IO::String->new($content);
84 6         345 my $TARZ = IO::Zlib->new($TARSTR, "rb");
85 6         9515 my $tar = Archive::Tar->new($TARZ);
86              
87 6         27795 my ($meta_yml) = grep { $tar->contains_file($_) } qw{meta.yml ./meta.yml};
  12         908  
88 6         3089 my $meta = YAML::Tiny::Load($tar->get_content($meta_yml));
89              
90             my @tap_sections = map {
91             # try different variants of filenames that meta.yml gave us
92 27         32 my $f1 = $_; # original name as-is
93 27         33 my $f2 = $_; $f2 =~ s,^\./,,; # force no-leading-dot
  27         39  
94 27         55 my $f3 = $_; $f3 = "./$_"; # force leading-dot
  27         47  
95 27         33 local $Archive::Tar::WARN = 0;
96              
97 27         31 my $tap;
98 27 50       51 $tap = "# Bummer! No tar." unless defined $tar; # no error balloon hint
99 27 50       65 $tap = $tar->get_content($f1) unless defined $tap;
100 27 50       2171 $tap = $tar->get_content($f2) unless defined $tap;
101 27 50       37 $tap = $tar->get_content($f3) unless defined $tap;
102 27         61 $tap;
103 6         8250 } @{$meta->{file_order}};
  6         22  
104             return {
105 6         165 meta => $meta,
106             tap => \@tap_sections,
107             };
108             }
109              
110             1; # End of TAP::DOM::Archive
111              
112             __END__