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.97';
5 2     2   61639 use 5.006;
  2         13  
6 2     2   8 use strict;
  2         3  
  2         40  
7 2     2   8 use warnings;
  2         2  
  2         1057  
8              
9             sub new {
10             # hash or hash ref
11 7     7 1 14379 my $class = shift;
12              
13 7 50       36 my %args = (@_ == 1) ? %{$_[0]} : @_;
  0         0  
14              
15 7         488 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         8 delete $args{sources};
21 7         9 delete $args{exec};
22              
23 7         14 my %tap_dom_args = ();
24 7         18 foreach (@TAP::DOM::tap_dom_args) {
25 98 100       148 if (defined $args{$_}) {
26 4         9 $tap_dom_args{$_} = $args{$_};
27 4         5 delete $args{$_};
28             }
29             }
30              
31 7         41 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         100 map { TAP::DOM->new(tap => $_, %tap_dom_args) }
37 28         39 grep { defined $_ }
38 7         435 @{$tap_documents->{tap}}
  7         14  
39             ],
40             };
41 7         282 return bless $tap_dom_list, $class;
42             }
43              
44             sub _read_tap_from_archive
45             {
46 7     7   14 my ($args, $tap_dom_args) = @_;
47              
48 7         1146 require Archive::Tar;
49 7         139772 require YAML::Tiny;
50 7         8636 require IO::String;
51 7         19 require IO::Zlib;
52 7         20 require Scalar::Util;
53              
54 7         11 my $content;
55 7 50 66     87 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         14 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         11 $content = do {
73 6         21 local $/;
74 6         21 my $F = Scalar::Util::openhandle($args->{source});
75 6 100       15 if (!defined $F) {
76 2 50       66 open $F, '<', $args->{source} or die 'Can not read '.$args->{source};
77             }
78             <$F>
79 6         172 };
80             }
81              
82             # some stacking to enable Archive::Tar read compressed in-memory string
83 6         39 my $TARSTR = IO::String->new($content);
84 6         279 my $TARZ = IO::Zlib->new($TARSTR, "rb");
85 6         7746 my $tar = Archive::Tar->new($TARZ);
86              
87 6         24719 my ($meta_yml) = grep { $tar->contains_file($_) } qw{meta.yml ./meta.yml};
  12         789  
88 6         2558 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         29 my $f1 = $_; # original name as-is
93 27         69 my $f2 = $_; $f2 =~ s,^\./,,; # force no-leading-dot
  27         36  
94 27         31 my $f3 = $_; $f3 = "./$_"; # force leading-dot
  27         30  
95 27         29 local $Archive::Tar::WARN = 0;
96              
97 27         26 my $tap;
98 27 50       37 $tap = "# Bummer! No tar." unless defined $tar; # no error balloon hint
99 27 50       56 $tap = $tar->get_content($f1) unless defined $tap;
100 27 50       1929 $tap = $tar->get_content($f2) unless defined $tap;
101 27 50       39 $tap = $tar->get_content($f3) unless defined $tap;
102 27         49 $tap;
103 6         7450 } @{$meta->{file_order}};
  6         18  
104             return {
105 6         107 meta => $meta,
106             tap => \@tap_sections,
107             };
108             }
109              
110             1; # End of TAP::DOM::Archive
111              
112             __END__