summaryrefslogtreecommitdiff
path: root/testing/perl
diff options
context:
space:
mode:
Diffstat (limited to 'testing/perl')
-rw-r--r--testing/perl/0001-Append-CFLAGS-and-LDFLAGS-to-their-Config.pm-counter.patch83
-rw-r--r--testing/perl/ChangeLog66
-rw-r--r--testing/perl/PKGBUILD117
-rw-r--r--testing/perl/fix-h2ph-and-tests.patch104
-rw-r--r--testing/perl/perl.install10
-rw-r--r--testing/perl/perlbin.csh15
-rwxr-xr-xtesting/perl/perlbin.sh18
-rw-r--r--testing/perl/provides.pl286
8 files changed, 699 insertions, 0 deletions
diff --git a/testing/perl/0001-Append-CFLAGS-and-LDFLAGS-to-their-Config.pm-counter.patch b/testing/perl/0001-Append-CFLAGS-and-LDFLAGS-to-their-Config.pm-counter.patch
new file mode 100644
index 000000000..1404460df
--- /dev/null
+++ b/testing/perl/0001-Append-CFLAGS-and-LDFLAGS-to-their-Config.pm-counter.patch
@@ -0,0 +1,83 @@
+From bb249b0b26c2e79a6f55355ef94889070f07fd21 Mon Sep 17 00:00:00 2001
+From: Niko Tyni <ntyni@debian.org>
+Date: Thu, 28 Apr 2011 09:18:54 +0300
+Subject: [PATCH] Append CFLAGS and LDFLAGS to their Config.pm counterparts in
+ EU::CBuilder
+
+Since ExtUtils::CBuilder 0.27_04 (bleadperl commit 06e8058f27e4),
+CFLAGS and LDFLAGS from the environment have overridden the Config.pm
+ccflags and ldflags settings. This can cause binary incompatibilities
+between the core Perl and extensions built with EU::CBuilder.
+
+Append to the Config.pm values rather than overriding them.
+---
+ .../lib/ExtUtils/CBuilder/Base.pm | 6 +++-
+ dist/ExtUtils-CBuilder/t/04-base.t | 25 +++++++++++++++++++-
+ 2 files changed, 28 insertions(+), 3 deletions(-)
+
+diff --git a/dist/ExtUtils-CBuilder/lib/ExtUtils/CBuilder/Base.pm b/dist/ExtUtils-CBuilder/lib/ExtUtils/CBuilder/Base.pm
+index b572312..2255c51 100644
+--- a/dist/ExtUtils-CBuilder/lib/ExtUtils/CBuilder/Base.pm
++++ b/dist/ExtUtils-CBuilder/lib/ExtUtils/CBuilder/Base.pm
+@@ -40,11 +40,13 @@ sub new {
+ $self->{config}{$k} = $v unless exists $self->{config}{$k};
+ }
+ $self->{config}{cc} = $ENV{CC} if defined $ENV{CC};
+- $self->{config}{ccflags} = $ENV{CFLAGS} if defined $ENV{CFLAGS};
++ $self->{config}{ccflags} = join(" ", $self->{config}{ccflags}, $ENV{CFLAGS})
++ if defined $ENV{CFLAGS};
+ $self->{config}{cxx} = $ENV{CXX} if defined $ENV{CXX};
+ $self->{config}{cxxflags} = $ENV{CXXFLAGS} if defined $ENV{CXXFLAGS};
+ $self->{config}{ld} = $ENV{LD} if defined $ENV{LD};
+- $self->{config}{ldflags} = $ENV{LDFLAGS} if defined $ENV{LDFLAGS};
++ $self->{config}{ldflags} = join(" ", $self->{config}{ldflags}, $ENV{LDFLAGS})
++ if defined $ENV{LDFLAGS};
+
+ unless ( exists $self->{config}{cxx} ) {
+ my ($ccpath, $ccbase, $ccsfx ) = fileparse($self->{config}{cc}, qr/\.[^.]*/);
+diff --git a/dist/ExtUtils-CBuilder/t/04-base.t b/dist/ExtUtils-CBuilder/t/04-base.t
+index c3bf6b5..1bb15aa 100644
+--- a/dist/ExtUtils-CBuilder/t/04-base.t
++++ b/dist/ExtUtils-CBuilder/t/04-base.t
+@@ -1,7 +1,7 @@
+ #! perl -w
+
+ use strict;
+-use Test::More tests => 50;
++use Test::More tests => 64;
+ use Config;
+ use Cwd;
+ use File::Path qw( mkpath );
+@@ -326,6 +326,29 @@ is_deeply( $mksymlists_args,
+ "_prepare_mksymlists_args(): got expected arguments for Mksymlists",
+ );
+
++my %testvars = (
++ CFLAGS => 'ccflags',
++ LDFLAGS => 'ldflags',
++);
++
++while (my ($VAR, $var) = each %testvars) {
++ local $ENV{$VAR};
++ $base = ExtUtils::CBuilder::Base->new( quiet => 1 );
++ ok( $base, "ExtUtils::CBuilder::Base->new() returned true value" );
++ isa_ok( $base, 'ExtUtils::CBuilder::Base' );
++ like($base->{config}{$var}, qr/\Q$Config{$var}/,
++ "honours $var from Config.pm");
++
++ $ENV{$VAR} = "-foo -bar";
++ $base = ExtUtils::CBuilder::Base->new( quiet => 1 );
++ ok( $base, "ExtUtils::CBuilder::Base->new() returned true value" );
++ isa_ok( $base, 'ExtUtils::CBuilder::Base' );
++ like($base->{config}{$var}, qr/\Q$ENV{$VAR}/,
++ "honours $VAR from the environment");
++ like($base->{config}{$var}, qr/\Q$Config{$var}/,
++ "doesn't override $var from Config.pm with $VAR from the environment");
++}
++
+ #####
+
+ for ($source_file, $object_file, $lib_file) {
+--
+1.7.4.4
+
diff --git a/testing/perl/ChangeLog b/testing/perl/ChangeLog
new file mode 100644
index 000000000..9add39e20
--- /dev/null
+++ b/testing/perl/ChangeLog
@@ -0,0 +1,66 @@
+2011-06-22 Angel Velasquez <angvp@archlinux.org>
+ * Added a patch for ExtUtils doesnt overwrite CFLAGS and LDFLAGS
+ * Fixed #FS22197, FS#22441, FS#24767
+ * Rebuilt perl 5.14.1-2 against db 5.2.28
+
+2011-06-16 Angel Velasquez <angvp@archlinux.org>
+ * Fixed #FS24660
+ * Rebuilt against db 5.2.28
+
+2011-05-16 Angel Velasquez <angvp@archlinux.org>
+ * perl 5.14.0
+ * Removed patch for h2ph warning from 5.12.3
+ * Removed provides array, you can use corelist -v 5.14.0 to know the
+ modules included with the perl core, through Module::CoreList (thx j3nnn1
+ for the tip)
+
+2010-11-07 kevin <kevin@archlinux.org>
+
+ * perl 5.12.2-1
+ - Using /usr/bin/*_perl for script directories
+
+2010-11-06 kevin <kevin@archlinux.org>
+
+ - Removed otherlibdirs directive from Configure
+ - Removed /usr/*/perl5/site_perl/5.10.1 from INC
+ - Finally removed legacy dirs /usr/lib/perl5/current and
+ /usr/lib/perl5/site_perl/current from @INC
+
+2010-05-23 kevin <kevin@archlinux.org>
+
+ * perl 5.12.1-2
+ - Francois updated the provides array.
+
+2010-05-23 kevin <kevin@archlinux.org>
+
+ * perl 5.12.1-1
+
+2010-05-16 kevin <kevin@archlinux.org>
+
+ * perl 5.12.0-2
+
+2010-05-12 kevin <kevin@archlinux.org>
+
+ - FS#19411. Removed the for loop in perlbin.sh which didn't work on zsh.
+ This makes the loop variables unnecessary so the script no longer
+ pollutes the user's environment.
+ - FS#19427. Added /usr/*/perl5/site_perl/5.10.1 to otherlibdirs to support
+ user built modules.
+
+2010-05-09 kevin <kevin@archlinux.org>
+
+ * perl 5.12.0-1
+ - Modified perlbin.sh to only add existing dirs to PATH. Fixes FS#17402,
+ path points to non-existant directories
+
+2010-05-07 kevin <kevin@archlinux.org>
+
+ - Added this changelog.
+ - Added -Dinc_version_list=none to fix FS#19136, double entry in @INC.
+ This removes the duplicates and versioned directory entries.
+ - Change scriptdirs to /usr/lib/perl5/{core,vendor,site}_perl/bin to fix
+ Fix FS#13808, binaries don't follow FHS.
+ - Stopped using versioned directories in sitelib and sitearch.
+
+
+# vim: set ft=changelog ts=4 sw=4 et:
diff --git a/testing/perl/PKGBUILD b/testing/perl/PKGBUILD
new file mode 100644
index 000000000..e3bd0f0c4
--- /dev/null
+++ b/testing/perl/PKGBUILD
@@ -0,0 +1,117 @@
+# $Id: PKGBUILD 146353 2012-01-09 18:52:56Z stephane $
+# Maintainer: Angel Velasquez <angvp@archlinux.org>
+# Contributor: kevin <kevin.archlinux.org>
+# Contributor: judd <jvinet.zeroflux.org>
+# Contributor: francois <francois.archlinux.org>
+pkgname=perl
+pkgver=5.14.2
+pkgrel=6
+pkgdesc="A highly capable, feature-rich programming language"
+arch=(i686 x86_64)
+license=('GPL' 'PerlArtistic')
+url="http://www.perl.org"
+groups=('base')
+depends=('gdbm' 'db' 'coreutils' 'glibc' 'sh')
+changelog=ChangeLog
+source=(http://www.cpan.org/src/5.0/perl-${pkgver}.tar.bz2
+perlbin.sh
+perlbin.csh
+provides.pl
+0001-Append-CFLAGS-and-LDFLAGS-to-their-Config.pm-counter.patch)
+install=perl.install
+options=('makeflags' '!purge')
+md5sums=('04a4c5d3c1f9f19d77daff8e8cd19a26'
+ '5ed2542fdb9a60682f215bd33701e61a'
+ '1f0cbbee783e8a6d32f01be5118e0d5e'
+ '31fc0b5bb4935414394c5cfbec2cb8e5'
+ 'c25d86206d649046538c3daab7874564')
+
+build() {
+ cd ${srcdir}/${pkgname}-${pkgver}
+
+ if [ "${CARCH}" = "x86_64" ]; then
+ # for x86_64
+ arch_opts="-Dcccdlflags='-fPIC'"
+ else
+ # for i686
+ arch_opts=""
+ fi
+
+ ./Configure -des -Dusethreads -Duseshrplib -Doptimize="${CFLAGS}" \
+ -Dprefix=/usr -Dinstallprefix=${pkgdir}/usr -Dvendorprefix=/usr \
+ -Dprivlib=/usr/share/perl5/core_perl \
+ -Darchlib=/usr/lib/perl5/core_perl \
+ -Dsitelib=/usr/share/perl5/site_perl \
+ -Dsitearch=/usr/lib/perl5/site_perl \
+ -Dvendorlib=/usr/share/perl5/vendor_perl \
+ -Dvendorarch=/usr/lib/perl5/vendor_perl \
+ -Dscriptdir=/usr/bin/core_perl \
+ -Dsitescript=/usr/bin/site_perl \
+ -Dvendorscript=/usr/bin/vendor_perl \
+ -Dinc_version_list=none \
+ -Dman1ext=1perl -Dman3ext=3perl ${arch_opts} \
+ -Dlddlflags="-shared ${LDFLAGS}" -Dldflags="${LDFLAGS}"
+ patch -Np1 -i $srcdir/0001-Append-CFLAGS-and-LDFLAGS-to-their-Config.pm-counter.patch
+ make
+}
+
+check() {
+ cd ${srcdir}/${pkgname}-${pkgver}
+ TEST_JOBS=$(echo $MAKEFLAGS | sed 's/.*-j\([0-9][0-9]*\).*/\1/') make test_harness
+# make test
+}
+
+package() {
+ # hack to work around makepkg running the subshell in check_sanity()
+ new_provides=($(cd "$srcdir/perl-$pkgver"; LD_PRELOAD=./libperl.so ./perl -Ilib "$srcdir/provides.pl" .))
+ provides=(${new_provides[@]})
+
+ cd ${srcdir}/${pkgname}-${pkgver}
+ make install
+
+ ### Perl Settings ###
+ # Change man page extensions for site and vendor module builds.
+ # Use archlinux email address instead of my own.
+ sed -e '/^man1ext=/ s/1perl/1p/' -e '/^man3ext=/ s/3perl/3pm/' \
+ -e "/^cf_email=/ s/'.*'/'kevin@archlinux.org'/" \
+ -e "/^perladmin=/ s/'.*'/'kevin@archlinux.org'/" \
+ -i ${pkgdir}/usr/lib/perl5/core_perl/Config_heavy.pl
+
+ ### CPAN Settings ###
+ # Set CPAN default config to use the site directories.
+ sed -e '/(makepl_arg =>/ s/""/"INSTALLDIRS=site"/' \
+ -e '/(mbuildpl_arg =>/ s/""/"installdirs=site"/' \
+ -i ${pkgdir}/usr/share/perl5/core_perl/CPAN/FirstTime.pm
+
+ ### CPANPLUS Settings ###
+ # Set CPANPLUS default config to use the site directories.
+ sed -e "/{'makemakerflags'}/ s/'';/'INSTALLDIRS=site';/" \
+ -e "/{'buildflags'}/ s/'';/'installdirs=site';/" \
+ -i ${pkgdir}/usr/share/perl5/core_perl/CPANPLUS/Config.pm
+
+ # Profile script to set paths to perl scripts.
+ install -D -m755 ${srcdir}/perlbin.sh \
+ ${pkgdir}/etc/profile.d/perlbin.sh
+ # Profile script to set paths to perl scripts on csh. (FS#22441)
+ install -D -m755 ${srcdir}/perlbin.csh \
+ ${pkgdir}/etc/profile.d/perlbin.csh
+
+ (cd ${pkgdir}/usr/bin; mv perl${pkgver} perl)
+ (cd ${pkgdir}/usr/bin/core_perl; ln -sf c2ph pstruct; ln -sf s2p psed)
+ grep -Rl "${pkgdir}" ${pkgdir}/usr | \
+ xargs sed -i "s^${pkgdir}^^g"
+
+ # Remove all pod files *except* those under /usr/share/perl5/core_perl/pod/
+ # (FS#16488)
+ rm -f $pkgdir/usr/share/perl5/core_perl/*.pod
+ for d in $pkgdir/usr/share/perl5/core_perl/*; do
+ if [ -d $d -a $(basename $d) != "pod" ]; then
+ find $d -name *.pod -delete
+ fi
+ done
+ find $pkgdir/usr/lib -name *.pod -delete
+ find $pkgdir -name .packlist -delete
+ # Add /usr/lib/perl5/core_perl/CORE/ to standard library path (FS#24660)
+ install -dv ${pkgdir}/etc/ld.so.conf.d
+ echo "/usr/lib/perl5/core_perl/CORE" > ${pkgdir}/etc/ld.so.conf.d/perl.conf
+}
diff --git a/testing/perl/fix-h2ph-and-tests.patch b/testing/perl/fix-h2ph-and-tests.patch
new file mode 100644
index 000000000..a2d176ec6
--- /dev/null
+++ b/testing/perl/fix-h2ph-and-tests.patch
@@ -0,0 +1,104 @@
+From 8d66b3f930dc6d88b524d103e304308ae73a46e7 Mon Sep 17 00:00:00 2001
+From: Robin Barker <rmbarker@cpan.org>
+Date: Thu, 22 Apr 2010 11:51:20 +0100
+Subject: [PATCH 1/1] Fix h2ph and test
+
+---
+ lib/h2ph.t | 12 ++++++++++--
+ utils/h2ph.PL | 28 +++++++++++++++++++++++-----
+ 2 files changed, 33 insertions(+), 7 deletions(-)
+
+diff --git a/lib/h2ph.t b/lib/h2ph.t
+index 27dd7b9..8d62d46 100644
+--- a/lib/h2ph.t
++++ b/lib/h2ph.t
+@@ -18,7 +18,7 @@ if (!(-e $extracted_program)) {
+ exit 0;
+ }
+
+-plan(4);
++plan(5);
+
+ # quickly compare two text files
+ sub txt_compare {
+@@ -41,8 +41,16 @@ $result = runperl( progfile => 'lib/h2ph.pht',
+ stderr => 1 );
+ like( $result, qr/syntax OK$/, "output compiles");
+
++$result = runperl( progfile => '_h2ph_pre.ph',
++ switches => ['-c'],
++ stderr => 1 );
++like( $result, qr/syntax OK$/, "preamble compiles");
++
+ $result = runperl( switches => ["-w"],
+- prog => '$SIG{__WARN__} = sub { die $_[0] }; require q(lib/h2ph.pht);');
++ stderr => 1,
++ prog => <<'PROG' );
++$SIG{__WARN__} = sub { die $_[0] }; require q(lib/h2ph.pht);
++PROG
+ is( $result, '', "output free of warnings" );
+
+ # cleanup
+diff --git a/utils/h2ph.PL b/utils/h2ph.PL
+index 8f56db4..1255807 100644
+--- a/utils/h2ph.PL
++++ b/utils/h2ph.PL
+@@ -401,7 +401,10 @@ if ($opt_e && (scalar(keys %bad_file) > 0)) {
+ exit $Exit;
+
+ sub expr {
+- $new = '"(assembly code)"' and return if /\b__asm__\b/; # freak out.
++ if (/\b__asm__\b/) { # freak out
++ $new = '"(assembly code)"';
++ return
++ }
+ my $joined_args;
+ if(keys(%curargs)) {
+ $joined_args = join('|', keys(%curargs));
+@@ -770,7 +773,7 @@ sub inc_dirs
+ sub build_preamble_if_necessary
+ {
+ # Increment $VERSION every time this function is modified:
+- my $VERSION = 2;
++ my $VERSION = 3;
+ my $preamble = "$Dest_dir/_h2ph_pre.ph";
+
+ # Can we skip building the preamble file?
+@@ -798,7 +801,16 @@ sub build_preamble_if_necessary
+ # parenthesized value: d=(v)
+ $define{$_} = $1;
+ }
+- if ($define{$_} =~ /^([+-]?(\d+)?\.\d+([eE][+-]?\d+)?)[FL]?$/) {
++ if (/^(\w+)\((\w)\)$/) {
++ my($macro, $arg) = ($1, $2);
++ my $def = $define{$_};
++ $def =~ s/$arg/\$\{$arg\}/g;
++ print PREAMBLE <<DEFINE;
++unless (defined &$macro) { sub $macro(\$) { my (\$$arg) = \@_; \"$def\" } }
++
++DEFINE
++ } elsif
++ ($define{$_} =~ /^([+-]?(\d+)?\.\d+([eE][+-]?\d+)?)[FL]?$/) {
+ # float:
+ print PREAMBLE
+ "unless (defined &$_) { sub $_() { $1 } }\n\n";
+@@ -807,8 +819,14 @@ sub build_preamble_if_necessary
+ print PREAMBLE
+ "unless (defined &$_) { sub $_() { $1 } }\n\n";
+ } elsif ($define{$_} =~ /^\w+$/) {
+- print PREAMBLE
+- "unless (defined &$_) { sub $_() { &$define{$_} } }\n\n";
++ my $def = $define{$_};
++ if ($isatype{$def}) {
++ print PREAMBLE
++ "unless (defined &$_) { sub $_() { \"$def\" } }\n\n";
++ } else {
++ print PREAMBLE
++ "unless (defined &$_) { sub $_() { &$def } }\n\n";
++ }
+ } else {
+ print PREAMBLE
+ "unless (defined &$_) { sub $_() { \"",
+--
+1.6.5.2.74.g610f9.dirty
+
diff --git a/testing/perl/perl.install b/testing/perl/perl.install
new file mode 100644
index 000000000..a355c5bbe
--- /dev/null
+++ b/testing/perl/perl.install
@@ -0,0 +1,10 @@
+# arg 1: the new package version
+post_install() {
+ for ver in 5.8.{0,1,2,3,4,5,6,7,8}; do
+ [ -h usr/lib/perl5/$ver ] && rm usr/lib/perl5/$ver
+ [ -h usr/lib/perl5/site_perl/$ver ] && rm usr/lib/perl5/site_perl/$ver
+ [ -h usr/bin/perl$ver ] && rm usr/bin/perl$ver
+ done
+ return 0
+}
+
diff --git a/testing/perl/perlbin.csh b/testing/perl/perlbin.csh
new file mode 100644
index 000000000..535f0b18d
--- /dev/null
+++ b/testing/perl/perlbin.csh
@@ -0,0 +1,15 @@
+# Set path to perl scriptdirs if they exist
+# https://wiki.archlinux.org/index.php/Perl_Policy#Binaries_and_Scripts
+# Added /usr/bin/*_perl dirs for scripts
+# Remove /usr/lib/perl5/*_perl/bin in next release
+
+[ -d /usr/bin/site_perl ] && setenv PATH ${PATH}:/usr/bin/site_perl
+[ -d /usr/lib/perl5/site_perl/bin ] && setenv PATH ${PATH}:/usr/lib/perl5/site_perl/bin
+
+[ -d /usr/bin/vendor_perl ] && setenv PATH ${PATH}:/usr/bin/vendor_perl
+[ -d /usr/lib/perl5/vendor_perl/bin ] && setenv PATH ${PATH}:/usr/lib/perl5/vendor_perl/bin
+
+[ -d /usr/bin/core_perl ] && setenv PATH ${PATH}:/usr/bin/core_perl
+
+# If you have modules in non-standard directories you can add them here.
+#export PERLLIB=dir1:dir2
diff --git a/testing/perl/perlbin.sh b/testing/perl/perlbin.sh
new file mode 100755
index 000000000..20f830436
--- /dev/null
+++ b/testing/perl/perlbin.sh
@@ -0,0 +1,18 @@
+# Set path to perl scriptdirs if they exist
+# https://wiki.archlinux.org/index.php/Perl_Policy#Binaries_and_Scripts
+# Added /usr/bin/*_perl dirs for scripts
+# Remove /usr/lib/perl5/*_perl/bin in next release
+
+[ -d /usr/bin/site_perl ] && PATH=$PATH:/usr/bin/site_perl
+[ -d /usr/lib/perl5/site_perl/bin ] && PATH=$PATH:/usr/lib/perl5/site_perl/bin
+
+[ -d /usr/bin/vendor_perl ] && PATH=$PATH:/usr/bin/vendor_perl
+[ -d /usr/lib/perl5/vendor_perl/bin ] && PATH=$PATH:/usr/lib/perl5/vendor_perl/bin
+
+[ -d /usr/bin/core_perl ] && PATH=$PATH:/usr/bin/core_perl
+
+export PATH
+
+# If you have modules in non-standard directories you can add them here.
+#export PERLLIB=dir1:dir2
+
diff --git a/testing/perl/provides.pl b/testing/perl/provides.pl
new file mode 100644
index 000000000..3bf369577
--- /dev/null
+++ b/testing/perl/provides.pl
@@ -0,0 +1,286 @@
+# provides.pl
+##
+# Script for printing out a provides list of every CPAN distribution
+# that is bundled with perl.
+#
+# Justin Davis <jrcd83@gmail.com>
+
+use warnings 'FATAL' => 'all';
+use strict;
+
+package Common;
+
+sub evalver
+{
+ my ($path, $mod) = @_;
+ $mod ||= "";
+
+ open my $fh, '<', $path or die "open $path: $!";
+
+ while (<$fh>) {
+ next unless /\s*(?:\$${mod}::|\$)VERSION\s*=\s*(.+)/;
+ my $ver = eval $1;
+ return $ver unless $@;
+ warn qq{$path:$. bad version string "$ver"\n};
+ }
+
+ close $fh;
+ return undef;
+}
+
+#-----------------------------------------------------------------------------
+
+package Dists;
+
+sub maindistfile
+{
+ my ($dist, $dir) = @_;
+
+ # libpath is the modern style, installing modules under lib/
+ # with dirs matching the name components.
+ my $libpath = join q{/}, 'lib', split /-/, "${dist}.pm";
+
+ # dumbpath is an old style where there's no subdirs and just
+ # a .pm file.
+ my $dumbpath = $dist;
+ $dumbpath =~ s/\A.+-//;
+ $dumbpath .= ".pm";
+
+ my @paths = ($libpath, $dumbpath);
+ # Some modules (with simple names like XSLoader, lib, etc) are
+ # generated by Makefile.PL. Search through their generating code.
+ push @paths, "${dist}_pm.PL" if $dist =~ tr/-/-/ == 0;
+
+ for my $path (map { "$dir/$_" } @paths) { return $path if -f $path; }
+ return undef;
+}
+
+sub module_ver
+{
+ my ($dist, $dir) = @_;
+
+ my $path = maindistfile($dist, $dir) or return undef;
+
+ my $mod = $dist;
+ $mod =~ s/-/::/g;
+ my $ver = Common::evalver($path, $mod);
+ unless ($ver) {
+ warn "failed to find version in module file for $dist\n";
+ return undef;
+ }
+
+ return $ver;
+}
+
+sub changelog_ver
+{
+ my ($dist, $dir) = @_;
+
+ my $path;
+ for my $tmp (glob "$dir/{Changes,ChangeLog}") {
+ if (-f $tmp) { $path = $tmp; last; }
+ }
+ return undef unless $path;
+
+ open my $fh, '<', $path or die "open: $!";
+ while (<$fh>) {
+ return $1 if /\A\s*(?:$dist[ \t]*)?([0-9._]+)/;
+ return $1 if /\A\s*version\s+([0-9._]+)/i;
+ }
+ close $fh;
+
+ return undef;
+}
+
+# for some reason podlators has a VERSION file with perl code in it
+sub verfile_ver
+{
+ my ($dist, $dir) = @_;
+
+ my $path = "$dir/VERSION";
+ return undef unless -f $path; # no warning, only podlaters has it
+
+ return Common::evalver($path);
+}
+
+# scans a directory full of nicely separated dist. directories.
+sub scan_distroot
+{
+ my ($distroot) = @_;
+ opendir my $cpand, "$distroot" or die "failed to open $distroot";
+ my @dists = grep { !/^\./ && -d "$distroot/$_" } readdir $cpand;
+ closedir $cpand;
+
+ my @found;
+ for my $dist (@dists) {
+ my $distdir = "$distroot/$dist";
+ my $ver = (module_ver($dist, $distdir)
+ || changelog_ver($dist, $distdir)
+ || verfile_ver($dist, $distdir));
+
+ if ($ver) { push @found, [ $dist, $ver ]; }
+ else { warn "failed to find version for $dist\n"; }
+ }
+ return @found;
+}
+
+sub find
+{
+ my ($srcdir) = @_;
+ return map { scan_distroot($_) } glob "$srcdir/{cpan,dist}";
+}
+
+#-----------------------------------------------------------------------------
+
+package Modules;
+
+use HTTP::Tiny qw();
+use File::Find qw();
+use File::stat;
+
+*findfile = *File::Find::find;
+
+sub cpan_provider
+{
+ my ($module) = @_;
+ my $url = "http://cpanmetadb.appspot.com/v1.0/package/$module";
+ my $http = HTTP::Tiny->new;
+ my $resp = $http->get($url);
+ return undef unless $resp->{'success'};
+
+ my ($cpanpath) = $resp->{'content'} =~ /^distfile: (.*)$/m
+ or return undef;
+
+ my $dist = $cpanpath;
+ $dist =~ s{\A.+/}{}; # remove author directory
+ $dist =~ s{-[^-]+\z}{}; # remove version and extension
+ return ($dist eq 'perl' ? undef : $dist);
+}
+
+sub find
+{
+ my ($srcdir) = @_;
+ my $libdir = "$srcdir/lib/";
+ die "failed to find $libdir directory" unless -d $libdir;
+
+ # Find only the module files that have not changed since perl
+ # was extracted. We don't want the files perl just recently
+ # installed into lib/. We processed those already.
+ my @modfiles;
+ my $finder = sub {
+ return unless /[.]pm\z/;
+ push @modfiles, $_;
+ };
+ findfile({ 'no_chdir' => 1, 'wanted' => $finder }, $libdir);
+
+ # First we have to find what the oldest ctime actually is.
+ my $oldest = time;
+ @modfiles = map {
+ my $modfile = $_;
+ my $ctime = (stat $modfile)->ctime;
+ $oldest = $ctime if $ctime < $oldest;
+ [ $modfile, $ctime ]; # save ctime for later
+ } @modfiles;
+
+ # Then we filter out any file that was created more than a
+ # few seconds after that. Process the rest.
+ my @mods;
+ for my $modfile (@modfiles) {
+ my ($mod, $ctime) = @$modfile;
+ next if $ctime - $oldest > 5; # ignore newer files
+
+ my $path = $mod;
+ $mod =~ s{[.]pm\z}{};
+ $mod =~ s{\A$libdir}{};
+ $mod =~ s{/}{::}g;
+
+ my $ver = Common::evalver($path) || q{};
+ push @mods, [ $mod, $ver ];
+ }
+
+ # Convert modules names to the dist names who provide them.
+ my %seen;
+ my @dists;
+ for my $modref (@mods) {
+ my ($mod, $ver) = @$modref;
+ my $dist = cpan_provider($mod) or next; # filter out core modules
+ next if $seen{$dist}++; # avoid duplicate dists
+ push @dists, [ $dist, $ver ];
+ }
+ return @dists;
+}
+
+#-----------------------------------------------------------------------------
+
+package Dist2Pkg;
+
+sub name
+{
+ my ($name) = @_;
+ my $orig = $name;
+
+ # Package names should be lowercase and consist of alphanumeric
+ # characters only (and hyphens!)...
+ $name =~ tr/A-Z/a-z/;
+ $name =~ tr/_+/-/; # _ and +'s converted to - (ie Tabbed-Text+Wrap)
+ $name =~ tr/-a-z0-9+//cd; # Delete all other chars.
+ $name =~ tr/-/-/s;
+
+ # Delete leading or trailing hyphens...
+ $name =~ s/\A-|-\z//g;
+
+ die qq{Dist. name '$orig' completely violates packaging standards}
+ unless $name;
+
+ return "perl-$name";
+}
+
+sub version
+{
+ my ($version) = @_;
+
+ # Package versions should be numbers and decimal points only...
+ $version =~ tr/-/./;
+ $version =~ tr/_0-9.-//cd;
+
+ # Remove developer versions because pacman has no special logic
+ # to compare them to regular versions like perl does.
+ $version =~ s/_[^_]+\z//;
+
+ $version =~ tr/_//d; # delete other underscores
+ $version =~ tr/././s; # only one period at a time
+ $version =~ s/\A[.]|[.]\z//g; # shouldn't start or stop with a period
+
+ return $version;
+}
+
+#-----------------------------------------------------------------------------
+
+package main;
+
+my %CPANNAME = ('List-Util' => 'Scalar-List-Utils',
+ 'Text-Tabs' => 'Text-Tabs+Wrap',
+ 'Cwd' => 'PathTools');
+
+my $perldir = shift or die "Usage: $0 [path to perl source directory]\n";
+die "$perldir is not a valid directory." unless -d $perldir;
+
+my @dists = (Dists::find($perldir), Modules::find($perldir));
+for my $dist (@dists) {
+ my $name = $dist->[0];
+ $dist->[0] = $CPANNAME{$name} if exists $CPANNAME{$name};
+}
+
+my @pkgs = map {
+ my ($name, $ver) = @$_;
+ $name = Dist2Pkg::name($name);
+ $ver = Dist2Pkg::version($ver);
+ [ $name, $ver ];
+} @dists;
+
+@pkgs = sort { $a->[0] cmp $b->[0] } @pkgs;
+
+for my $pkg (@pkgs) {
+ my ($name, $ver) = @$pkg;
+ print "$name=$ver\n";
+}