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.17';
3 21     21   13385 use strict;
  21         43  
  21         1510  
4 21     21   98 use warnings;
  21         32  
  21         613  
5              
6             # ABSTRACT: Build index for an OPM repository
7              
8 21     21   1323 use Carp qw(croak);
  21         1016  
  21         991  
9 21     21   114 use File::Basename;
  21         2137  
  21         1141  
10 21     21   3187 use File::Find::Rule;
  21         48855  
  21         139  
11 21     21   3674 use MIME::Base64 ();
  21         3837  
  21         384  
12 21     21   2728 use Sys::Hostname;
  21         6074  
  21         801  
13 21     21   2674 use Path::Class ();
  21         154535  
  21         665  
14 21     21   4137 use XML::LibXML;
  21         251330  
  21         112  
15 21     21   12132 use XML::LibXML::PrettyPrint;
  21         140027  
  21         204  
16              
17 21     21   4856 use OPM::Maker -command;
  21         49  
  21         172  
18 21     21   68402 use OPM::Maker::Utils qw(reformat_size);
  21         43  
  21         14959  
19              
20             sub abstract {
21 1     1 1 2872 return "build index for an OPM repository";
22             }
23              
24             sub usage_desc {
25 1     1 1 852 return "opmbuild index ";
26             }
27              
28             sub validate_args {
29 7     7 1 6841 my ($self, $opt, $args) = @_;
30            
31 7 100 100     94 $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 11756 my ($self, $opt, $args) = @_;
40            
41 11         22 my $dir = $args->[0];
42            
43 11         287 my @opm_files = File::Find::Rule->file->name( '*.opm' )->in( $dir );
44            
45 11         8915 my @packages;
46 11         127 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         269 my $root_name;
58            
59 11         33 for my $opm_file ( sort @opm_files ) {
60 16         484 my $size = -s $opm_file;
61 16         37 my %opts;
62              
63 16 50       53 if ( !$ENV{OPM_UNSECURE} ) {
64 16         47 %opts = (
65             no_network => 1,
66             expand_entities => 0,
67             );
68             }
69              
70             # if file is big, but not "too big"
71 16         21 my $max_size = 31_457_280;
72 16 100       37 if ( $ENV{OPM_MAX_SIZE} ) {
73 11         36 $max_size = reformat_size( $ENV{OPM_MAX_SIZE} );
74             }
75              
76 16 100       39 if ( $size > $max_size ) {
77 3         353 croak "$opm_file too big (max size: $max_size bytes)";
78             }
79              
80 13 50       28 if ( $size > 10_000_000 ) {
81 0         0 $opts{huge} = 1;
82             }
83              
84 13         77 my $parser = XML::LibXML->new( %opts );
85 13         1006 my $tree = $parser->parse_file( $opm_file );
86            
87 13         4998 $tree->setStandalone( 0 );
88            
89 13         57 my $root_elem = $tree->getDocumentElement;
90 13         73 $root_name = $root_elem->nodeName();
91 13         61 $root_elem->setNodeName( 'Package' );
92 13         51 $root_elem->removeAttribute( 'version' );
93            
94             # retrieve file information
95 13         43 my @files = $root_elem->findnodes( 'Filelist/File' );
96            
97             FILE:
98 13         483 for my $file ( @files ) {
99 26         161 my $location = $file->findvalue( '@Location' );
100            
101             # keep only documentation in file list
102 26 100       1753 if ( $location !~ m{\A doc/}x ) {
103 19         138 $file->parentNode->removeChild( $file );
104             }
105             else {
106 7         28 my @child_nodes = $file->childNodes;
107            
108             # clean nodes
109 7         127 $file->removeChild( $_ ) for @child_nodes;
110 7         30 $file->removeAttribute( 'Encode' );
111 7         31 $file->setNodeName( 'FileDoc' );
112             }
113             }
114            
115             # remove unnecessary nodes
116 13         392 for my $node_name ( qw(Code Intro Database)) {
117 39         53 for my $phase ( qw(Install Upgrade Reinstall Uninstall) ) {
118 156         480 my @nodes = $root_elem->findnodes( $node_name . $phase );
119 156         2848 $_->parentNode->removeChild( $_ ) for @nodes;
120             }
121             }
122            
123 13         20 for my $node_name ( qw(BuildHost BuildDate)) {
124 26         330 my @nodes = $root_elem->findnodes( $node_name );
125 26         574 $_->parentNode->removeChild( $_ ) for @nodes;
126             }
127            
128 13         334 my $file_node = XML::LibXML::Element->new( 'File' );
129 13         24 my $file_path = $opm_file;
130              
131 13 100       103 $file_path =~ s/\Q$dir// if $dir ne '.';
132 13 100       42 $file_path = '/' . $file_path if '/' ne substr $file_path, 0, 1;
133              
134 13         53 $file_node->appendText( $file_path );
135 13         59 $root_elem->addChild( $file_node );
136            
137 13         28 $pp->pretty_print( $tree );
138            
139 13         67851 my $xml = $tree->toString;
140 13         501 $xml =~ s{<\?xml .*? \?> \s+}{}x;
141            
142 13         50 push @packages, $xml;
143             }
144              
145 8   100     332 $root_name //= 'otrs';
146 8 100       37 my $product = $root_name =~ m{otobo} ? 'otobo' : 'otrs';
147            
148 8         30 my $packages_list = join '', @packages;
149            
150 8         3836 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__