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   44566 use warnings 'FATAL' => 'all';
  7         11  
  7         341  
4 7     7   32 use strict;
  7         10  
  7         225  
5              
6 7     7   38 use File::Basename qw(basename);
  7         10  
  7         576  
7 7     7   34 use File::Path qw(make_path);
  7         9  
  7         459  
8 7     7   38 use File::Spec qw();
  7         11  
  7         120  
9 7     7   33 use Carp qw();
  7         12  
  7         107  
10              
11 7     7   2880 use WWW::AUR::Package::File qw();
  7         19  
  7         173  
12 7     7   38 use WWW::AUR::URI qw( pkgbuild_uri pkgfile_uri pkg_uri );
  7         9  
  7         392  
13 7     7   33 use WWW::AUR::RPC qw();
  7         11  
  7         119  
14 7     7   24 use WWW::AUR qw( _path_params _useragent );
  7         12  
  7         1313  
15              
16             ##############################################################################
17             # CONSTANTS
18             #-----------------------------------------------------------------------------
19              
20             #---CONSTRUCTOR---
21             sub new
22             {
23 4778     4778 0 8713 my $class = shift;
24 4778 50       7858 Carp::croak( "You must at least supply a name as argument" ) if @_ == 0;
25              
26 4778         4915 my $name = shift;
27 4778         8505 my %params = @_;
28              
29 4778         3194 my $info;
30 4778 100       6622 if ( $params{info} ) {
31 4671         3875 $info = $params{info};
32             } else {
33             # this might croak on error
34 107         204 $info = eval { WWW::AUR::RPC::info( $name ) };
  107         492  
35 107 100       687 Carp::croak( "Failed to find package: $name" ) unless ( $info );
36             }
37              
38 4777         8080 my $self = bless { _path_params( @_ ),
39             pkgfile => "$name.src.tar.gz",
40             info => $info,
41             }, $class;
42              
43 4777         26022 return $self;
44             }
45              
46             sub _def_info_accessor
47             {
48 84     84   78 my ($field) = @_;
49              
50 7     7   40 no strict 'refs';
  7         9  
  7         3850  
51 84         306 *{ "WWW::AUR::Package::$field" } = sub {
52 2343     2343   17580 my ($self) = @_;
53 2343   100     9134 return $self->{info}{$field} || q{};
54 84         187 };
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 2 my ($self) = @_;
65 1         3 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   19 my ($self) = @_;
80              
81 10         33 return pkgfile_uri( $self->name );
82             }
83              
84             #---OBJECT METHOD---
85             sub download_size
86             {
87 2     2 0 1382 my ($self) = @_;
88              
89 2         14 my $ua = _useragent();
90 2         555 my $resp = $ua->head( $self->_download_url() );
91            
92 2 50       312104 return undef unless $resp->is_success;
93 2         36 return $resp->header( 'content-length' );
94             }
95              
96             #---OBJECT METHOD---
97             sub download
98             {
99 4     4 1 1575 my ($self, $usercb) = @_;
100              
101 4         14 my $pkgurl = $self->_download_url();
102 4         72 my $pkgpath = File::Spec->catfile( $self->{dlpath},
103             $self->{pkgfile} );
104              
105 4         356 make_path( $self->{dlpath} );
106              
107 4 50       953 open my $pkgfile, '>', $pkgpath or die "Failed to open $pkgpath:\n$!";
108 4         16 binmode $pkgfile;
109              
110             my $store_chunk = sub {
111 8     8   471287 my $chunk = shift;
112 8         48 print $pkgfile $chunk;
113 4         21 };
114              
115 4 100       21 if ( $usercb ) {
116 1         6 my $total = $self->download_size();
117 1         76 my $dled = 0;
118              
119 1         3 my $store = $store_chunk;
120             $store_chunk = sub {
121 2     2   159158 my $chunk = shift;
122 2         4 $dled += length $chunk;
123 2         8 $usercb->( $dled, $total );
124 2         11 $store->( $chunk );
125 1         10 };
126             }
127              
128 4         25 my $ua = _useragent();
129 4         944 my $resp = $ua->get( $self->_download_url(),
130             ':content_cb' => $store_chunk );
131 4 50       10463 close $pkgfile or die "close: $!";
132 4 50       31 Carp::croak( 'Failed to download package file:' . $resp->status_line )
133             unless $resp->is_success;
134              
135 4         98 $self->{pkgfile_obj} = WWW::AUR::Package::File->new
136             ( $pkgpath, _path_params( %$self ));
137              
138 4         198 return $pkgpath;
139             }
140              
141             #---PUBLIC METHOD---
142             # Purpose: Returns an object representing the package maintainer.
143             sub maintainer
144             {
145 1     1 1 692 my $self = shift;
146 1         4 my $mname = $self->maintainer_name();
147 1 50       4 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         9 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         5 my %params = ( _path_params( %$self ), _path_params( @_ ) );
159 1         10 my $mobj = WWW::AUR::Maintainer->new( $mname, %params );
160 1         8 return $mobj;
161             }
162              
163             sub _def_file_wrapper
164             {
165 42     42   38 my ($name) = @_;
166              
167 7     7   37 no warnings 'redefine';
  7         10  
  7         326  
168 7     7   32 no strict 'refs';
  7         41  
  7         981  
169 42         33 my $file_method = *{ $WWW::AUR::Package::File::{$name} }{ 'CODE' };
  42         97  
170 42         113 *{ $name } = sub {
171 3     3   1233 my $self = shift;
172 3 50       45 return undef unless $self->{'pkgfile_obj'};
173 3         8 my $ret = eval { $file_method->( $self->{'pkgfile_obj'}, @_ ) };
  3         19  
174 3 50       17 die if $@;
175 3         38 return $ret;
176 42         105 };
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   19 my ($name) = @_;
187              
188 7     7   45 no warnings 'redefine';
  7         8  
  7         196  
189 7     7   30 no strict 'refs';
  7         8  
  7         1756  
190              
191 14         9 my $oldcode = *{ $name }{ 'CODE' };
  14         20  
192 14         32 *{ $name } = sub {
193 2     2   669 my $self = shift;
194 2 50       10 unless ( $self->{'pkgfile_obj'} ) { $self->download(); }
  2         8  
195 2         11 return $oldcode->( $self, @_ );
196 14         33 };
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         12 my $name = $self->name;
208 1         9 my $pkgbuild_uri = pkgbuild_uri( $name );
209              
210 1         56 my $ua = _useragent();
211 1         285 my $resp = $ua->get( $pkgbuild_uri );
212              
213 1 50       157720 Carp::croak "Failed to download ${name}'s PKGBUILD: "
214             . $resp->status_line() unless $resp->is_success();
215              
216 1         14 return $resp->content();
217             }
218              
219             sub pkgbuild
220             {
221 2     2 1 19 my ($self) = @_;
222              
223 2 100       26 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         37 $self->{pkgbuild_txt} = $pbtext;
232 1         3 $self->{pkgbuild_obj} = eval { WWW::AUR::PKGBUILD->new( $pbtext ) };
  1         11  
233 1 50       3 Carp::confess if $@; # stack trace
234              
235 1         4 return $self->{pkgbuild_obj};
236             }
237              
238             1;