Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,5 @@ MANIFEST.bak
blib/
pm_to_blib
*.tar.gz
.vstags
local
23 changes: 15 additions & 8 deletions lib/Module/ScanDeps.pm
Original file line number Diff line number Diff line change
Expand Up @@ -603,6 +603,7 @@ sub scan_deps {
modules => [path_to_inc_name($path, $args{warn_missing})],
skip => undef,
warn_missing => $args{warn_missing},
include_missing => $args{include_missing},
);
}
else {
Expand Down Expand Up @@ -686,6 +687,7 @@ sub scan_deps_static {
modules => [$pm],
skip => $args->{skip},
warn_missing => $args->{warn_missing},
include_missing => $args->{include_missing},
);

my @preload = _get_preload($pm) or next;
Expand All @@ -696,6 +698,7 @@ sub scan_deps_static {
modules => \@preload,
skip => $args->{skip},
warn_missing => $args->{warn_missing},
include_missing => $args->{include_missing},
);
}
}
Expand Down Expand Up @@ -1035,12 +1038,13 @@ sub _find_encoding {
sub _add_info {
my %args = @_;
my ($rv, $module, $file, $used_by, $type) = @args{qw/rv module file used_by type/};

return unless defined($module) and defined($file);

# Ensure file is always absolute
$file = File::Spec->rel2abs($file);
$file =~ s|\\|\/|go;
if($file ne 'MISSING') {
$file = File::Spec->rel2abs($file);
$file =~ s|\\|\/|go;
}

# Avoid duplicates that can arise due to case differences that don't actually
# matter on a case tolerant system
Expand Down Expand Up @@ -1095,8 +1099,10 @@ sub add_deps {
my $used_by = $args{used_by};

foreach my $module (@{ $args{modules} }) {
my $file = _find_in_inc($module)
or _warn_of_missing_module($module, $args{warn_missing}), next;
my $file = _find_in_inc($module, $args{include_missing});

_warn_of_missing_module($module, $args{warn_missing}) if(!$file || $file eq 'MISSING');
next if !$file;
next if $skip->{$file};

if (exists $rv->{$module}) {
Expand Down Expand Up @@ -1144,16 +1150,16 @@ sub add_deps {

sub _find_in_inc {
my $file = shift;
my $include_missing = shift ? 'MISSING' : '';

return unless defined $file;

foreach my $dir (grep !/\bBSDPAN\b/, @INC, @IncludeLibs) {
return "$dir/$file" if -f "$dir/$file";
}

# absolute file names
return $file if -f $file;

return;
return -f $file ? $file : $include_missing;
}

sub _glob_in_inc {
Expand Down Expand Up @@ -1504,6 +1510,7 @@ sub _info2rv {
sub _gettype {
my $name = shift;

return 'missing' if $name eq 'MISSING';
return 'autoload' if $name =~ /\.(?:ix|al|bs)$/i;
return 'module' if $name =~ /\.p[mh]$/i;
return 'shared' if $name =~ /\.\Q$Config{dlext}\E$/i;
Expand Down
85 changes: 80 additions & 5 deletions script/scandeps.pl
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Getopt::Long qw(:config bundling no_ignore_case);
use Module::ScanDeps;
use ExtUtils::MakeMaker;
use File::Find;
use subs qw( _name _modtree );

my $usage = "Usage: $0 [ -B ] [ -V ] [ -T ] [ -x [ --xargs STRING ] | -c ] [ -R ] [-C FILE ] [ -e STRING | FILE ... ]\n";
Expand All @@ -22,15 +23,39 @@
"T|modtree",
"V|verbose",
"x|execute",
"m|include-missing",
"like-cpanfile",
"save-cpanfile",
"no-versions",
"force",
"files-from-workdir",
) or die $usage;

die 'Use `--save-cpanfile` only with `--like-cpanfile` option' if ($opts{'save-cpanfile'} and not $opts{'like-cpanfile'});
die 'Use `--force` only with `--save-cpanfile` option' if ($opts{'force'} and not $opts{'save-cpanfile'});

my (%map, %skip);
my $core = $opts{B};
my $verbose = $opts{V};
my $eval = $opts{e};
my $recurse = $opts{R} ? 0 : 1;
my $modtree = {} unless $opts{T}; # i.e. disable it unless explicitly requested

if($opts{'files-from-workdir'}) { #todo make custom filemask
# use lib 'lib';
finddepth({
wanted => sub { push @ARGV, $_ if /\.pl$/ },
no_chdir => 1,
}, 'bin');

finddepth({
wanted => sub { push @ARGV, $_ if /\.pm$/ },
no_chdir => 1,
}, 'lib');

# warn "Files found: ", join ", ", @ARGV;
}

if ($eval) {
require File::Temp;
my ($fh, $filename) = File::Temp::tempfile( UNLINK => 1 );
Expand Down Expand Up @@ -59,9 +84,9 @@
$opts{c} ? ( compile => 1 ) : (),
$opts{V} ? ( warn_missing => 1 ) : (),
$opts{C} ? ( cache_file => $opts{C}) : (),
$opts{m} ? ( include_missing => $opts{m}) : (),
);


my $len = 0;
my @todo;
my (%seen, %dist, %core, %bin);
Expand All @@ -79,7 +104,11 @@
$bin{$key}++;
}

next unless $mod->{type} eq 'module';
# warn $mod->{type};
if($mod->{type} ne 'module') {
if ($opts{m}) { next if $mod->{type} ne 'missing'; }
else { next }
}

next if $skip{$name};

Expand Down Expand Up @@ -107,10 +136,27 @@

print "#\n# Legend: [C]ore [X]ternal [S]ubmodule [?]NotOnCPAN\n" if $verbose;

foreach my $mod (sort { $a->{name} cmp $b->{name} } @todo ) {
my $version = MM->parse_version($mod->{file});
my $cpanfile_fh;
if ($opts{'save-cpanfile'} and $opts{'like-cpanfile'}) {
die "Attention! cpanfile already exists. Use `--force` option to overwrite it." if -f 'cpanfile' and not $opts{force};
open($cpanfile_fh, '>', "cpanfile") or die "Attention! Cant open cpanfile. $!.";
}

if (!$verbose) {
foreach my $mod (sort { $a->{name} cmp $b->{name} } @todo ) {
# warn Dumper $mod;
my $version = ($opts{m} and $mod->{type} eq 'missing') ? 0 : MM->parse_version($mod->{file});
# warn $version;
if($opts{'like-cpanfile'}) {
$version = 0 if $opts{'no-versions'};
# use Data::Dumper; warn Dumper $mod;
my $cpanfile_str = sprintf "requires '%s', '%s';\n", $mod->{name}, ($version eq 'undef' ? 0 : $version);

if($cpanfile_fh) { print $cpanfile_fh $cpanfile_str }
else { print $cpanfile_str }

next;
}
elsif (!$verbose) {
printf "%-${len}s => '$version',", "'$mod->{name}'" if $version;
} else {
printf "%-${len}s => '0', # ", "'$mod->{name}'";
Expand Down Expand Up @@ -234,6 +280,35 @@ =head1 OPTIONS

Retrieves module information from CPAN if you have B<CPANPLUS> installed.

no-versions
force

=item B<--files-from-workdir>

Finds *.pm files from C<$PWD/lib> and *.pl files from C<$PWD/bin>.

=back

=item B<-m>, B<--include-missing>

Shows missing modules too.

=item B<--no-versions>

All versions will be set to 0.

=item B<--like-cpanfile>

Shows dependencies in cpanfile syntax.

=item B<--save-cpanfile>

Could be used only with C<--like-cpanfile> option. Saves cpanfile to the working directory.

=item B<--force>

Could be used only with C<--like-cpanfile> and C<--save-cpanfile> options. Overwrites cpanfile to the working directory.

=back

=head1 SEE ALSO
Expand Down