File Coverage

lib/CPANPLUS/Module/Author.pm
Criterion Covered Total %
statement 59 62 95.1
branch 10 16 62.5
condition n/a
subroutine 13 13 100.0
pod 5 5 100.0
total 87 96 90.6


line stmt bran cond sub pod time code
1             package CPANPLUS::Module::Author;
2              
3 20     20   132 use strict;
  20         53  
  20         702  
4              
5 20     20   132 use CPANPLUS::Error;
  20         47  
  20         1106  
6 20     20   139 use CPANPLUS::Internals::Constants;
  20         89  
  20         7331  
7 20     20   152 use Params::Check qw[check];
  20         49  
  20         987  
8 20     20   139 use Locale::Maketext::Simple Class => 'CPANPLUS', Style => 'gettext';
  20         51  
  20         131  
9 20     20   5284 use vars qw[$VERSION];
  20         44  
  20         2193  
10             $VERSION = "0.9910";
11              
12             local $Params::Check::VERBOSE = 1;
13              
14             =pod
15              
16             =head1 NAME
17              
18             CPANPLUS::Module::Author - CPAN author object for CPANPLUS
19              
20             =head1 SYNOPSIS
21              
22             my $author = CPANPLUS::Module::Author->new(
23             author => 'Jack Ashton',
24             cpanid => 'JACKASH',
25             _id => INTERNALS_OBJECT_ID,
26             );
27              
28             $author->cpanid;
29             $author->author;
30             $author->email;
31              
32             @dists = $author->distributions;
33             @mods = $author->modules;
34              
35             @accessors = CPANPLUS::Module::Author->accessors;
36              
37             =head1 DESCRIPTION
38              
39             C creates objects from the information in the
40             source files. These can then be used to query on.
41              
42             These objects should only be created internally. For C objects,
43             there's the C class.
44              
45             =head1 ACCESSORS
46              
47             An objects of this class has the following accessors:
48              
49             =over 4
50              
51             =item author
52              
53             Name of the author.
54              
55             =item cpanid
56              
57             The CPAN id of the author.
58              
59             =item email
60              
61             The email address of the author, which defaults to '' if not provided.
62              
63             =item parent
64              
65             The C that spawned this module object.
66              
67             =back
68              
69             =cut
70              
71             my $tmpl = {
72             author => { required => 1 }, # full name of the author
73             cpanid => { required => 1 }, # cpan id
74             email => { default => '' }, # email address of the author
75             _id => { required => 1 }, # id of the Internals object that spawned us
76             };
77              
78             ### autogenerate accessors ###
79             for my $key ( keys %$tmpl ) {
80 20     20   151 no strict 'refs';
  20         51  
  20         12540  
81             *{__PACKAGE__."::$key"} = sub {
82 195     195   2932 my $self = shift;
83 195 50       499 $self->{$key} = $_[0] if @_;
84 195         968 return $self->{$key};
85             }
86             }
87              
88             sub parent {
89 6     6 1 33 my $self = shift;
90 6         74 my $obj = CPANPLUS::Internals->_retrieve_id( $self->_id );
91              
92 6         25 return $obj;
93             }
94              
95             =pod
96              
97             =head1 METHODS
98              
99             =head2 $auth = CPANPLUS::Module::Author->new( author => AUTHOR_NAME, cpanid => CPAN_ID, _id => INTERNALS_ID [, email => AUTHOR_EMAIL] )
100              
101             This method returns a C object, based on the given
102             parameters.
103              
104             Returns false on failure.
105              
106             =cut
107              
108             sub new {
109 224     224 1 609 my $class = shift;
110 224         1301 my %hash = @_;
111              
112             ### don't check the template for sanity
113             ### -- we know it's good and saves a lot of performance
114 224         836 local $Params::Check::SANITY_CHECK_TEMPLATE = 0;
115              
116 224 50       1066 my $object = check( $tmpl, \%hash ) or return;
117              
118 224         31240 return bless $object, $class;
119             }
120              
121             =pod
122              
123             =head2 @mod_objs = $auth->modules()
124              
125             Return a list of module objects this author has released.
126              
127             =cut
128              
129             sub modules {
130 5     5 1 32 my $self = shift;
131 5         52 my $cb = $self->parent;
132              
133 5         29 my $aref = $cb->_search_module_tree(
134             type => 'author',
135             ### XXX, depending on backend, this is either an object
136             ### or the cpanid string. Don't know an elegant way to
137             ### solve this right now, so passing both
138             allow => [$self, $self->cpanid],
139             );
140 5 50       39 return @$aref if $aref;
141 0         0 return;
142             }
143              
144             =pod
145              
146             =head2 @dists = $auth->distributions()
147              
148             Returns a list of module objects representing all the distributions
149             this author has released.
150              
151             =cut
152              
153             sub distributions {
154 2     2 1 718 my $self = shift;
155 2         13 my %hash = @_;
156              
157 2         8 local $Params::Check::ALLOW_UNKNOWN = 1;
158 2         10 local $Params::Check::NO_DUPLICATES = 1;
159              
160 2         13 my $mod;
161 2         17 my $tmpl = {
162             module => { default => '', store => \$mod },
163             };
164              
165 2 50       53 my $args = check( $tmpl, \%hash ) or return;
166              
167             ### if we didn't get a module object passed, we'll find one ourselves ###
168 2 100       155 unless( $mod ) {
169 1         7 my @list = $self->modules;
170 1 50       17 if( @list ) {
171 1         10 $mod = $list[0];
172             } else {
173 0         0 error( loc( "This author has released no modules" ) );
174 0         0 return;
175             }
176             }
177              
178 2         15 my $file = $mod->checksums( %hash );
179 2 50       189 my $href = $mod->_parse_checksums_file( file => $file ) or return;
180              
181 2         8 my @rv;
182 2         21 for my $name ( keys %$href ) {
183              
184             ### shortcut asap, so we avoid extra ops. On big checksums files
185             ### the call to clone() takes up a lot of time.
186             ### .meta files are now also in the checksums file,
187             ### which means we have to filter out things that don't
188             ### match our regex
189 8 100       46 next if $mod->package_extension( $name ) eq META_EXT;
190              
191             ### used to do this wiht ->clone. However, that calls ->dslip,
192             ### (which is wrong anyway, as we're doing a different module),
193             ### which in turn calls ->contains, which scans the entire
194             ### module tree using _search_module_tree, which uses P::C
195             ### and is therefor VERY VERY slow.
196             ### so let's do this the direct way for speed ups.
197             my $dist = CPANPLUS::Module::Fake->new(
198 6         20 module => do { my $m = $mod->package_name( $name );
199 6         38 $m =~ s/-/::/g; $m;
  6         27  
200             },
201             version => $mod->package_version( $name ),
202             package => $name,
203             path => $mod->path, # same author after all
204             author => $mod->author, # same author after all
205 6         11 mtime => $href->{$name}->{'mtime'}, # release date
206             );
207              
208 6         19 push @rv, $dist;
209             }
210              
211 2         26 return @rv;
212             }
213              
214              
215             =pod
216              
217             =head1 CLASS METHODS
218              
219             =head2 accessors ()
220              
221             Returns a list of all accessor methods to the object
222              
223             =cut
224              
225 166     166 1 1496 sub accessors { return keys %$tmpl };
226              
227             1;
228              
229             # Local variables:
230             # c-indentation-style: bsd
231             # c-basic-offset: 4
232             # indent-tabs-mode: nil
233             # End:
234             # vim: expandtab shiftwidth=4: