File Coverage

blib/lib/Installer/Software.pm
Criterion Covered Total %
statement 25 116 21.5
branch 0 52 0.0
condition 0 9 0.0
subroutine 9 25 36.0
pod 0 16 0.0
total 34 218 15.6


line stmt bran cond sub pod time code
1             package Installer::Software;
2             BEGIN {
3 1     1   28 $Installer::Software::AUTHORITY = 'cpan:GETTY';
4             }
5             # ABSTRACT: A software installation
6             $Installer::Software::VERSION = '0.903';
7 1     1   6 use Moo;
  1         2  
  1         7  
8 1     1   295 use IO::All;
  1         2  
  1         6  
9 1     1   933 use IO::All::LWP;
  1         123037  
  1         16  
10 1     1   1346 use JSON_File;
  1         43594  
  1         67  
11 1     1   14 use Path::Class;
  1         3  
  1         88  
12 1     1   1155 use File::chdir;
  1         4374  
  1         140  
13 1     1   1214 use Archive::Extract;
  1         340140  
  1         51  
14 1     1   12 use namespace::clean;
  1         3  
  1         12  
15              
16             has target => (
17             is => 'ro',
18             required => 1,
19             );
20 0     0 0   sub log_print { shift->target->log_print(@_) }
21 0     0 0   sub run { shift->target->run(@_) }
22 0     0 0   sub target_directory { shift->target->target->stringify }
23 0     0 0   sub target_path { shift->target->target_path(@_) }
24 0     0 0   sub target_file { shift->target->target_file(@_) }
25              
26             has archive_url => (
27             is => 'ro',
28             predicate => 1,
29             );
30              
31             has archive => (
32             is => 'ro',
33             predicate => 1,
34             );
35              
36             has export => (
37             is => 'ro',
38             predicate => 1,
39             );
40              
41             has unset => (
42             is => 'ro',
43             predicate => 1,
44             );
45              
46             for (qw( custom_configure custom_test post_install export_sh )) {
47             has $_ => (
48             is => 'ro',
49             predicate => 1,
50             );
51             }
52              
53             for (qw( with enable disable without patch )) {
54             has $_ => (
55             is => 'ro',
56             predicate => 1,
57             );
58             }
59              
60             has alias => (
61             is => 'ro',
62             lazy => 1,
63             default => sub {
64             my ( $self ) = @_;
65             if ($self->has_archive_url) {
66             return (split('-',(split('/',io($self->archive_url)->uri->path))[-1]))[0];
67             } elsif ($self->has_archive) {
68             return (split('-',(split('/',$self->archive))[-1]))[0];
69             }
70             die "Can't produce an alias for this sofware";
71             },
72             );
73              
74             has meta => (
75             is => 'ro',
76             lazy => 1,
77             default => sub {
78             my ( $self ) = @_;
79             tie(my %meta,'JSON_File',file($self->target->installer_dir,$_[0]->alias.'.json')->stringify,, pretty => 1 );
80             return \%meta;
81             },
82             );
83              
84             has testable => (
85             is => 'ro',
86             lazy => 1,
87             default => sub { $_[0]->has_custom_test ? 1 : 0 },
88             );
89              
90             sub installation {
91 0     0 0   my ( $self ) = @_;
92 0           $self->fetch;
93 0           $self->unpack;
94 0           $self->configure;
95 0           $self->compile;
96 0 0         $self->test if $self->testable;
97 0           $self->install;
98             }
99              
100             sub fetch {
101 0     0 0   my ( $self ) = @_;
102 0 0         return if defined $self->meta->{fetch};
103 0 0         if ($self->has_archive_url) {
    0          
104 0           my $sio = io($self->archive_url);
105 0           my $filename = (split('/',$sio->uri->path))[-1];
106 0           $self->log_print("Downloading ".$self->archive_url." as ".$filename." ...");
107 0           my $full_filename = file($self->target->src_dir,$filename)->stringify;
108 0           io($full_filename)->print(io($self->archive_url)->get->content);
109 0           $self->meta->{fetch} = $full_filename;
110             } elsif ($self->has_archive) {
111 0           $self->meta->{fetch} = file($self->archive)->absolute->stringify;
112             }
113 0 0         die "Unable to get an archive for unpacking for this software" unless defined $self->meta->{fetch};
114             }
115 0     0 0   sub fetch_path { file(shift->meta->{fetch}) }
116              
117             sub unpack {
118 0     0 0   my ( $self ) = @_;
119 0 0         return if defined $self->meta->{unpack};
120 0           $self->log_print("Extracting ".$self->fetch_path." ...");
121 0           my $archive = Archive::Extract->new( archive => $self->fetch_path );
122 0           local $CWD = $self->target->src_dir;
123 0           $archive->extract;
124 0           for (@{$archive->files}) {
  0            
125 0           $self->target->log($_);
126             }
127 0           my $src_path = dir($archive->extract_path)->absolute->stringify;
128 0           $self->log_print("Extracted to ".$src_path." ...");
129 0 0         if ($self->has_patch) {
130 0           my @patches = ref $self->patch eq 'ARRAY'
131 0 0         ? @{$self->patch}
132             : $self->patch;
133 0           for (@patches) {
134 0           $self->target->patch_via_url($self->target->src_dir,$_,'-p0');
135             }
136             }
137 0           $self->meta->{unpack} = $src_path;
138             }
139 0     0 0   sub unpack_path { dir(shift->meta->{unpack},@_) }
140 0     0 0   sub unpack_file { file(shift->meta->{unpack},@_) }
141              
142             sub run_configure {
143 0     0 0   my ( $self, @configure_args ) = @_;
144 0 0         if ($self->has_with) {
145 0           for my $key (keys %{$self->with}) {
  0            
146 0           my $value = $self->with->{$key};
147 0 0 0       if (defined $value && $value ne "") {
148 0           push @configure_args, '--with-'.$key.'='.$value;
149             } else {
150 0           push @configure_args, '--with-'.$key;
151             }
152             }
153             }
154 0           for my $func (qw( enable disable without )) {
155 0           my $has_func = 'has_'.$func;
156 0 0         if ($self->$has_func) {
157 0           for my $value (@{$self->$func}) {
  0            
158 0           push @configure_args, '--'.$func.'-'.$value;
159             }
160             }
161             }
162 0           $self->run($self->unpack_path,'./configure','--prefix='.$self->target_directory,@configure_args);
163             }
164              
165             sub configure {
166 0     0 0   my ( $self ) = @_;
167 0 0         return if defined $self->meta->{configure};
168 0           $self->log_print("Configuring ".$self->unpack_path." ...");
169 0 0         if ($self->has_custom_configure) {
170 0           $self->custom_configure->($self);
171             } else {
172 0 0         if (-f $self->unpack_file('autogen.sh')) {
173 0           $self->run($self->unpack_path,'./autogen.sh');
174             }
175 0 0         if (-f $self->unpack_file('configure')) {
    0          
    0          
176 0           $self->run_configure;
177             } elsif (-f $self->unpack_path('setup.py')) {
178             # no configure
179             } elsif ($self->unpack_file('Makefile.PL')) {
180 0           $self->run($self->unpack_path,'perl','Makefile.PL');
181             }
182             }
183 0           $self->meta->{configure} = 1;
184             }
185              
186             sub compile {
187 0     0 0   my ( $self ) = @_;
188 0 0         return if defined $self->meta->{compile};
189 0           $self->log_print("Compiling ".$self->unpack_path." ...");
190 0 0 0       if (-f $self->unpack_file('setup.py') and !-f $self->unpack_file('configure')) {
    0          
191 0           $self->run($self->unpack_path,'python','setup.py','build');
192             } elsif (-f $self->unpack_file('Makefile')) {
193 0           $self->run($self->unpack_path,'make');
194             }
195 0           $self->meta->{compile} = 1;
196             }
197              
198             sub test {
199 0     0 0   my ( $self ) = @_;
200 0 0         return if defined $self->meta->{test};
201 0           $self->log_print("Testing ".$self->unpack_path." ...");
202 0 0         if ($self->has_custom_test) {
203 0           $self->custom_test->($self);
204             } else {
205 0 0         if (-f $self->unpack_file('Makefile')) {
206 0           $self->run($self->unpack_path,'make','test');
207             }
208             }
209 0           $self->meta->{test} = 1;
210             }
211              
212             sub install {
213 0     0 0   my ( $self ) = @_;
214 0 0         return if defined $self->meta->{install};
215 0           $self->log_print("Installing ".$self->unpack_path." ...");
216 0 0 0       if (-f $self->unpack_file('setup.py') and !-f $self->unpack_file('configure')) {
    0          
217 0           $self->run($self->unpack_path,'python','setup.py','install');
218             } elsif (-f $self->unpack_file('Makefile')) {
219 0           $self->run($self->unpack_path,'make','install');
220             }
221 0           $self->meta->{install} = 1;
222             }
223              
224             1;
225              
226             __END__