Merge pull request #2 from seveas/master

Several new features for even more usefulness
This commit is contained in:
Steven Pritchard committed 2011-08-31 09:55:00 -07:00
commit 84d26ab5af
1 file changed
+84 -17
+84 -17
View File
@@ -26,6 +26,7 @@ cpanspec [options] [file [...]]
Options: Options:
--help -h Help message --help -h Help message
--old -o Be more compatible with old RHL/FC releases --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 --license -l Include generated license texts if absent in source
--noprefix -n Don't add perl- prefix to package name --noprefix -n Don't add perl- prefix to package name
--force -f Force overwriting existing spec --force -f Force overwriting existing spec
@@ -86,6 +87,11 @@ Includes a hack to remove LD_RUN_PATH from Makefile.
=back =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> =item B<-l>, B<--license>
Generate COPYING and Artistic license texts if the source doesn't seem Generate COPYING and Artistic license texts if the source doesn't seem
@@ -103,6 +109,10 @@ Force overwriting an existing spec file. Normally B<cpanspec> will
refuse to overwrite an existing spec file for safety. This option refuse to overwrite an existing spec file for safety. This option
removes that safety check. Please use with caution. 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> =item B<-p>, B<--packager>
The name and email address of the packager. Overrides the C<%packager> The name and email address of the packager. Overrides the C<%packager>
@@ -204,6 +214,7 @@ use File::Basename;
use LWP::UserAgent; use LWP::UserAgent;
use Parse::CPAN::Packages; use Parse::CPAN::Packages;
use Pod::Simple::TextContent; use Pod::Simple::TextContent;
use Module::CoreList;
# Apparently gets pulled in by another module. # Apparently gets pulled in by another module.
#use Cwd; #use Cwd;
@@ -211,9 +222,11 @@ our %opt;
our $help=0; our $help=0;
our $compat=0; our $compat=0;
our $perl_version=0;
our $addlicense=0; our $addlicense=0;
our $noprefix=0; our $noprefix=0;
our $force=0; our $force=0;
our $stdout=0;
our $packager; our $packager;
our $release=1; our $release=1;
our $epoch; our $epoch;
@@ -260,6 +273,15 @@ my @MACROS = (
# this is set after the parameters are passed # this is set after the parameters are passed
our %macro; 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 { sub print_version {
print "$NAME version $VERSION\n"; print "$NAME version $VERSION\n";
exit 0; exit 0;
@@ -518,9 +540,11 @@ setlocale(LC_ALL, "en_US.UTF-8");
GetOptions( GetOptions(
'help|h' => \$help, 'help|h' => \$help,
'old|o' => \$compat, 'old|o' => \$compat,
'perl-version|P=s' => \$perl_version,
'license|l' => \$addlicense, 'license|l' => \$addlicense,
'noprefix|n' => \$noprefix, 'noprefix|n' => \$noprefix,
'force|f' => \$force, 'force|f' => \$force,
'stdout|S' => \$stdout,
'packager|p=s' => \$packager, 'packager|p=s' => \$packager,
'release|r=i' => \$release, 'release|r=i' => \$release,
'epoch|e=i' => \$epoch, 'epoch|e=i' => \$epoch,
@@ -563,20 +587,33 @@ if (!$packager or $packager eq "\%packager") {
our %corelist; our %corelist;
my $rpm=new FileHandle "rpm -q --provides perl|" if($perl_version) {
or warn "Failed to execute rpm: $!\n"; 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>) { while (my $provides=<$rpm>) {
chomp $provides; chomp $provides;
if ($provides=~/^perl\(([^\)]+)\)(?:\s+=\s+(\S+))\s*$/) { if ($provides=~/^perl\(([^\)]+)\)(?:\s+=\s+(\S+))\s*$/) {
$corelist{$1}=defined($2) ? $2 : 0; $corelist{$1}=defined($2) ? $2 : 0;
}
} }
} }
my @args=@ARGV; my @args=@ARGV;
my @processed=(); 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) { for my $file (@args) {
my ($name,$version,$type); my ($name,$version,$type);
@@ -598,11 +635,6 @@ for my $file (@args) {
$file =~ s/-/::/g; $file =~ s/-/::/g;
# Look up $file in 02packages.details.txt. # 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); my ($m,$d);
if ($m=$packages->package($file) and $d=$m->distribution()) { if ($m=$packages->package($file) and $d=$m->distribution()) {
$source=$cpan . "/authors/id/" . $d->prefix(); $source=$cpan . "/authors/id/" . $d->prefix();
@@ -791,7 +823,9 @@ for my $file (@args) {
verbose "Writing $specfile..."; verbose "Writing $specfile...";
my $spec; my $spec;
if ($force) { if ($stdout) {
$spec = *STDOUT;
} elsif ($force) {
rename($specfile, "$specfile~") if (-e $specfile); rename($specfile, "$specfile~") if (-e $specfile);
$spec=new FileHandle ">$specfile"; $spec=new FileHandle ">$specfile";
} else { } else {
@@ -809,7 +843,18 @@ for my $file (@args) {
my $license=""; my $license="";
# TODO It's possible these need to be listed instead of just detected. # 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 (%build_requires,%requires);
my ($yml,$meta); my ($yml,$meta);
if (grep /^META\.yml$/, @files if (grep /^META\.yml$/, @files
@@ -823,6 +868,7 @@ for my $file (@args) {
} }
%build_requires=%{$meta->{build_requires}} if ($meta->{build_requires}); %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}); %requires=%{$meta->{requires}} if ($meta->{requires});
if ($meta->{recommends}) { if ($meta->{recommends}) {
for my $dep (keys(%{$meta->{recommends}})) { for my $dep (keys(%{$meta->{recommends}})) {
@@ -901,16 +947,29 @@ for my $file (@args) {
#print STDERR "$testfile: @{[$extract_o_matic->array()]}\n"; #print STDERR "$testfile: @{[$extract_o_matic->array()]}\n";
for my $dep ($extract_o_matic->array()) { for my $dep ($extract_o_matic->array()) {
next if ($dep eq $module); 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; my $usebuildpl=0;
if (grep /^Build\.PL$/, @files) { if (grep /^Build\.PL$/, @files) {
$build_requires{'Module::Build'}=0; $build_requires{'Module::Build'} ||= 0;
$usebuildpl=1; $usebuildpl=1;
} else { } else {
$build_requires{'ExtUtils::MakeMaker'}=0; $build_requires{'ExtUtils::MakeMaker'} ||= 0;
} }
if (!$usebuildpl) { if (!$usebuildpl) {
@@ -994,6 +1053,7 @@ END
} }
if (defined($build_requires{perl})) { if (defined($build_requires{perl})) {
$build_requires{perl} =~ s/^[<>=]+ *//;
printf $spec "%-16s%s >= %s\n", "BuildRequires:", "perl", printf $spec "%-16s%s >= %s\n", "BuildRequires:", "perl",
(($build_requires{perl} lt "5.6.0" ? "0:" : "1:") (($build_requires{perl} lt "5.6.0" ? "0:" : "1:")
. $build_requires{perl}) if $build_requires{perl}; . $build_requires{perl}) if $build_requires{perl};
@@ -1005,7 +1065,8 @@ END
} }
for my $dep (sort(keys(%build_requires))) { 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); next if (!$compat);
} elsif ($follow) { } elsif ($follow) {
if ($dep ne $module and !(grep { $_ eq $dep } @processed, @args)) { if ($dep ne $module and !(grep { $_ eq $dep } @processed, @args)) {
@@ -1105,6 +1166,12 @@ END
\%build \%build
END END
if($uses_autoinstall) {
print $spec <<END
export PERL_AUTOINSTALL="--skipdeps"
END
}
if ($usebuildpl) { if ($usebuildpl) {
print $spec <<END; print $spec <<END;
\%{__perl} Build.PL installdirs=vendor@{[$noarch ? '' : qq{ optimize="$macro{optimize}"} ]} \%{__perl} Build.PL installdirs=vendor@{[$noarch ? '' : qq{ optimize="$macro{optimize}"} ]}