File Coverage

blib/lib/WWW/AUR/Package.pm
Criterion Covered Total %
statement 139 142 97.8
branch 21 34 61.7
condition 2 2 100.0
subroutine 31 32 96.8
pod 5 7 71.4
total 198 217 91.2


line stmt bran cond sub pod time code
1             package WWW::AUR::Package;
2              
3 7     7   93432 use warnings 'FATAL' => 'all';
  7         16  
  7         333  
4 7     7   36 use strict;
  7         15  
  7         249  
5              
6 7     7   49 use File::Basename qw(basename);
  7         15  
  7         677  
7 7     7   39 use File::Path qw(make_path);
  7         15  
  7         603  
8 7     7   39 use File::Spec qw();
  7         13  
  7         137  
9 7     7   46 use Carp qw();
  7         13  
  7         128  
10              
11 7     7   5226 use WWW::AUR::Package::File qw();
  7         26  
  7         206  
12 7     7   55 use WWW::AUR::URI qw( pkgbuild_uri pkgfile_uri pkg_uri );
  7         12  
  7         463  
13 7     7   40 use WWW::AUR::RPC qw();
  7         14  
  7         142  
14 7     7   35 use WWW::AUR qw( _path_params _useragent );
  7         15  
  7         1562  
15              
16             ##############################################################################
17             # CONSTANTS
18             #-----------------------------------------------------------------------------
19              
20             #---CONSTRUCTOR---
21             sub new
22             {
23 4662     4662 0 9858 my $class = shift;
24 4662 50       10734 Carp::croak( "You must at least supply a name as argument" ) if @_ == 0;
25              
26 4662         6287 my $name = shift;
27 4662         13120 my %params = @_;
28              
29 4662         4520 my $info;
30 4662 100       8474 if ( $params{info} ) {
31 4555         5991 $info = $params{info};
32             } else {
33             # this might croak on error
34 107         201 $info = eval { WWW::AUR::RPC::info( $name ) };
  107         440  
35 107 100       674 Carp::croak( "Failed to find package: $name" ) unless ( $info );
36             }
37              
38 4661         11497 my $self = bless { _path_params( @_ ),
39             pkgfile => "$name.src.tar.gz",
40             info => $info,
41             }, $class;
42              
43 4661         35579 return $self;
44             }
45              
46             sub _def_info_accessor
47             {
48 84     84   101 my ($field) = @_;
49              
50 7     7   49 no strict 'refs';
  7         12  
  7         5411  
51 84         411 *{ "WWW::AUR::Package::$field" } = sub {
52 2289     2289   19642 my ($self) = @_;
53 2289   100     11912 return $self->{info}{$field} || q{};
54 84         230 };
55             }
56              
57             for ( qw{ id name version desc category url urlpath
58             license votes outdated ctime mtime } ) {
59             _def_info_accessor( $_ );
60             }
61              
62             sub maintainer_name
63             {
64 1     1 1 3 my ($self) = @_;
65 1         5 return $self->{'info'}{'maintainer'}; # might be undef for orphan
66             }
67              
68             #---PUBLIC METHOD---
69             # Returns a copy of the package info as a hash...
70             sub info
71             {
72 0     0 1 0 my ($self) = @_;
73 0         0 return %{ $self->{info} };
  0         0  
74             }
75              
76             #---PRIVATE METHOD---
77             sub _download_url
78             {
79 10     10   22 my ($self) = @_;
80              
81 10         160 return pkgfile_uri( $self->name );
82             }
83              
84             #---OBJECT METHOD---
85             sub download_size
86             {
87 2     2 0 1314 my ($self) = @_;
88              
89 2         12 my $ua = _useragent();
90 2         882 my $resp = $ua->head( $self->_download_url() );
91            
92 2 50       384703 return undef unless $resp->is_success;
93 2         32 return $resp->header( 'content-length' );
94             }
95              
96             #---OBJECT METHOD---
97             sub download
98             {
99 4     4 1 1817 my ($self, $usercb) = @_;
100              
101 4         19 my $pkgurl = $self->_download_url();
102 4         78 my $pkgpath = File::Spec->catfile( $self->{dlpath},
103             $self->{pkgfile} );
104              
105 4         326 make_path( $self->{dlpath} );
106              
107 4 50       964 open my $pkgfile, '>', $pkgpath or die "Failed to open $pkgpath:\n$!";
108 4         14 binmode $pkgfile;
109              
110             my $store_chunk = sub {
111 7     7   540538 my $chunk = shift;
112 7         54 print $pkgfile $chunk;
113 4         22 };
114              
115 4 100       18 if ( $usercb ) {
116 1         5 my $total = $self->download_size();
117 1         66 my $dled = 0;
118              
119 1         3 my $store = $store_chunk;
120             $store_chunk = sub {
121 1     1   207426 my $chunk = shift;
122 1         4 $dled += length $chunk;
123 1         10 $usercb->( $dled, $total );
124 1         11 $store->( $chunk );
125 1         8 };
126             }
127              
128 4         28 my $ua = _useragent();
129 4         1301 my $resp = $ua->get( $self->_download_url(),
130             ':content_cb' => $store_chunk );
131 4 50       12351 close $pkgfile or die "close: $!";
132 4 50       25 Carp::croak( 'Failed to download package file:' . $resp->status_line )
133             unless $resp->is_success;
134              
135 4         99 $self->{pkgfile_obj} = WWW::AUR::Package::File->new
136             ( $pkgpath, _path_params( %$self ));
137              
138 4         204 return $pkgpath;
139             }
140              
141             #---PUBLIC METHOD---
142             # Purpose: Returns an object representing the package maintainer.
143             sub maintainer
144             {
145 1     1 1 819 my $self = shift;
146 1         5 my $mname = $self->maintainer_name();
147 1 50       5 return undef unless defined $mname;
148              
149             # Propogate parameters to our new Maintainer object...
150 1 50       6 Carp::croak 'Only a hash of path parameters are allowed as argument'
151             unless @_ % 2 == 0;
152              
153 1         12 require WWW::AUR::Maintainer;
154              
155             # Propogate parameters to our new Maintainer object...
156             # Path parameters given as arguments override the path params the
157             # package object was given...
158 1         10 my %params = ( _path_params( %$self ), _path_params( @_ ) );
159 1         15 my $mobj = WWW::AUR::Maintainer->new( $mname, %params );
160 1         10 return $mobj;
161             }
162              
163             sub _def_file_wrapper
164             {
165 42     42   62 my ($name) = @_;
166              
167 7     7   41 no warnings 'redefine';
  7         12  
  7         387  
168 7     7   41 no strict 'refs';
  7         53  
  7         1092  
169 42         46 my $file_method = *{ $WWW::AUR::Package::File::{$name} }{ 'CODE' };
  42         133  
170 42         198 *{ $name } = sub {
171 3     3   2176 my $self = shift;
172 3 50       34 return undef unless $self->{'pkgfile_obj'};
173 3         7 my $ret = eval { $file_method->( $self->{'pkgfile_obj'}, @_ ) };
  3         20  
174 3 50       24 die if $@;
175 3         58 return $ret;
176 42         169 };
177             }
178              
179             _def_file_wrapper( $_ ) for qw{ extract src_pkg_path
180             src_dir_path make_src_path build
181             bin_pkg_path };
182              
183             # Wrap the Package::File methods to call download first if we have to...
184             sub _def_dl_wrapper
185             {
186 14     14   25 my ($name) = @_;
187              
188 7     7   38 no warnings 'redefine';
  7         12  
  7         201  
189 7     7   30 no strict 'refs';
  7         14  
  7         2310  
190              
191 14         16 my $oldcode = *{ $name }{ 'CODE' };
  14         31  
192 14         48 *{ $name } = sub {
193 2     2   773 my $self = shift;
194 2 50       11 unless ( $self->{'pkgfile_obj'} ) { $self->download(); }
  2         10  
195 2         10 return $oldcode->( $self, @_ );
196 14         47 };
197             }
198              
199             _def_dl_wrapper( $_ ) for qw/ extract build /;
200              
201             #---PRIVATE METHOD---
202             # Purpose: Download the package's PKGBUILD without saving it to a file.
203             sub _download_pkgbuild
204             {
205 1     1   3 my ($self) = @_;
206              
207 1         6 my $name = $self->name;
208 1         8 my $pkgbuild_uri = pkgbuild_uri( $name );
209              
210 1         6 my $ua = _useragent();
211 1         326 my $resp = $ua->get( $pkgbuild_uri );
212              
213 1 50       211156 Carp::croak "Failed to download ${name}'s PKGBUILD: "
214             . $resp->status_line() unless $resp->is_success();
215              
216 1         21 return $resp->content();
217             }
218              
219             sub pkgbuild
220             {
221 2     2 1 11 my ($self) = @_;
222              
223 2 100       37 return $self->{pkgfile_obj}->pkgbuild
224             if $self->{pkgfile_obj};
225              
226 1 50       6 return $self->{pkgbuild_obj}
227             if $self->{pkgbuild_obj};
228              
229 1         5 my $pbtext = $self->_download_pkgbuild;
230              
231 1         56 $self->{pkgbuild_txt} = $pbtext;
232 1         11 $self->{pkgbuild_obj} = eval { WWW::AUR::PKGBUILD->new( $pbtext ) };
  1         14  
233 1 50       4 Carp::confess if $@; # stack trace
234              
235 1         8 return $self->{pkgbuild_obj};
236             }
237              
238             1;