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 = '1.001';
5 3     3   493733 use 5.006;
  3         13  
6 3     3   20 use strict;
  3         9  
  3         117  
7 3     3   24 use warnings;
  3         8  
  3         2723  
8              
9             sub new {
10             # hash or hash ref
11 8     8 1 764854 my $class = shift;
12              
13 8 50       64 my %args = (@_ == 1) ? %{$_[0]} : @_;
  0         0  
14              
15 8         1083 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         27 delete $args{tap};
20 8         17 delete $args{sources};
21 8         18 delete $args{exec};
22              
23 8         20 my %tap_dom_args = ();
24 8         30 foreach (@TAP::DOM::tap_dom_args) {
25 144 100       344 if (defined $args{$_}) {
26 5         15 $tap_dom_args{$_} = $args{$_};
27 5         14 delete $args{$_};
28             }
29             }
30              
31 8         34 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         213 map { TAP::DOM->new(tap => $_, %tap_dom_args) }
37 31         71 grep { defined $_ }
38 8         1046 @{$tap_documents->{tap}}
  8         36  
39             ],
40             };
41 8         659 return bless $tap_dom_list, $class;
42             }
43              
44             sub _read_tap_from_archive
45             {
46 8     8   26 my ($args, $tap_dom_args) = @_;
47              
48 8         1835 require Archive::Tar;
49 8         211928 require YAML::Tiny;
50 8         19988 require IO::String;
51 8         72 require IO::Zlib;
52 8         43 require Scalar::Util;
53              
54 8         49 my $content;
55 8 50 66     237 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         22 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         26 $content = do {
73 7         41 local $/;
74 7         42 my $F = Scalar::Util::openhandle($args->{source});
75 7 100       27 if (!defined $F) {
76 3 50       180 open $F, '<', $args->{source} or die 'Can not read '.$args->{source};
77             }
78             <$F>
79 7         389 };
80             }
81              
82             # some stacking to enable Archive::Tar read compressed in-memory string
83 7         92 my $TARSTR = IO::String->new($content);
84 7         543 my $TARZ = IO::Zlib->new($TARSTR, "rb");
85 7         17009 my $tar = Archive::Tar->new($TARZ);
86              
87 7         52693 my ($meta_yml) = grep { $tar->contains_file($_) } qw{meta.yml ./meta.yml};
  14         1513  
88 7         4464 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         54 my $f1 = $_; # original name as-is
93 30         50 my $f2 = $_; $f2 =~ s,^\./,,; # force no-leading-dot
  30         89  
94 30         62 my $f3 = $_; $f3 = "./$_"; # force leading-dot
  30         57  
95 30         54 local $Archive::Tar::WARN = 0;
96              
97 30         40 my $tap;
98 30 50       129 $tap = "# Bummer! No tar." unless defined $tar; # no error balloon hint
99 30 50       120 $tap = $tar->get_content($f1) unless defined $tap;
100 30 50       3543 $tap = $tar->get_content($f2) unless defined $tap;
101 30 50       127 $tap = $tar->get_content($f3) unless defined $tap;
102 30         98 $tap;
103 7         15213 } @{$meta->{file_order}};
  7         30  
104             return {
105 7         272 meta => $meta,
106             tap => \@tap_sections,
107             };
108             }
109              
110             1; # End of TAP::DOM::Archive
111              
112             __END__