File Coverage

blib/lib/OPM/Maker/Command/depcheck.pm
Criterion Covered Total %
statement 88 99 88.8
branch 25 36 69.4
condition 6 9 66.6
subroutine 11 14 78.5
pod 5 5 100.0
total 135 163 82.8


line stmt bran cond sub pod time code
1             package OPM::Maker::Command::depcheck;
2              
3             # ABSTRACT: Check if ticketsystem addon dependencies are installed (works for ((OTRS)) Community Edition, Znuny and OTOBO)
4              
5 6     6   3896 use v5.10;
  6         18  
6              
7 6     6   25 use strict;
  6         8  
  6         100  
8 6     6   24 use warnings;
  6         11  
  6         210  
9              
10             our $VERSION = '1.0.1'; # VERSION
11              
12 6     6   2090 use version;
  6         9629  
  6         28  
13              
14 6     6   381 use Carp qw(croak);
  6         11  
  6         258  
15 6     6   3293 use XML::LibXML;
  6         211280  
  6         34  
16              
17 6     6   2980 use OPM::Maker -command;
  6         228313  
  6         53  
18 6     6   29370 use OPM::Maker::Utils qw(check_args_sopm);
  6         46742  
  6         4758  
19              
20             sub abstract {
21 0     0 1 0 return "check if OPM package depencies are already installed";
22             }
23              
24             sub usage_desc {
25 0     0 1 0 return "opmbuild depcheck [--home ] ";
26             }
27              
28             sub opt_spec {
29             return (
30 0     0 1 0 [ 'home=s', 'Path to ticketsystem installation' ],
31             [ 'local_sopm', 'Checks if a .sopm for the required package exists in ' ],
32             );
33             }
34              
35             sub validate_args {
36 2     2 1 2253 my ($self, $opt, $args) = @_;
37              
38 2         13 my $sopm = check_args_sopm( $args, 1 );
39 2 100       1631 $self->usage_error( 'need path to .sopm or .opm' ) if
40             !$sopm;
41              
42 1 50       4 if ( !$opt->{home} ) {
43 0         0 for my $dir ( qw(otobo otrs znuny) ) {
44 0         0 my $path = '/opt/' . $dir;
45              
46 0 0       0 next if ! -d $path;
47              
48 0         0 $opt->{home} = $path;
49             }
50             }
51              
52 1 50       18 if ( !-d $opt->{home} ) {
53 1         10 $self->usage_error( "No ticketsystem found" );
54             }
55             }
56              
57             sub execute {
58 4     4 1 9252 my ($self, $opt, $args) = @_;
59            
60 4         23 my $file = check_args_sopm( $args, 1 );
61              
62 4         168 my %opts;
63 4 50       25 if ( !$ENV{OPM_UNSECURE} ) {
64 4         15 %opts = (
65             no_network => 1,
66             expand_entities => 0,
67             );
68             }
69              
70 4         34 my $size = -s $file;
71              
72             # if file is big, but not "too big"
73 4         42 my $max_size = 31_457_280;
74 4 50       16 if ( $ENV{OPM_MAX_SIZE} ) {
75 0         0 $max_size = reformat_size( $ENV{OPM_MAX_SIZE} );
76             }
77              
78 4 50       13 if ( $size > $max_size ) {
79 0         0 croak "$file too big (max size: $max_size bytes)";
80             }
81              
82 4 50       23 if ( $size > 10_000_000 ) {
83 0         0 $opts{huge} = 1;
84             }
85              
86 4         34 my $parser = XML::LibXML->new( %opts );
87 4         400 my $tree = $parser->parse_file( $file );
88            
89 4         1488 my $root_elem = $tree->getDocumentElement;
90              
91             # retrieve file information
92 4         38 my @package_req = $root_elem->findnodes( 'PackageRequired' );
93 4         300 my @modules_req = $root_elem->findnodes( 'ModuleRequired' );
94            
95 4         139 for my $subpath ( '', qw(/Kernel/cpan-lib Custom) ) {
96 12         36 push @INC, $opt->{home} . $subpath;
97             }
98              
99 4         8 my @missing;
100              
101             DEP:
102 4         10 for my $dependency ( @package_req, @modules_req ) {
103 8         48 my $type = $dependency->nodeName;
104 8         47 my $version = $dependency->findvalue( '@Version' );
105 8         922 my $name = $dependency->textContent;
106            
107 8         23 my $result = _check_dep( $name, $version, $type );
108              
109 8 100 100     39 if ( $result && $opt->{local_sopm} && $type eq 'PackageRequired' ) {
      66        
110 1         4 my $path = $opt->{home} . '/' . $name . '.sopm';
111 1 50       22 if ( -f $path ) {
112 1         5 my $local_tree = $parser->parse_file( $path );
113 1         284 my $root_elem = $local_tree->getDocumentElement;
114              
115 1         4 my @local_names = $root_elem->findnodes('Name');
116 1         46 my $local_name = $local_names[0]->textContent;
117              
118 1         6 my @local_versions = $root_elem->findnodes('Version');
119 1         28 my $local_version = $local_versions[0]->textContent;
120              
121 1 50 33     10 if ( $local_name eq $name && version->new($local_version) > version->new( $version ) ) {
122 0         0 $result = '';
123             }
124             }
125             }
126              
127 8 100       110 push @missing, $result if $result;
128             }
129              
130 4 100       12 if ( !@missing ) {
131 1         32 say "Everything ok!";
132 1         8 return 0;
133             }
134             else {
135 3         113 say "Missing: $_" for @missing;
136 3         27 return 1;
137             }
138             }
139              
140             sub _check_dep {
141 8     8   19 my ($name, $version, $type) = @_;
142              
143 8 100       33 if ( $type eq 'ModuleRequired' ) {
    50          
144 4         11 my $path = $name . '.pm';
145 4         25 $path =~ s{::}{/}g;
146              
147 4 100       9 eval {
148 4         24 require $path;
149 4         83 $name->VERSION( $version )
150             } or return "CPAN-Module $name $version";
151             }
152             elsif ( $type eq 'PackageRequired' ) {
153 4         23 require Kernel::System::ObjectManager;
154              
155 4         23 local $Kernel::OM = Kernel::System::ObjectManager->new;
156 4         22 my $db_object = $Kernel::OM->Get('Kernel::System::DB');
157              
158 4         38 my $sql = 'SELECT id, version FROM package_repository WHERE name = ?';
159 4         18 $db_object->Prepare(
160             SQL => $sql,
161             Bind => [ \$name ],
162             );
163              
164 4         58 my $installed_version;
165 4         12 while ( my @row = $db_object->FetchrowArray() ) {
166 3         26 $installed_version = $row[1];
167             }
168              
169 4 100       43 return "Addon $name $version" if !$installed_version;
170              
171 3         25 my $installed = version->new( $installed_version );
172 3         13 my $required = version->new( $version );
173              
174 3 100       116 return "Addon $name $version (installed $installed_version)" if $installed < $required;
175             }
176              
177 5         14 return;
178             }
179              
180             1;
181              
182             __END__