[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
1 package CPANPLUS::Internals::Search; 2 3 use strict; 4 5 use CPANPLUS::Error; 6 use CPANPLUS::Internals::Constants; 7 use CPANPLUS::Module; 8 use CPANPLUS::Module::Author; 9 10 use File::Find; 11 use File::Spec; 12 13 use Params::Check qw[check allow]; 14 use Locale::Maketext::Simple Class => 'CPANPLUS', Style => 'gettext'; 15 16 $Params::Check::VERBOSE = 1; 17 18 =pod 19 20 =head1 NAME 21 22 CPANPLUS::Internals::Search 23 24 =head1 SYNOPSIS 25 26 my $aref = $cpan->_search_module_tree( 27 type => 'package', 28 allow => [qr/DBI/], 29 ); 30 31 my $aref = $cpan->_search_author_tree( 32 type => 'cpanid', 33 data => \@old_results, 34 verbose => 1, 35 allow => [qw|KANE AUTRIJUS|], 36 ); 37 38 my $aref = $cpan->_all_installed( ); 39 40 =head1 DESCRIPTION 41 42 The functions in this module are designed to find module(objects) 43 based on certain criteria and return them. 44 45 =head1 METHODS 46 47 =head2 _search_module_tree( type => TYPE, allow => \@regexex, [data => \@previous_results ] ) 48 49 Searches the moduletree for module objects matching the criteria you 50 specify. Returns an array ref of module objects on success, and false 51 on failure. 52 53 It takes the following arguments: 54 55 =over 4 56 57 =item type 58 59 This can be any of the accessors for the C<CPANPLUS::Module> objects. 60 This is a required argument. 61 62 =item allow 63 64 A set of rules, or more precisely, a list of regexes (via C<qr//> or 65 plain strings), that the C<type> must adhere too. You can specify as 66 many as you like, and it will be treated as an C<OR> search. 67 For an C<AND> search, see the C<data> argument. 68 69 This is a required argument. 70 71 =item data 72 73 An arrayref of previous search results. This is the way to do an C<AND> 74 search -- C<_search_module_tree> will only search the module objects 75 specified in C<data> if provided, rather than the moduletree itself. 76 77 =back 78 79 =cut 80 81 # Although the Params::Check solution is more graceful, it is WAY too slow. 82 # 83 # This sample script: 84 # 85 # use CPANPLUS::Backend; 86 # my $cb = new CPANPLUS::Backend; 87 # $cb->module_tree; 88 # my @list = $cb->search( type => 'module', allow => [qr/^Acme/] ); 89 # print $_->module, $/ for @list; 90 # 91 # Produced the following output using Dprof WITH params::check code 92 # 93 # Total Elapsed Time = 3.670024 Seconds 94 # User+System Time = 3.390373 Seconds 95 # Exclusive Times 96 # %Time ExclSec CumulS #Calls sec/call Csec/c Name 97 # 88.7 3.008 4.463 20610 0.0001 0.0002 Params::Check::check 98 # 47.4 1.610 1.610 1 1.6100 1.6100 Storable::net_pstore 99 # 25.6 0.869 0.737 20491 0.0000 0.0000 Locale::Maketext::Simple::_default 100 # _gettext 101 # 23.2 0.789 0.524 40976 0.0000 0.0000 Params::Check::_who_was_it 102 # 23.2 0.789 0.677 20610 0.0000 0.0000 Params::Check::_sanity_check 103 # 19.7 0.670 0.670 1 0.6700 0.6700 Storable::pretrieve 104 # 14.1 0.480 0.211 41350 0.0000 0.0000 Params::Check::_convert_case 105 # 11.5 0.390 0.256 20610 0.0000 0.0000 Params::Check::_hashdefs 106 # 11.5 0.390 0.255 20697 0.0000 0.0000 Params::Check::_listreqs 107 # 11.4 0.389 0.177 20653 0.0000 0.0000 Params::Check::_canon_key 108 # 10.9 0.370 0.356 20697 0.0000 0.0000 Params::Check::_hasreq 109 # 8.02 0.272 4.750 1 0.2723 4.7501 CPANPLUS::Internals::Search::_sear 110 # ch_module_tree 111 # 6.49 0.220 0.086 20653 0.0000 0.0000 Params::Check::_iskey 112 # 6.19 0.210 0.077 20488 0.0000 0.0000 Params::Check::_store_error 113 # 5.01 0.170 0.036 20680 0.0000 0.0000 CPANPLUS::Module::__ANON__ 114 # 115 # and this output /without/ 116 # 117 # Total Elapsed Time = 2.803426 Seconds 118 # User+System Time = 2.493426 Seconds 119 # Exclusive Times 120 # %Time ExclSec CumulS #Calls sec/call Csec/c Name 121 # 56.9 1.420 1.420 1 1.4200 1.4200 Storable::net_pstore 122 # 25.6 0.640 0.640 1 0.6400 0.6400 Storable::pretrieve 123 # 9.22 0.230 0.096 20680 0.0000 0.0000 CPANPLUS::Module::__ANON__ 124 # 7.06 0.176 0.272 1 0.1762 0.2719 CPANPLUS::Internals::Search::_sear 125 # ch_module_tree 126 # 3.21 0.080 0.098 10 0.0080 0.0098 IPC::Cmd::BEGIN 127 # 1.60 0.040 0.205 13 0.0031 0.0158 CPANPLUS::Internals::BEGIN 128 # 1.20 0.030 0.030 29 0.0010 0.0010 vars::BEGIN 129 # 1.20 0.030 0.117 10 0.0030 0.0117 Log::Message::BEGIN 130 # 1.20 0.030 0.029 9 0.0033 0.0033 CPANPLUS::Internals::Search::BEGIN 131 # 0.80 0.020 0.020 5 0.0040 0.0040 DynaLoader::dl_load_file 132 # 0.80 0.020 0.127 10 0.0020 0.0127 CPANPLUS::Module::BEGIN 133 # 0.80 0.020 0.389 2 0.0099 0.1944 main::BEGIN 134 # 0.80 0.020 0.359 12 0.0017 0.0299 CPANPLUS::Backend::BEGIN 135 # 0.40 0.010 0.010 30 0.0003 0.0003 Config::FETCH 136 # 0.40 0.010 0.010 18 0.0006 0.0005 Locale::Maketext::Simple::load_loc 137 # 138 139 sub _search_module_tree { 140 my $self = shift; 141 my $conf = $self->configure_object; 142 my %hash = @_; 143 144 my($mods,$list,$verbose,$type); 145 my $tmpl = { 146 data => { default => [values %{$self->module_tree}], 147 strict_type=> 1, store => \$mods }, 148 allow => { required => 1, default => [ ], strict_type => 1, 149 store => \$list }, 150 verbose => { default => $conf->get_conf('verbose'), 151 store => \$verbose }, 152 type => { required => 1, allow => [CPANPLUS::Module->accessors()], 153 store => \$type }, 154 }; 155 156 my $args = check( $tmpl, \%hash ) or return; 157 158 { local $Params::Check::VERBOSE = 0; 159 160 my @rv; 161 for my $mod (@$mods) { 162 #push @rv, $mod if check( 163 # { $type => { allow => $list } }, 164 # { $type => $mod->$type() } 165 # ); 166 push @rv, $mod if allow( $mod->$type() => $list ); 167 168 } 169 return \@rv; 170 } 171 } 172 173 =pod 174 175 =head2 _search_author_tree( type => TYPE, allow => \@regexex, [data => \@previous_results ] ) 176 177 Searches the authortree for author objects matching the criteria you 178 specify. Returns an array ref of author objects on success, and false 179 on failure. 180 181 It takes the following arguments: 182 183 =over 4 184 185 =item type 186 187 This can be any of the accessors for the C<CPANPLUS::Module::Author> 188 objects. This is a required argument. 189 190 =item allow 191 192 193 A set of rules, or more precisely, a list of regexes (via C<qr//> or 194 plain strings), that the C<type> must adhere too. You can specify as 195 many as you like, and it will be treated as an C<OR> search. 196 For an C<AND> search, see the C<data> argument. 197 198 This is a required argument. 199 200 =item data 201 202 An arrayref of previous search results. This is the way to do an C<and> 203 search -- C<_search_author_tree> will only search the author objects 204 specified in C<data> if provided, rather than the authortree itself. 205 206 =back 207 208 =cut 209 210 sub _search_author_tree { 211 my $self = shift; 212 my $conf = $self->configure_object; 213 my %hash = @_; 214 215 my($authors,$list,$verbose,$type); 216 my $tmpl = { 217 data => { default => [values %{$self->author_tree}], 218 strict_type=> 1, store => \$authors }, 219 allow => { required => 1, default => [ ], strict_type => 1, 220 store => \$list }, 221 verbose => { default => $conf->get_conf('verbose'), 222 store => \$verbose }, 223 type => { required => 1, allow => [CPANPLUS::Module::Author->accessors()], 224 store => \$type }, 225 }; 226 227 my $args = check( $tmpl, \%hash ) or return; 228 229 { local $Params::Check::VERBOSE = 0; 230 231 my @rv; 232 for my $auth (@$authors) { 233 #push @rv, $auth if check( 234 # { $type => { allow => $list } }, 235 # { $type => $auth->$type } 236 # ); 237 push @rv, $auth if allow( $auth->$type() => $list ); 238 } 239 return \@rv; 240 } 241 242 243 } 244 245 =pod 246 247 =head2 _all_installed() 248 249 This function returns an array ref of module objects of modules that 250 are installed on this system. 251 252 =cut 253 254 sub _all_installed { 255 my $self = shift; 256 my $conf = $self->configure_object; 257 my %hash = @_; 258 259 ### File::Find uses follow_skip => 1 by default, which doesn't die 260 ### on duplicates, unless they are directories or symlinks. 261 ### Ticket #29796 shows this code dying on Alien::WxWidgets, 262 ### which uses symlinks. 263 ### File::Find doc says to use follow_skip => 2 to ignore duplicates 264 ### so this will stop it from dying. 265 my %find_args = ( follow_skip => 2 ); 266 267 ### File::Find uses lstat, which quietly becomes stat on win32 268 ### it then uses -l _ which is not allowed by the statbuffer because 269 ### you did a stat, not an lstat (duh!). so don't tell win32 to 270 ### follow symlinks, as that will break badly 271 $find_args{'follow_fast'} = 1 unless ON_WIN32; 272 273 ### never use the @INC hooks to find installed versions of 274 ### modules -- they're just there in case they're not on the 275 ### perl install, but the user shouldn't trust them for *other* 276 ### modules! 277 ### XXX CPANPLUS::inc is now obsolete, remove the calls 278 #local @INC = CPANPLUS::inc->original_inc; 279 280 my %seen; my @rv; 281 for my $dir (@INC ) { 282 next if $dir eq '.'; 283 284 ### not a directory after all 285 ### may be coderef or some such 286 next unless -d $dir; 287 288 ### make sure to clean up the directories just in case, 289 ### as we're making assumptions about the length 290 ### This solves rt.cpan issue #19738 291 292 ### John M. notes: On VMS cannonpath can not currently handle 293 ### the $dir values that are in UNIX format. 294 $dir = File::Spec->canonpath( $dir ) unless ON_VMS; 295 296 ### have to use F::S::Unix on VMS, or things will break 297 my $file_spec = ON_VMS ? 'File::Spec::Unix' : 'File::Spec'; 298 299 ### XXX in some cases File::Find can actually die! 300 ### so be safe and wrap it in an eval. 301 eval { File::Find::find( 302 { %find_args, 303 wanted => sub { 304 305 return unless /\.pm$/i; 306 my $mod = $File::Find::name; 307 308 ### make sure it's in Unix format, as it 309 ### may be in VMS format on VMS; 310 $mod = VMS::Filespec::unixify( $mod ) if ON_VMS; 311 312 $mod = substr($mod, length($dir) + 1, -3); 313 $mod = join '::', $file_spec->splitdir($mod); 314 315 return if $seen{$mod}++; 316 317 my $modobj = $self->module_tree($mod); 318 319 ### seperate return, a list context return with one '' 320 ### in it, is also true! 321 return unless $modobj; 322 323 push @rv, $modobj; 324 }, 325 }, $dir 326 ) }; 327 328 ### report the error if file::find died 329 error(loc("Error finding installed files in '%1': %2", $dir, $@)) if $@; 330 } 331 332 return \@rv; 333 } 334 335 1; 336 337 # Local variables: 338 # c-indentation-style: bsd 339 # c-basic-offset: 4 340 # indent-tabs-mode: nil 341 # End: 342 # vim: expandtab shiftwidth=4:
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Tue Mar 17 22:47:18 2015 | Cross-referenced by PHPXref 0.7.1 |