File Coverage

blib/lib/OPM/Maker/Command/index.pm
Criterion Covered Total %
statement 94 95 98.9
branch 16 18 88.8
condition 11 11 100.0
subroutine 16 16 100.0
pod 4 4 100.0
total 141 144 97.9


line stmt bran cond sub pod time code
1             package OPM::Maker::Command::index;
2             $OPM::Maker::Command::index::VERSION = '1.16';
3 21     21   16859 use strict;
  21         49  
  21         1866  
4 21     21   132 use warnings;
  21         47  
  21         734  
5              
6             # ABSTRACT: Build index for an OPM repository
7              
8 21     21   1225 use Carp qw(croak);
  21         1361  
  21         1324  
9 21     21   1312 use File::Basename;
  21         1220  
  21         1469  
10 21     21   4008 use File::Find::Rule;
  21         62998  
  21         198  
11 21     21   5671 use MIME::Base64 ();
  21         5747  
  21         477  
12 21     21   3422 use Sys::Hostname;
  21         7999  
  21         1098  
13 21     21   3545 use Path::Class ();
  21         204093  
  21         735  
14 21     21   5937 use XML::LibXML;
  21         329795  
  21         139  
15 21     21   15735 use XML::LibXML::PrettyPrint;
  21         170906  
  21         270  
16              
17 21     21   6688 use OPM::Maker -command;
  21         59  
  21         215  
18 21     21   88360 use OPM::Maker::Utils qw(reformat_size);
  21         52  
  21         18203  
19              
20             sub abstract {
21 1     1 1 4005 return "build index for an OPM repository";
22             }
23              
24             sub usage_desc {
25 1     1 1 1048 return "opmbuild index ";
26             }
27              
28             sub validate_args {
29 7     7 1 7684 my ($self, $opt, $args) = @_;
30            
31 7 100 100     107 $self->usage_error( 'need path to directory that contains opm files' ) if
      100        
      100        
32             !$args ||
33             'ARRAY' ne ref $args ||
34             !$args->[0] ||
35             !-d $args->[0];
36             }
37              
38             sub execute {
39 11     11 1 14485 my ($self, $opt, $args) = @_;
40            
41 11         32 my $dir = $args->[0];
42            
43 11         421 my @opm_files = File::Find::Rule->file->name( '*.opm' )->in( $dir );
44            
45 11         12102 my @packages;
46 11         159 my $pp = XML::LibXML::PrettyPrint->new(
47             indent_string => ' ',
48             element => {
49             compact => [qw(
50             Vendor Name Description Version Framework
51             ModuleRequired PackageRequired URL License
52             File
53             )],
54             },
55             );
56              
57 11         345 my $root_name;
58            
59 11         62 for my $opm_file ( sort @opm_files ) {
60 16         774 my $size = -s $opm_file;
61 16         57 my %opts;
62              
63 16 50       75 if ( !$ENV{OPM_UNSECURE} ) {
64 16         84 %opts = (
65             no_network => 1,
66             expand_entities => 0,
67             );
68             }
69              
70             # if file is big, but not "too big"
71 16         30 my $max_size = 31_457_280;
72 16 100       56 if ( $ENV{OPM_MAX_SIZE} ) {
73 11         56 $max_size = reformat_size( $ENV{OPM_MAX_SIZE} );
74             }
75              
76 16 100       63 if ( $size > $max_size ) {
77 3         464 croak "$opm_file too big (max size: $max_size bytes)";
78             }
79              
80 13 50       42 if ( $size > 10_000_000 ) {
81 0         0 $opts{huge} = 1;
82             }
83              
84 13         115 my $parser = XML::LibXML->new( %opts );
85 13         1386 my $tree = $parser->parse_file( $opm_file );
86            
87 13         6773 $tree->setStandalone( 0 );
88            
89 13         69 my $root_elem = $tree->getDocumentElement;
90 13         107 $root_name = $root_elem->nodeName();
91 13         86 $root_elem->setNodeName( 'Package' );
92 13         74 $root_elem->removeAttribute( 'version' );
93            
94             # retrieve file information
95 13         65 my @files = $root_elem->findnodes( 'Filelist/File' );
96            
97             FILE:
98 13         626 for my $file ( @files ) {
99 26         220 my $location = $file->findvalue( '@Location' );
100            
101             # keep only documentation in file list
102 26 100       2273 if ( $location !~ m{\A doc/}x ) {
103 19         161 $file->parentNode->removeChild( $file );
104             }
105             else {
106 7         44 my @child_nodes = $file->childNodes;
107            
108             # clean nodes
109 7         167 $file->removeChild( $_ ) for @child_nodes;
110 7         35 $file->removeAttribute( 'Encode' );
111 7         42 $file->setNodeName( 'FileDoc' );
112             }
113             }
114            
115             # remove unnecessary nodes
116 13         501 for my $node_name ( qw(Code Intro Database)) {
117 39         76 for my $phase ( qw(Install Upgrade Reinstall Uninstall) ) {
118 156         603 my @nodes = $root_elem->findnodes( $node_name . $phase );
119 156         3387 $_->parentNode->removeChild( $_ ) for @nodes;
120             }
121             }
122            
123 13         29 for my $node_name ( qw(BuildHost BuildDate)) {
124 26         458 my @nodes = $root_elem->findnodes( $node_name );
125 26         725 $_->parentNode->removeChild( $_ ) for @nodes;
126             }
127            
128 13         419 my $file_node = XML::LibXML::Element->new( 'File' );
129 13         30 my $file_path = $opm_file;
130              
131 13 100       151 $file_path =~ s/\Q$dir// if $dir ne '.';
132 13 100       67 $file_path = '/' . $file_path if '/' ne substr $file_path, 0, 1;
133              
134 13         72 $file_node->appendText( $file_path );
135 13         75 $root_elem->addChild( $file_node );
136            
137 13         34 $pp->pretty_print( $tree );
138            
139 13         84880 my $xml = $tree->toString;
140 13         771 $xml =~ s{<\?xml .*? \?> \s+}{}x;
141            
142 13         74 push @packages, $xml;
143             }
144              
145 8   100     435 $root_name //= 'otrs';
146 8 100       57 my $product = $root_name =~ m{otobo} ? 'otobo' : 'otrs';
147            
148 8         42 my $packages_list = join '', @packages;
149            
150 8         1112 print sprintf qq~
151             <%s_package_list version="1.0">
152             %s
153            
154             ~, $product, $packages_list, $product;
155             }
156              
157             1;
158              
159             __END__