App-used
view release on metacpan or search on metacpan
}
# do stuff here
if (!@dirs) {
push @dirs, '.';
}
my %used;
my %versions;
while ( my $file = shift @dirs ) {
next if $file =~ m{ (?: README(?: [.]pod | [.]md)? $ | MANIFEST(?:[.]SKIP)?$ | Changes$ | [._]build | blib | [.](?: git | svn | bzr | cpanm) | CVS | RCS | debian ) }xms;
next if skip($file);
if ( -f $file ) {
next if $file !~ /[.](?:pm|pod|pl|cgi|t)$/ && path($file)->basename =~ /[.]/;
next if $option{exclude} && $file =~ m{/ $option{exclude} /}xms;
if ( path($file)->basename !~ /[.]/xms ) {
next if path($file)->slurp !~ /\A.*perl/;
}
process_file($file, \%used, \%versions);
}
else {
eval {
push @dirs, grep {!/^[.][^.]+/} path($file)->children;
warn "$file\n" if $option{verbose} > 5;
};
}
}
# remove modules that available from the maximum of the minimum versions of Perl required for these files
my $max_ver = max map { version->parse($_) } keys %versions;
warn "Files with the hightest Perl version:\n\t", join "\n\t", @{ $versions{$max_ver} }, "\n" if $option{perl_version};
for my $module (keys %used) {
my $rel_ver = Module::CoreList->first_release($module);
if ( $rel_ver && $rel_ver <= $max_ver ) {
my $value = delete $used{$module};
if ( $option{verbose} > 1 ) {
$used{$module} = { count => $value, colour => 'blue' };
}
}
}
# remove any modules defined in the local lib directory
for my $lib ( @{ $option{lib} } ) {
next if !-d $lib;
$lib =~ s{/$}{};
my @files = eval { grep {!/^[.][^.]+/} path($lib)->children };
while (my $file = shift @files) {
if ( -d $file ) {
push @files, grep {!/^[.][^.]+/} $file->children;
}
elsif ( $file =~ /[.]pm$/ ) {
my $mod = "$file";
$mod =~ s{^$lib/}{}xms;
$mod =~ s{/}{::}gxms;
$mod =~ s{[.]pm$}{}xms;
my $value = delete $used{$mod};
if ( $option{verbose} > 1 ) {
$used{$mod} = { count => $value, colour => 'bold' };
}
}
}
}
for my $module (keys %used) {
$used{$module} = { count => $used{$module}, colour => '' } if !ref $used{$module};
}
# Check what modules have been already required
my %specified = pre_specified();
show_results( $max_ver, \%used, \%specified );
return;
}
sub show_results {
my ( $max_ver, $used, $specified ) = @_;
if ( $option{update} ) {
my $max = 0;
my %map
= map {
$max = length $_ if length $_ > $max;
$_ => get_version($_)->{num}
}
grep {
$_ ne 'v5'
}
keys %{$used};
$max += 2;
print ' ' x 8,
join ' ' x 8,
( sprintf "%-${max}s => %s,\n", "'perl'", "'$max_ver'" ),
map {
sprintf "%-${max}s => %s,\n", "'$_'", $map{$_} eq 0 ? $map{$_} : "'$map{$_}'"
}
sort keys %map;
return;
}
my %notes;
$max_ver ||= 0;
# start the out put
my $star = ' ';
if ( $specified->{perl} && $max_ver > $specified->{perl}{version} ) {
$star = 'â';
$notes{$star} = "The specified minimum perl version ($specified->{perl}{version}) is less than some used features require";
}
print "Perl$star $max_ver\n" unless $option{quiet};
delete $specified->{perl};
if ( $option{verbose} ) {
for my $defined ( keys %$specified ) {
$used->{$defined} = { count => 0, build_only => $specified->{$defined}{build_only}, recommended => $specified->{$defined}{recommended} }
if defined $specified->{$defined} && !exists $used->{$defined};
warn $defined if defined $specified->{$defined} && !exists $used->{$defined};
}
}
my $max = max map { length $_ } keys %$used;
my @keys
= $option{uses} ? sort { $used->{$a}{count} <=> $used->{$b}{count} || uc $a cmp uc $b } keys %$used
: sort { uc $a cmp uc $b } keys %$used;
if ( $option{decending} ) {
@keys = reverse @keys;
}
for my $module (@keys) {
my $version = '';
my $star = '';
if ( $option{verbose} ) {
my $ver = get_version($module);
my $num = $ver->{num};
$version = $ver->{version};
my $spec = defined $specified->{$module} ? " ($specified->{$module}{version})" : '';
$version .= ' ' x (8 - length $version) . $spec;
$version = ' ' x ($max + 1 - length $module) . $version;
$star =
! exists $specified->{$module} ? 'â '
: ! defined $specified->{$module} ? ' '
: version->new($num) < version->new($specified->{$module}{version}) ? 'â¡'
: $used->{$module}{build_only} ? 'â'
: $used->{$module}{recommended} ? 'â'
: ' ';
}
else {
$star = exists $specified->{$module} ? ' ' : 'â ';
}
if ( $star ne ' ' && !exists $notes{$star} ) {
$notes{$star} =
$star eq 'â¡' ? 'The version specified in Build.PL greater that the currently installed version'
: $star eq 'â' ? 'The module is specified in Build.PL but doesn\'t appear to be used'
: $star eq 'â' ? 'The module is recommended in Build.PL but doesn\'t appear to be used'
: 'This module is not specified in Build.PL';
}
$used->{$module}{count} ||= 0;
$used->{$module}{colour} ||= '';
printf "%4d %s$star$version\n", $used->{$module}{count}, $used->{$module}{colour} ? colored($module, $used->{$module}{colour} ) : $module
unless $option{quiet};
if ( $used->{$module}{colour} && $used->{$module}{colour} ne '' && !$notes{ colored( $used->{$module}{colour}, $used->{$module}{colour} ) } ) {
$notes{ colored( $used->{$module}{colour}, $used->{$module}{colour} ) }
= $used->{$module}{colour} eq 'blue' ? "Core module"
: $used->{$module}{colour} eq 'bold' ? 'Local module'
: 'Update the code for this colour';
}
}
print "\n" unless $option{quiet};
$max = 1;
for my $key ( keys %notes ) {
$max = 4 if length $key > 4;
}
for my $note (sort keys %notes) {
print $note . ( ' ' x ( $max + 1 - ( length $note > 4 ? 4 : 1 ) ) ) . "$notes{$note}\n";
}
# return an error if some notes found
exit scalar keys %notes if keys %notes;
return;
}
{
my %cache;
sub get_version {
my ($module) = @_;
return $cache{$module} if $cache{$module};
my $file = "$module.pm";
$file =~ s{::}{/}gxms;
eval { require $file };
{
no strict qw/refs/; ## no critic
$cache{$module}{version} =
$EVAL_ERROR ? '0?0'
: defined ${$module . '::VERSION'} ? ${$module . '::VERSION'}
: 'undef';
$cache{$module}{num} =
$EVAL_ERROR ? 0
: defined ${$module . '::VERSION'} ? ${$module . '::VERSION'}
: 0;
}
return $cache{$module};
}
}
sub process_file {
my ($file, $used, $versions) = @_;
my $contents = path($file)->slurp;
# remove any data or end sections
$contents =~ s{^__(?:DATA|END)__\n.*\Z}{}xms;
# remove any POD
$contents =~ s/^=.*?^=cut$//gxms;
# TODO need to make the extends logic work for multiple extended modules
my @modules = grep { $_ ne 'ok' } $contents =~ m{^ \s* (?: use | require ) \s+ ( [\w:]+ ) }gxms;
push @modules, $contents =~ m{^ \s* (?: (?: use | require ) \s+ ok | extends ) \s+ ['"]( [\w:]+ )['"] }gxms;
( run in 0.346 second using v1.01-cache-2.11-cpan-cdf2f3d4e48 )