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.15';
3 21     21   15549 use strict;
  21         47  
  21         684  
4 21     21   111 use warnings;
  21         38  
  21         625  
5              
6             # ABSTRACT: Build index for an OPM repository
7              
8 21     21   110 use Carp qw(croak);
  21         37  
  21         1060  
9 21     21   130 use File::Basename;
  21         49  
  21         1288  
10 21     21   3793 use File::Find::Rule;
  21         59714  
  21         185  
11 21     21   4534 use MIME::Base64 ();
  21         4671  
  21         595  
12 21     21   3229 use Sys::Hostname;
  21         7563  
  21         1036  
13 21     21   3207 use Path::Class ();
  21         190446  
  21         609  
14 21     21   5479 use XML::LibXML;
  21         304504  
  21         148  
15 21     21   15512 use XML::LibXML::PrettyPrint;
  21         163955  
  21         303  
16              
17 21     21   5665 use OPM::Maker -command;
  21         58  
  21         189  
18 21     21   74579 use OPM::Maker::Utils qw(reformat_size);
  21         65  
  21         16871  
19              
20             sub abstract {
21 1     1 1 3443 return "build index for an OPM repository";
22             }
23              
24             sub usage_desc {
25 1     1 1 1028 return "opmbuild index ";
26             }
27              
28             sub validate_args {
29 7     7 1 8517 my ($self, $opt, $args) = @_;
30            
31 7 100 100     130 $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 12450 my ($self, $opt, $args) = @_;
40            
41 11         27 my $dir = $args->[0];
42            
43 11         335 my @opm_files = File::Find::Rule->file->name( '*.opm' )->in( $dir );
44            
45 11         11447 my @packages;
46 11         125 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         316 my $root_name;
58            
59 11         47 for my $opm_file ( sort @opm_files ) {
60 16         575 my $size = -s $opm_file;
61 16         45 my %opts;
62              
63 16 50       65 if ( !$ENV{OPM_UNSECURE} ) {
64 16         56 %opts = (
65             no_network => 1,
66             expand_entities => 0,
67             );
68             }
69              
70             # if file is big, but not "too big"
71 16         26 my $max_size = 31_457_280;
72 16 100       42 if ( $ENV{OPM_MAX_SIZE} ) {
73 11         38 $max_size = reformat_size( $ENV{OPM_MAX_SIZE} );
74             }
75              
76 16 100       49 if ( $size > $max_size ) {
77 3         436 croak "$opm_file too big (max size: $max_size bytes)";
78             }
79              
80 13 50       31 if ( $size > 10_000_000 ) {
81 0         0 $opts{huge} = 1;
82             }
83              
84 13         85 my $parser = XML::LibXML->new( %opts );
85 13         1193 my $tree = $parser->parse_file( $opm_file );
86            
87 13         5914 $tree->setStandalone( 0 );
88            
89 13         71 my $root_elem = $tree->getDocumentElement;
90 13         89 $root_name = $root_elem->nodeName();
91 13         73 $root_elem->setNodeName( 'Package' );
92 13         62 $root_elem->removeAttribute( 'version' );
93            
94             # retrieve file information
95 13         51 my @files = $root_elem->findnodes( 'Filelist/File' );
96            
97             FILE:
98 13         589 for my $file ( @files ) {
99 26         201 my $location = $file->findvalue( '@Location' );
100            
101             # keep only documentation in file list
102 26 100       2257 if ( $location !~ m{\A doc/}x ) {
103 19         156 $file->parentNode->removeChild( $file );
104             }
105             else {
106 7         36 my @child_nodes = $file->childNodes;
107            
108             # clean nodes
109 7         149 $file->removeChild( $_ ) for @child_nodes;
110 7         33 $file->removeAttribute( 'Encode' );
111 7         37 $file->setNodeName( 'FileDoc' );
112             }
113             }
114            
115             # remove unnecessary nodes
116 13         480 for my $node_name ( qw(Code Intro Database)) {
117 39         66 for my $phase ( qw(Install Upgrade Reinstall Uninstall) ) {
118 156         610 my @nodes = $root_elem->findnodes( $node_name . $phase );
119 156         3374 $_->parentNode->removeChild( $_ ) for @nodes;
120             }
121             }
122            
123 13         23 for my $node_name ( qw(BuildHost BuildDate)) {
124 26         394 my @nodes = $root_elem->findnodes( $node_name );
125 26         699 $_->parentNode->removeChild( $_ ) for @nodes;
126             }
127            
128 13         366 my $file_node = XML::LibXML::Element->new( 'File' );
129 13         26 my $file_path = $opm_file;
130              
131 13 100       128 $file_path =~ s/\Q$dir// if $dir ne '.';
132 13 100       51 $file_path = '/' . $file_path if '/' ne substr $file_path, 0, 1;
133              
134 13         63 $file_node->appendText( $file_path );
135 13         70 $root_elem->addChild( $file_node );
136            
137 13         33 $pp->pretty_print( $tree );
138            
139 13         83045 my $xml = $tree->toString;
140 13         599 $xml =~ s{<\?xml .*? \?> \s+}{}x;
141            
142 13         58 push @packages, $xml;
143             }
144              
145 8   100     439 $root_name //= 'otrs';
146 8 100       40 my $product = $root_name =~ m{otobo} ? 'otobo' : 'otrs';
147            
148 8         39 my $packages_list = join '', @packages;
149            
150 8         5740 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__