locatepm 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. #!/usr/bin/perl
  2. # Daniel "Trizen" Șuteu
  3. # License: GPLv3
  4. # Date: 18 February 2012
  5. # Edit: 08 August 2012
  6. # https://github.com/trizen
  7. # Find installed Perl modules matching a regular expression
  8. use 5.014;
  9. use File::Find qw(find);
  10. use Getopt::Std qw(getopts);
  11. sub usage {
  12. die <<"HELP";
  13. usage: perl $0 [options] 'REGEX'\n
  14. options:
  15. -p : print full path
  16. -b : both: path + name
  17. -i : case insensitive\n
  18. example:
  19. perl $0 -b ^File:: ^Term
  20. HELP
  21. }
  22. my %opts;
  23. getopts('pbih', \%opts);
  24. (!@ARGV || $opts{h}) && usage();
  25. sub reduce_dirs {
  26. my %substring_count;
  27. @substring_count{@_} = ();
  28. for my $x (@_) {
  29. for my $y (@_) {
  30. next if $x eq $y;
  31. if (index($x, $y) == 0) {
  32. $substring_count{$x}++;
  33. }
  34. }
  35. }
  36. grep { !$substring_count{$_} } keys %substring_count;
  37. }
  38. my @dirs;
  39. for my $dirname (@INC) {
  40. if (-d $dirname) {
  41. next if chr ord $dirname eq q{.};
  42. $dirname =~ tr{/}{/}s;
  43. chop $dirname if substr($dirname, -1) eq '/';
  44. push @dirs, $dirname;
  45. }
  46. }
  47. @dirs = reduce_dirs(@dirs);
  48. my $inc_re = do {
  49. local $" = q{|};
  50. qr{^(?>@{[map { quotemeta(s{/}{::}gr) } @dirs]})::};
  51. };
  52. foreach my $arg (@ARGV) {
  53. my $regex = $opts{i} ? qr{$arg}i : qr{$arg};
  54. find {
  55. wanted => sub {
  56. my $name = $_;
  57. say $opts{b} ? "$name\n$_\n"
  58. : $opts{p} ? $_
  59. : $name
  60. if substr($name, -3, 3, '') eq '.pm'
  61. and $name =~ s{/}{::}g
  62. and $name =~ s{$inc_re}{}o
  63. and $name =~ /$regex/;
  64. },
  65. no_chdir => 1,
  66. } => @dirs;
  67. }