App-perlutils
view release on metacpan or search on metacpan
#!/usr/bin/perl
# List all functions defined in ./**.{pl,pm}
use vars qw($VERSION);
$VERSION = '0.004';
use strict;
use Term::ExtendedColor qw(fg);
use File::Find::Rule;
use Cwd 'abs_path';
my $dir = abs_path( shift // '.' );
if(-f $dir) {
output_func($dir);
}
elsif(-d $dir) {
my $ff = File::Find::Rule->new;
$ff->file;
$ff->name('*.pm', '*.pl');
my @perl = $ff->in( $dir );
output_func($ff->in($dir));
}
else {
print STDERR "Neither a file or directory specified.\n";
exit 1;
}
sub grab_func {
my @files = @_;
my %functions;
for my $file(@files) {
open(my $fh, '<', $file) or die($!);
while(<$fh>) {
if(m;\s*sub\s+(.+)\s*{;) {
$functions{$1} = $file;
}
}
}
return \%functions;
}
sub output_func {
my @files = @_;
my %func = %{ grab_func(@files) };
my $module;
for my $file(sort { $func{$b} cmp $func{$a} } (keys(%func))) {
if($func{$file} ne $module) {
$module = $func{$file};
my $mod_name;
if( ($module =~ m;.+lib/(.+)\.pm$;)) {
$mod_name = $1;
$mod_name =~ s;/;::;g;
$mod_name =~ s;\.pm;;;
print "\n";
print fg('bold', fg('yellow18', $mod_name)), "\n";
}
}
my ($basename) = $func{$file} =~ m;.+/(.+)$;;
my ($two_lvl) = $func{$file} =~ m;.+/(.+/.+)$;;
my $sep_counter = 0;
for(split(//, $func{$file})) {
if($_ eq '/') {
$sep_counter++;
}
}
if($sep_counter >= 4) {
$two_lvl =~ s;(.+)/(.+);
fg('grey10', $1) . fg('grey5', "::") . fg('grey4', $2)
;igex;
printf("%67.90s -> %s\n",
$two_lvl, $file);
}
else {
printf("%37.90s -> %s\n",
fg('gray10', $basename), $file);
}
}
printf("\n%s functions defined in %s\n",
fg('bold', scalar(keys(%func))), $dir)
unless(scalar(keys(%func)) < 1);
}
( run in 0.674 second using v1.01-cache-2.11-cpan-cdf2f3d4e48 )