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.98';
5 2     2   66095 use 5.006;
  2         16  
6 2     2   10 use strict;
  2         4  
  2         53  
7 2     2   11 use warnings;
  2         5  
  2         1366  
8              
9             sub new {
10             # hash or hash ref
11 8     8 1 25608 my $class = shift;
12              
13 8 50       55 my %args = (@_ == 1) ? %{$_[0]} : @_;
  0         0  
14              
15 8         606 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 8         23 delete $args{tap};
20 8         17 delete $args{sources};
21 8         15 delete $args{exec};
22              
23 8         19 my %tap_dom_args = ();
24 8         26 foreach (@TAP::DOM::tap_dom_args) {
25 112 100       227 if (defined $args{$_}) {
26 5         14 $tap_dom_args{$_} = $args{$_};
27 5         11 delete $args{$_};
28             }
29             }
30              
31 8         53 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 31         149 map { TAP::DOM->new(tap => $_, %tap_dom_args) }
37 31         64 grep { defined $_ }
38 8         728 @{$tap_documents->{tap}}
  8         24  
39             ],
40             };
41 8         470 return bless $tap_dom_list, $class;
42             }
43              
44             sub _read_tap_from_archive
45             {
46 8     8   23 my ($args, $tap_dom_args) = @_;
47              
48 8         1496 require Archive::Tar;
49 8         179652 require YAML::Tiny;
50 8         11351 require IO::String;
51 8         28 require IO::Zlib;
52 8         29 require Scalar::Util;
53              
54 8         16 my $content;
55 8 50 66     149 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 7         17 $content = do {
73 7         33 local $/;
74 7         34 my $F = Scalar::Util::openhandle($args->{source});
75 7 100       24 if (!defined $F) {
76 3 50       147 open $F, '<', $args->{source} or die 'Can not read '.$args->{source};
77             }
78             <$F>
79 7         288 };
80             }
81              
82             # some stacking to enable Archive::Tar read compressed in-memory string
83 7         63 my $TARSTR = IO::String->new($content);
84 7         414 my $TARZ = IO::Zlib->new($TARSTR, "rb");
85 7         13324 my $tar = Archive::Tar->new($TARZ);
86              
87 7         38474 my ($meta_yml) = grep { $tar->contains_file($_) } qw{meta.yml ./meta.yml};
  14         1205  
88 7         3971 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 30         43 my $f1 = $_; # original name as-is
93 30         38 my $f2 = $_; $f2 =~ s,^\./,,; # force no-leading-dot
  30         61  
94 30         40 my $f3 = $_; $f3 = "./$_"; # force leading-dot
  30         54  
95 30         43 local $Archive::Tar::WARN = 0;
96              
97 30         39 my $tap;
98 30 50       72 $tap = "# Bummer! No tar." unless defined $tar; # no error balloon hint
99 30 50       92 $tap = $tar->get_content($f1) unless defined $tap;
100 30 50       2897 $tap = $tar->get_content($f2) unless defined $tap;
101 30 50       57 $tap = $tar->get_content($f3) unless defined $tap;
102 30         77 $tap;
103 7         10851 } @{$meta->{file_order}};
  7         33  
104             return {
105 7         187 meta => $meta,
106             tap => \@tap_sections,
107             };
108             }
109              
110             1; # End of TAP::DOM::Archive
111              
112             __END__