From 8310f8b5aa3e9f92a9225afe10dc5570a01d89c5 Mon Sep 17 00:00:00 2001 From: Dmitry Tarasov Date: Tue, 15 Jan 2019 14:29:18 +0300 Subject: [PATCH 1/9] include missing modules option was added --- .gitignore | 2 ++ lib/Module/ScanDeps.pm | 24 ++++++++++++++++-------- script/scandeps.pl | 15 +++++++++++---- 3 files changed, 29 insertions(+), 12 deletions(-) diff --git a/.gitignore b/.gitignore index 3c4a0ae..ac034b2 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,5 @@ MANIFEST.bak blib/ pm_to_blib *.tar.gz +.vstags +local \ No newline at end of file diff --git a/lib/Module/ScanDeps.pm b/lib/Module/ScanDeps.pm index eaa7c03..4e9f3e4 100644 --- a/lib/Module/ScanDeps.pm +++ b/lib/Module/ScanDeps.pm @@ -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 { @@ -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; @@ -696,6 +698,7 @@ sub scan_deps_static { modules => \@preload, skip => $args->{skip}, warn_missing => $args->{warn_missing}, + include_missing => $args->{include_missing}, ); } } @@ -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 @@ -1095,8 +1099,11 @@ 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}); + if(not $file or $file eq 'MISSING') { + _warn_of_missing_module($module, $args{warn_missing}); + next unless $args{include_missing}; + } next if $skip->{$file}; if (exists $rv->{$module}) { @@ -1144,6 +1151,8 @@ 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) { @@ -1151,9 +1160,7 @@ sub _find_in_inc { } # absolute file names - return $file if -f $file; - - return; + return -f $file ? $file : $include_missing; } sub _glob_in_inc { @@ -1504,6 +1511,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; diff --git a/script/scandeps.pl b/script/scandeps.pl index bed7668..783599a 100644 --- a/script/scandeps.pl +++ b/script/scandeps.pl @@ -22,6 +22,8 @@ "T|modtree", "V|verbose", "x|execute", + "m|include-missing", + "like-cpanfile", ) or die $usage; my (%map, %skip); @@ -59,9 +61,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); @@ -79,7 +81,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}; @@ -108,8 +114,9 @@ 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}); - + # warn Dumper $mod; + my $version = ($opts{m} and $mod->{type} eq 'missing') ? 0 : MM->parse_version($mod->{file}); + # warn $version; if (!$verbose) { printf "%-${len}s => '$version',", "'$mod->{name}'" if $version; } else { From 03811179b18b201ec0f032797a1775a94b6ae9b7 Mon Sep 17 00:00:00 2001 From: Dmitry Tarasov Date: Tue, 15 Jan 2019 14:39:55 +0300 Subject: [PATCH 2/9] no-versions and like-cpanfile options --- script/scandeps.pl | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/script/scandeps.pl b/script/scandeps.pl index 783599a..3702a5e 100644 --- a/script/scandeps.pl +++ b/script/scandeps.pl @@ -24,6 +24,7 @@ "x|execute", "m|include-missing", "like-cpanfile", + 'no-versions', ) or die $usage; my (%map, %skip); @@ -117,7 +118,11 @@ # warn Dumper $mod; my $version = ($opts{m} and $mod->{type} eq 'missing') ? 0 : MM->parse_version($mod->{file}); # warn $version; - if (!$verbose) { + if($opts{'like-cpanfile'}) { + $version = 0 if $opts{'no-versions'}; + printf "requires '%s', %s;", $mod->{name}, $version eq 'undef' ? 0 : $version; + } + elsif (!$verbose) { printf "%-${len}s => '$version',", "'$mod->{name}'" if $version; } else { printf "%-${len}s => '0', # ", "'$mod->{name}'"; From 41c16aafd1b0c977e32dfabbf08314c46d8dc6b4 Mon Sep 17 00:00:00 2001 From: Dmitry Tarasov Date: Tue, 15 Jan 2019 14:48:16 +0300 Subject: [PATCH 3/9] save-cpanfile option saves cpanfile in workdir --- script/scandeps.pl | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/script/scandeps.pl b/script/scandeps.pl index 3702a5e..f897c97 100644 --- a/script/scandeps.pl +++ b/script/scandeps.pl @@ -24,6 +24,7 @@ "x|execute", "m|include-missing", "like-cpanfile", + "save-cpanfile", 'no-versions', ) or die $usage; @@ -114,13 +115,20 @@ print "#\n# Legend: [C]ore [X]ternal [S]ubmodule [?]NotOnCPAN\n" if $verbose; +my $cpanfile_fh; +if ($opts{'save-cpanfile'}) { + open($cpanfile_fh, $opts{force} ? '>' : '+>', "cpanfile") or die "Attention! Cant open cpanfile. $!. Use `--force` option to overwrite it." +} + 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'}; - printf "requires '%s', %s;", $mod->{name}, $version eq 'undef' ? 0 : $version; + my $cpanfile_str = "requires '%s', %s;", $mod->{name}, $version eq 'undef' ? 0 : $version; + if($cpanfile_fh) { printf $cpanfile_fh $cpanfile_str } + else { printf $cpanfile_str } } elsif (!$verbose) { printf "%-${len}s => '$version',", "'$mod->{name}'" if $version; From 8b9fee3b99e27b10ee60a134f5fd92db455b6efc Mon Sep 17 00:00:00 2001 From: Dmitry Tarasov Date: Tue, 15 Jan 2019 15:01:14 +0300 Subject: [PATCH 4/9] Check options combintaions. Documentation for --include-missing --like-cpanfile --save-cpanfile --no-versions --force options --- script/scandeps.pl | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/script/scandeps.pl b/script/scandeps.pl index f897c97..68f18ee 100644 --- a/script/scandeps.pl +++ b/script/scandeps.pl @@ -25,9 +25,13 @@ "m|include-missing", "like-cpanfile", "save-cpanfile", - 'no-versions', + "no-versions", + "force" ) 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}; @@ -116,7 +120,7 @@ print "#\n# Legend: [C]ore [X]ternal [S]ubmodule [?]NotOnCPAN\n" if $verbose; my $cpanfile_fh; -if ($opts{'save-cpanfile'}) { +if ($opts{'save-cpanfile'} and $opts{'like-cpanfile'}) { open($cpanfile_fh, $opts{force} ? '>' : '+>', "cpanfile") or die "Attention! Cant open cpanfile. $!. Use `--force` option to overwrite it." } @@ -254,6 +258,29 @@ =head1 OPTIONS Retrieves module information from CPAN if you have B installed. +no-versions +force + +=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 From 04bac9857aaecb9dcd13937f74eac7ce95cd2666 Mon Sep 17 00:00:00 2001 From: Dmitry Tarasov Date: Tue, 15 Jan 2019 15:46:30 +0300 Subject: [PATCH 5/9] files-from-workdir option added --- script/scandeps.pl | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/script/scandeps.pl b/script/scandeps.pl index 68f18ee..68fc821 100644 --- a/script/scandeps.pl +++ b/script/scandeps.pl @@ -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"; @@ -26,7 +27,8 @@ "like-cpanfile", "save-cpanfile", "no-versions", - "force" + "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'}); @@ -39,6 +41,19 @@ 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'); +} + if ($eval) { require File::Temp; my ($fh, $filename) = File::Temp::tempfile( UNLINK => 1 ); @@ -261,6 +276,12 @@ =head1 OPTIONS 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. From d76b8a06a26ccfec8a958f295dd606104bdff1df Mon Sep 17 00:00:00 2001 From: Dmitry Tarasov Date: Tue, 15 Jan 2019 16:14:05 +0300 Subject: [PATCH 6/9] force warning fix cpanfile printing fix --- script/scandeps.pl | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/script/scandeps.pl b/script/scandeps.pl index 68fc821..4793245 100644 --- a/script/scandeps.pl +++ b/script/scandeps.pl @@ -136,7 +136,8 @@ my $cpanfile_fh; if ($opts{'save-cpanfile'} and $opts{'like-cpanfile'}) { - open($cpanfile_fh, $opts{force} ? '>' : '+>', "cpanfile") or die "Attention! Cant open cpanfile. $!. Use `--force` option to overwrite it." + 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. $!."; } foreach my $mod (sort { $a->{name} cmp $b->{name} } @todo ) { @@ -145,9 +146,13 @@ # warn $version; if($opts{'like-cpanfile'}) { $version = 0 if $opts{'no-versions'}; - my $cpanfile_str = "requires '%s', %s;", $mod->{name}, $version eq 'undef' ? 0 : $version; - if($cpanfile_fh) { printf $cpanfile_fh $cpanfile_str } - else { printf $cpanfile_str } + # 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; From 21f86dacb74b157d82a39ee63c3cbd30d3daef98 Mon Sep 17 00:00:00 2001 From: Dmitry Tarasov Date: Tue, 15 Jan 2019 16:20:38 +0300 Subject: [PATCH 7/9] uninitialized file fix --- lib/Module/ScanDeps.pm | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/lib/Module/ScanDeps.pm b/lib/Module/ScanDeps.pm index 4e9f3e4..e06c322 100644 --- a/lib/Module/ScanDeps.pm +++ b/lib/Module/ScanDeps.pm @@ -1100,10 +1100,9 @@ sub add_deps { foreach my $module (@{ $args{modules} }) { my $file = _find_in_inc($module, $args{include_missing}); - if(not $file or $file eq 'MISSING') { - _warn_of_missing_module($module, $args{warn_missing}); - next unless $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}) { From fc31715b319feac9903129b477bee16bf5eb0064 Mon Sep 17 00:00:00 2001 From: Dmitry Tarasov Date: Tue, 15 Jan 2019 18:17:31 +0300 Subject: [PATCH 8/9] debug commented --- script/scandeps.pl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/script/scandeps.pl b/script/scandeps.pl index 4793245..1ab2556 100644 --- a/script/scandeps.pl +++ b/script/scandeps.pl @@ -52,6 +52,8 @@ wanted => sub { push @ARGV, $_ if /\.pm$/ }, no_chdir => 1, }, 'lib'); + + # warn "Files found: ", join ", ", @ARGV; } if ($eval) { From a2dbaf76233cf200496c88633b4d3b6f8d054720 Mon Sep 17 00:00:00 2001 From: Dmitry Tarasov Date: Tue, 15 Jan 2019 18:49:39 +0300 Subject: [PATCH 9/9] version must be in quotes --- script/scandeps.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script/scandeps.pl b/script/scandeps.pl index 1ab2556..b2e971a 100644 --- a/script/scandeps.pl +++ b/script/scandeps.pl @@ -149,7 +149,7 @@ 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); + 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 }