diff --git a/cpanspec b/cpanspec index e77b2c4..0cae552 100755 --- a/cpanspec +++ b/cpanspec @@ -26,6 +26,7 @@ cpanspec [options] [file [...]] Options: --help -h Help message --old -o Be more compatible with old RHL/FC releases + --perl-version -P Minimum perl version to support --license -l Include generated license texts if absent in source --noprefix -n Don't add perl- prefix to package name --force -f Force overwriting existing spec @@ -86,6 +87,11 @@ Includes a hack to remove LD_RUN_PATH from Makefile. =back +=item B<-P>, B<--perl-version> + +Include explicit dependencies for core modules when newer versions are +required than shipped with the specified version. + =item B<-l>, B<--license> Generate COPYING and Artistic license texts if the source doesn't seem @@ -103,6 +109,10 @@ Force overwriting an existing spec file. Normally B will refuse to overwrite an existing spec file for safety. This option removes that safety check. Please use with caution. +=item B<-S>, B<--stdout> + +Write the generated spec file to stdout instead of a file. + =item B<-p>, B<--packager> The name and email address of the packager. Overrides the C<%packager> @@ -204,6 +214,7 @@ use File::Basename; use LWP::UserAgent; use Parse::CPAN::Packages; use Pod::Simple::TextContent; +use Module::CoreList; # Apparently gets pulled in by another module. #use Cwd; @@ -211,9 +222,11 @@ our %opt; our $help=0; our $compat=0; +our $perl_version=0; our $addlicense=0; our $noprefix=0; our $force=0; +our $stdout=0; our $packager; our $release=1; our $epoch; @@ -260,6 +273,15 @@ my @MACROS = ( # this is set after the parameters are passed our %macro; +our %dep_blacklist = ( + 'Win32' => 1, # We're not on win32 + 'Win32::Process' => 1, # We're not on win32 + 'Test::Perl::Critic' => 1, # Too many dependencies + 'ok' => 1, # Side effect of Test::use::ok + 'BaseClass' => 1, # Common test class shipped by ourselves + 'TestServer' => 1, # Likewise +); + sub print_version { print "$NAME version $VERSION\n"; exit 0; @@ -518,9 +540,11 @@ setlocale(LC_ALL, "en_US.UTF-8"); GetOptions( 'help|h' => \$help, 'old|o' => \$compat, + 'perl-version|P=s' => \$perl_version, 'license|l' => \$addlicense, 'noprefix|n' => \$noprefix, 'force|f' => \$force, + 'stdout|S' => \$stdout, 'packager|p=s' => \$packager, 'release|r=i' => \$release, 'epoch|e=i' => \$epoch, @@ -563,20 +587,33 @@ if (!$packager or $packager eq "\%packager") { our %corelist; -my $rpm=new FileHandle "rpm -q --provides perl|" - or warn "Failed to execute rpm: $!\n"; +if($perl_version) { + die("Unknown perl version: $perl_version. (Known versions: " . join(", ", keys %Module::CoreList::version) . ")") + unless exists $Module::CoreList::version{$perl_version}; + %corelist = %{ $Module::CoreList::version{$perl_version} }; +} +else { + my $rpm=new FileHandle "rpm -q --provides perl|" + or warn "Failed to execute rpm: $!\n"; -while (my $provides=<$rpm>) { - chomp $provides; + while (my $provides=<$rpm>) { + chomp $provides; - if ($provides=~/^perl\(([^\)]+)\)(?:\s+=\s+(\S+))\s*$/) { - $corelist{$1}=defined($2) ? $2 : 0; + if ($provides=~/^perl\(([^\)]+)\)(?:\s+=\s+(\S+))\s*$/) { + $corelist{$1}=defined($2) ? $2 : 0; + } } } my @args=@ARGV; my @processed=(); +update_packages(); +$packages=Parse::CPAN::Packages->new($pkgdetails) + if (!defined($packages)); +die "Parse::CPAN::Packages->new() failed: $!\n" + if (!defined($packages)); + for my $file (@args) { my ($name,$version,$type); @@ -598,11 +635,6 @@ for my $file (@args) { $file =~ s/-/::/g; # Look up $file in 02packages.details.txt. - update_packages(); - $packages=Parse::CPAN::Packages->new($pkgdetails) - if (!defined($packages)); - die "Parse::CPAN::Packages->new() failed: $!\n" - if (!defined($packages)); my ($m,$d); if ($m=$packages->package($file) and $d=$m->distribution()) { $source=$cpan . "/authors/id/" . $d->prefix(); @@ -791,7 +823,9 @@ for my $file (@args) { verbose "Writing $specfile..."; my $spec; - if ($force) { + if ($stdout) { + $spec = *STDOUT; + } elsif ($force) { rename($specfile, "$specfile~") if (-e $specfile); $spec=new FileHandle ">$specfile"; } else { @@ -809,7 +843,18 @@ for my $file (@args) { my $license=""; # TODO It's possible these need to be listed instead of just detected. - my $scripts=(grep /^(?:bin|scripts)\//, @files); + my $uses_autoinstall = grep /Module\/AutoInstall.pm/, @files; + my $scripts=(grep /^(?:bin|scripts?|tools)\//, @files); + my $makecontent; + if (grep /^Makefile\.PL$/, @files + and $makecontent=extract($archive, $type, "$path/Makefile.PL")) { + $scripts ||= $makecontent =~ 'install_script'; + $scripts ||= ($makecontent =~ /EXE_FILES/ && $makecontent !~ /EXE_FILES.*\[\s*(qw\(\s*\)\s*)?\]/) ? 1 : 0; + } + if (grep /^Build\.PL$/, @files + and $makecontent=extract($archive, $type, "$path/Build.PL")) { + $scripts ||= $makecontent =~ 'script_files'; + } my (%build_requires,%requires); my ($yml,$meta); if (grep /^META\.yml$/, @files @@ -823,6 +868,7 @@ for my $file (@args) { } %build_requires=%{$meta->{build_requires}} if ($meta->{build_requires}); + %build_requires=(%build_requires, %{$meta->{configure_requires}}) if ($meta->{configure_requires}); %requires=%{$meta->{requires}} if ($meta->{requires}); if ($meta->{recommends}) { for my $dep (keys(%{$meta->{recommends}})) { @@ -901,16 +947,29 @@ for my $file (@args) { #print STDERR "$testfile: @{[$extract_o_matic->array()]}\n"; for my $dep ($extract_o_matic->array()) { next if ($dep eq $module); - $build_requires{$dep}=0; + next if exists $build_requires{$dep}; + my $package = $packages->package($dep); + if(!defined($package)) { + # Don't print this for common false positives + unless($dep =~ /^(Config|base|5|lib)/) { + print STDERR "Module not on CPAN, not adding dependency: $dep\n"; + } + next; + } + if($package->distribution->dist eq $name) { + print STDERR "Dependency $dep provided by ourselves, not adding dependency\n"; + next; + } + $build_requires{$dep} ||= 0; } } my $usebuildpl=0; if (grep /^Build\.PL$/, @files) { - $build_requires{'Module::Build'}=0; + $build_requires{'Module::Build'} ||= 0; $usebuildpl=1; } else { - $build_requires{'ExtUtils::MakeMaker'}=0; + $build_requires{'ExtUtils::MakeMaker'} ||= 0; } if (!$usebuildpl) { @@ -994,6 +1053,7 @@ END } if (defined($build_requires{perl})) { + $build_requires{perl} =~ s/^[<>=]+ *//; printf $spec "%-16s%s >= %s\n", "BuildRequires:", "perl", (($build_requires{perl} lt "5.6.0" ? "0:" : "1:") . $build_requires{perl}) if $build_requires{perl}; @@ -1005,7 +1065,8 @@ END } for my $dep (sort(keys(%build_requires))) { - if (exists($corelist{$dep})) { + next if exists $dep_blacklist{$dep}; + if (exists($corelist{$dep}) && $corelist{$dep} ge $build_requires{$dep}) { next if (!$compat); } elsif ($follow) { if ($dep ne $module and !(grep { $_ eq $dep } @processed, @args)) { @@ -1105,6 +1166,12 @@ END \%build END + if($uses_autoinstall) { + print $spec <