In perl.git, the branch blead has been updated <http://perl5.git.perl.org/perl.git/commitdiff/4b07058c0374cb0e43fa6b403601418410442436?hp=0d0268b0705058782fcff32c6184f87f39b5ae3b>
- Log ----------------------------------------------------------------- commit 4b07058c0374cb0e43fa6b403601418410442436 Author: Ricardo Signes <[email protected]> Date: Sat Jan 26 08:28:50 2013 -0500 Import Config-Perl-V 0.16 ----------------------------------------------------------------------- Summary of changes: MANIFEST | 5 + Porting/Maintainers.pl | 8 + cpan/Config-Perl-V/V.pm | 505 ++++++++++++++++++++++++++++++++++++++++ cpan/Config-Perl-V/t/00_pod.t | 7 + cpan/Config-Perl-V/t/01_pod.t | 7 + cpan/Config-Perl-V/t/10_base.t | 35 +++ cpan/Config-Perl-V/t/20_plv.t | 57 +++++ 7 files changed, 624 insertions(+), 0 deletions(-) create mode 100644 cpan/Config-Perl-V/V.pm create mode 100644 cpan/Config-Perl-V/t/00_pod.t create mode 100644 cpan/Config-Perl-V/t/01_pod.t create mode 100644 cpan/Config-Perl-V/t/10_base.t create mode 100644 cpan/Config-Perl-V/t/20_plv.t diff --git a/MANIFEST b/MANIFEST index 50e2d47..a510591 100644 --- a/MANIFEST +++ b/MANIFEST @@ -279,6 +279,11 @@ cpan/Compress-Raw-Zlib/zlib-src/zlib.h Compress::Raw::Zlib cpan/Compress-Raw-Zlib/zlib-src/zutil.c Compress::Raw::Zlib cpan/Compress-Raw-Zlib/zlib-src/zutil.h Compress::Raw::Zlib cpan/Compress-Raw-Zlib/Zlib.xs Compress::Raw::Zlib +cpan/Config-Perl-V/t/00_pod.t Config::Perl::V +cpan/Config-Perl-V/t/01_pod.t Config::Perl::V +cpan/Config-Perl-V/t/10_base.t Config::Perl::V +cpan/Config-Perl-V/t/20_plv.t Config::Perl::V +cpan/Config-Perl-V/V.pm Config::Perl::V cpan/CPAN/Changes CPAN.pm Changes file cpan/CPAN/lib/App/Cpan.pm helper package for CPAN.pm cpan/CPAN/lib/CPAN/API/HOWTO.pod recipe book for programming with CPAN.pm diff --git a/Porting/Maintainers.pl b/Porting/Maintainers.pl index f2b9693..0cd3986 100755 --- a/Porting/Maintainers.pl +++ b/Porting/Maintainers.pl @@ -35,6 +35,7 @@ use File::Glob qw(:case); 'gbarr' => 'Graham Barr <[email protected]>', 'gaas' => 'Gisle Aas <[email protected]>', 'gsar' => 'Gurusamy Sarathy <[email protected]>', + 'hmbrand' => 'H.Merijn Brand <[email protected]>', 'ilyam' => 'Ilya Martynov <[email protected]>', 'ilyaz' => 'Ilya Zakharevich <[email protected]>', 'jand' => 'Jan Dubois <[email protected]>', @@ -386,6 +387,13 @@ use File::Glob qw(:case); 'UPSTREAM' => 'cpan', }, + 'Config::Perl::V' => { + 'MAINTAINER' => 'hmbrand', + 'DISTRIBUTION' => 'HMBRAND/Config-Perl-V-0.16.tgz', + 'FILES' => q[cpan/Config-Perl-V], + 'UPSTREAM' => 'cpan', + }, + 'constant' => { 'MAINTAINER' => 'saper', 'DISTRIBUTION' => 'SAPER/constant-1.25.tar.gz', diff --git a/cpan/Config-Perl-V/V.pm b/cpan/Config-Perl-V/V.pm new file mode 100644 index 0000000..d70ed81 --- /dev/null +++ b/cpan/Config-Perl-V/V.pm @@ -0,0 +1,505 @@ +#!/pro/bin/perl + +package Config::Perl::V; + +use strict; +use warnings; + +use Config; +use Exporter; +use vars qw($VERSION @ISA @EXPORT_OK %EXPORT_TAGS); +$VERSION = "0.16"; +@ISA = ("Exporter"); +@EXPORT_OK = qw( plv2hash summary myconfig signature ); +%EXPORT_TAGS = ( + all => [ @EXPORT_OK ], + sig => [ "signature" ], + ); + +# Characteristics of this binary (from libperl): +# Compile-time options: DEBUGGING PERL_DONT_CREATE_GVSV PERL_MALLOC_WRAP +# USE_64_BIT_INT USE_LARGE_FILES USE_PERLIO + +# The list are as the perl binary has stored it in PL_bincompat_options +# search for it in +# perl.c line 1661 S_Internals_V () +# perl.h line 4664 (second block), +my %BTD = map { $_ => 0 } qw( + + DEBUGGING + NO_MATHOMS + PERL_DISABLE_PMC + PERL_DONT_CREATE_GVSV + PERL_IS_MINIPERL + PERL_MALLOC_WRAP + PERL_MEM_LOG + PERL_MEM_LOG_ENV + PERL_MEM_LOG_ENV_FD + PERL_MEM_LOG_NOIMPL + PERL_MEM_LOG_STDERR + PERL_MEM_LOG_TIMESTAMP + PERL_PRESERVE_IVUV + PERL_RELOCATABLE_INCPUSH + PERL_USE_DEVEL + PERL_USE_SAFE_PUTENV + UNLINK_ALL_VERSIONS + USE_ATTRIBUTES_FOR_PERLIO + USE_FAST_STDIO + USE_LOCALE + USE_PERL_ATOF + USE_SITECUSTOMIZE + + DEBUG_LEAKING_SCALARS + DEBUG_LEAKING_SCALARS_FORK_DUMP + DECCRTL_SOCKETS + FAKE_THREADS + FCRYPT + HAS_TIMES + MULTIPLICITY + MYMALLOC + PERLIO_LAYERS + PERL_DEBUG_READONLY_OPS + PERL_GLOBAL_STRUCT + PERL_IMPLICIT_CONTEXT + PERL_IMPLICIT_SYS + PERL_MAD + PERL_MICRO + PERL_NEED_APPCTX + PERL_NEED_TIMESBASE + PERL_OLD_COPY_ON_WRITE + PERL_NEW_COPY_ON_WRITE + PERL_POISON + PERL_SAWAMPERSAND + PERL_TRACK_MEMPOOL + PERL_USES_PL_PIDSTATUS + PL_OP_SLAB_ALLOC + THREADS_HAVE_PIDS + USE_64_BIT_ALL + USE_64_BIT_INT + USE_IEEE + USE_ITHREADS + USE_LARGE_FILES + USE_LOCALE_COLLATE + USE_LOCALE_NUMERIC + USE_LONG_DOUBLE + USE_PERLIO + USE_REENTRANT_API + USE_SFIO + USE_SOCKS + VMS_DO_SOCKETS + VMS_SHORTEN_LONG_SYMBOLS + VMS_SYMBOL_CASE_AS_IS + ); + +# These are all the keys that are +# 1. Always present in %Config (first block) +# 2. Reported by 'perl -V' (the rest) +my @config_vars = qw( + + api_subversion + api_version + api_versionstring + archlibexp + dont_use_nlink + d_readlink + d_symlink + exe_ext + inc_version_list + ldlibpthname + patchlevel + path_sep + perl_patchlevel + privlibexp + scriptdir + sitearchexp + sitelibexp + subversion + usevendorprefix + version + + git_commit_id + git_describe + git_branch + git_uncommitted_changes + git_commit_id_title + git_snapshot_date + + package revision version_patchlevel_string + + osname osvers archname + myuname + config_args + hint useposix d_sigaction + useithreads usemultiplicity + useperlio d_sfio uselargefiles usesocks + use64bitint use64bitall uselongdouble + usemymalloc bincompat5005 + + cc ccflags + optimize + cppflags + ccversion gccversion gccosandvers + intsize longsize ptrsize doublesize byteorder + d_longlong longlongsize d_longdbl longdblsize + ivtype ivsize nvtype nvsize lseektype lseeksize + alignbytes prototype + + ld ldflags + libpth + libs + perllibs + libc so useshrplib libperl + gnulibc_version + + dlsrc dlext d_dlsymun ccdlflags + cccdlflags lddlflags + ); + +my %empty_build = ( + osname => "", + stamp => 0, + options => { %BTD }, + patches => [], + ); + +sub _make_derived +{ + my $conf = shift; + + for ( [ lseektype => "Off_t" ], + [ myuname => "uname" ], + [ perl_patchlevel => "patch" ], + ) { + my ($official, $derived) = @$_; + $conf->{config}{$derived} ||= $conf->{config}{$official}; + $conf->{config}{$official} ||= $conf->{config}{$derived}; + $conf->{derived}{$derived} = delete $conf->{config}{$derived}; + } + + if (exists $conf->{config}{version_patchlevel_string} && + !exists $conf->{config}{api_version}) { + my $vps = $conf->{config}{version_patchlevel_string}; + $vps =~ s{\b revision \s+ (\S+) }{}x and + $conf->{config}{revision} ||= $1; + + $vps =~ s{\b version \s+ (\S+) }{}x and + $conf->{config}{api_version} ||= $1; + $vps =~ s{\b subversion \s+ (\S+) }{}x and + $conf->{config}{subversion} ||= $1; + $vps =~ s{\b patch \s+ (\S+) }{}x and + $conf->{config}{perl_patchlevel} ||= $1; + } + + ($conf->{config}{version_patchlevel_string} ||= join " ", + map { ($_, $conf->{config}{$_} ) } + grep { $conf->{config}{$_} } + qw( api_version subversion perl_patchlevel )) =~ s/\bperl_//; + + $conf->{config}{perl_patchlevel} ||= ""; # 0 is not a valid patchlevel + + if ($conf->{config}{perl_patchlevel} =~ m{^git\w*-([^-]+)}i) { + $conf->{config}{git_branch} ||= $1; + $conf->{config}{git_describe} ||= $conf->{config}{perl_patchlevel}; + } + + $conf; + } # _make_derived + +sub plv2hash +{ + my %config; + for (split m/\n+/ => join "\n", @_) { + + if (s/^Summary of my\s+(\S+)\s+\(\s*(.*?)\s*\)//) { + $config{"package"} = $1; + my $rev = $2; + $rev =~ s/^ revision \s+ (\S+) \s*//x and $config{revision} = $1; + $rev and $config{version_patchlevel_string} = $rev; + my ($rel) = $config{package} =~ m{perl(\d)}; + my ($vers, $subvers) = $rev =~ m{version\s+(\d+)\s+subversion\s+(\d+)}; + defined $vers && defined $subvers && defined $rel and + $config{version} = "$rel.$vers.$subvers"; + next; + } + + if (s/^\s+(Snapshot of:)\s+(\S+)//) { + $config{git_commit_id_title} = $1; + $config{git_commit_id} = $2; + next; + } + + my %kv = m/\G,?\s*([^=]+)=('[^']+?'|\S+)/gc; + + while (my ($k, $v) = each %kv) { + $k =~ s/\s+$//; + $v =~ s/,$//; + $v =~ m/^'(.*)'$/ and $v = $1; + $v =~ s/^\s+//; + $v =~ s/\s+$//; + $config{$k} = $v; + } + } + my $build = { %empty_build }; + $build->{osname} = $config{osname}; + return _make_derived ({ + build => $build, + environment => {}, + config => \%config, + derived => {}, + inc => [], + }); + } # plv2hash + +sub summary +{ + my $conf = shift || myconfig (); + ref $conf eq "HASH" && + exists $conf->{config} && exists $conf->{build} or return; + + my %info = map { + exists $conf->{config}{$_} ? ( $_ => $conf->{config}{$_} ) : () } + qw( archname osname osvers revision patchlevel subversion version + cc ccversion gccversion config_args inc_version_list + d_longdbl d_longlong use64bitall use64bitint useithreads + uselongdouble usemultiplicity usemymalloc useperlio useshrplib + doublesize intsize ivsize nvsize longdblsize longlongsize lseeksize + ); + $info{$_}++ for grep { $conf->{build}{options}{$_} } keys %{$conf->{build}{options}}; + + return \%info; + } # summary + +sub signature +{ + eval { require Digest::MD5 }; + $@ and return "00000000000000000000000000000000"; + + my $conf = shift || summary (); + delete $conf->{config_args}; + return Digest::MD5::md5_hex (join "\xFF" => map { + "$_=".(defined $conf->{$_} ? $conf->{$_} : "\xFE"); + } sort keys %$conf); + } # signature + +sub myconfig +{ + my $args = shift; + my %args = ref $args eq "HASH" ? %$args : + ref $args eq "ARRAY" ? @$args : (); + + my $build = { %empty_build }; + + # 5.14.0 and later provide all the information without shelling out + my $stamp = eval { Config::compile_date () }; + if (defined $stamp) { + $stamp =~ s/^Compiled at //; + $build->{osname} = $^O; + $build->{stamp} = $stamp; + $build->{patches} = [ Config::local_patches () ]; + $build->{options}{$_} = 1 for Config::bincompat_options (), + Config::non_bincompat_options (); + } + else { + #y $pv = qx[$^X -e"sub Config::myconfig{};" -V]; + my $pv = qx[$^X -V]; + $pv =~ s{.*?\n\n}{}s; + $pv =~ s{\n(?: \s+|\t\s*)}{ }g; + + #print $pv; + + $pv =~ m{^\s+Built under (.*)}m and $build->{osname} = $1; + $pv =~ m{^\s+Compiled at (.*)}m and $build->{stamp} = $1; + $pv =~ m{^\s+Locally applied patches:\s+(.*)}m and $build->{patches} = [ split m/\s+/, $1 ]; + $pv =~ m{^\s+Compile-time options:\s+(.*)}m and map { $build->{options}{$_} = 1 } split m/\s+/, $1; + } + + my @KEYS = keys %ENV; + my %env = + map { $_ => $ENV{$_} } grep m/^PERL/ => @KEYS; + $args{env} and + map { $env{$_} = $ENV{$_} } grep m{$args{env}} => @KEYS; + + my %config = map { $_ => $Config{$_} } @config_vars; + + return _make_derived ({ + build => $build, + environment => \%env, + config => \%config, + derived => {}, + inc => \@INC, + }); + } # myconfig + +1; + +__END__ + +=head1 NAME + +Config::Perl::V - Structured data retrieval of perl -V output + +=head1 SYNOPSIS + + use Config::Perl::V; + + my $local_config = Config::Perl::V::myconfig (); + print $local_config->{config}{osname}; + +=head1 DESCRIPTION + +=head2 $conf = myconfig () + +This function will collect the data described in L<the hash structure> below, +and return that as a hash reference. It optionally accepts an option to +include more entries from %ENV. See L<environment> below. + +Note that this will not work on uninstalled perls when called with +C<-I/path/to/uninstalled/perl/lib>, but it works when that path is in +C<$PERL5LIB> or in C<$PERL5OPT>, as paths passed using C<-I> are not +known when the C<-V> information is collected. + +=head2 $conf = plv2hash ($text [, ...]) + +Convert a sole 'perl -V' text block, or list of lines, to a complete +myconfig hash. All unknown entries are defaulted. + +=head2 $info = summary ([$conf]) + +Return an arbitrary selection of the information. If no C<$conf> is +given, C<myconfig ()> is used instead. + +=head2 $md5 = signature ([$conf]) + +Return the MD5 of the info returned by C<summary ()> without the +C<config_args> entry. + +If C<Digest::MD5> is not available, it return a string with only C<0>'s. + +=head2 The hash structure + +The returned hash consists of 4 parts: + +=over 4 + +=item build + +This information is extracted from the second block that is emitted by +C<perl -V>, and usually looks something like + + Characteristics of this binary (from libperl): + Compile-time options: DEBUGGING USE_64_BIT_INT USE_LARGE_FILES + Locally applied patches: + defined-or + MAINT24637 + Built under linux + Compiled at Jun 13 2005 10:44:20 + @INC: + /usr/lib/perl5/5.8.7/i686-linux-64int + /usr/lib/perl5/5.8.7 + /usr/lib/perl5/site_perl/5.8.7/i686-linux-64int + /usr/lib/perl5/site_perl/5.8.7 + /usr/lib/perl5/site_perl + . + +or + + Characteristics of this binary (from libperl): + Compile-time options: DEBUGGING MULTIPLICITY + PERL_DONT_CREATE_GVSV PERL_IMPLICIT_CONTEXT + PERL_MALLOC_WRAP PERL_TRACK_MEMPOOL + PERL_USE_SAFE_PUTENV USE_ITHREADS + USE_LARGE_FILES USE_PERLIO + USE_REENTRANT_API + Built under linux + Compiled at Jan 28 2009 15:26:59 + +This information is not available anywhere else, including C<%Config>, +but it is the information that is only known to the perl binary. + +The extracted information is stored in 5 entries in the C<build> hash: + +=over 4 + +=item osname + +This is most likely the same as C<$Config{osname}>, and was the name +known when perl was built. It might be different if perl was cross-compiled. + +The default for this field, if it cannot be extracted, is to copy +C<$Config{osname}>. The two may be differing in casing (OpenBSD vs openbsd). + +=item stamp + +This is the time string for which the perl binary was compiled. The default +value is 0. + +=item options + +This is a hash with all the known defines as keys. The value is either 0, +which means unknown or unset, or 1, which means defined. + +=item derived + +As some variables are reported by a different name in the output of C<perl -V> +than their actual name in C<%Config>, I decided to leave the C<config> entry +as close to reality as possible, and put in the entries that might have been +guessed by the printed output in a separate block. + +=item patches + +This is a list of optionally locally applied patches. Default is an empty list. + +=back + +=item environment + +By default this hash is only filled with the environment variables +out of %ENV that start with C<PERL>, but you can pass the C<env> option +to myconfig to get more + + my $conf = Config::Perl::V::myconfig ({ env => qr/^ORACLE/ }); + my $conf = Config::Perl::V::myconfig ([ env => qr/^ORACLE/ ]); + +=item config + +This hash is filled with the variables that C<perl -V> fills its report +with, and it has the same variables that C<Config::myconfig> returns +from C<%Config>. + +=item inc + +This is the list of default @INC. + +=back + +=head1 REASONING + +This module was written to be able to return the configuration for the +currently used perl as deeply as needed for the CPANTESTERS framework. +Up until now they used the output of myconfig as a single text blob, +and so it was missing the vital binary characteristics of the running +perl and the optional applied patches. + +=head1 BUGS + +Please feedback what is wrong + +=head1 TODO + + * Implement retrieval functions/methods + * Documentation + * Error checking + * Tests + +=head1 AUTHOR + +H.Merijn Brand <[email protected]> + +=head1 COPYRIGHT AND LICENSE + +Copyright (C) 2009-2013 H.Merijn Brand + +This library is free software; you can redistribute it and/or modify +it under the same terms as Perl itself. + +=cut diff --git a/cpan/Config-Perl-V/t/00_pod.t b/cpan/Config-Perl-V/t/00_pod.t new file mode 100644 index 0000000..67d0815 --- /dev/null +++ b/cpan/Config-Perl-V/t/00_pod.t @@ -0,0 +1,7 @@ +#!/usr/bin/perl + +use Test::More; + +eval "use Test::Pod 1.00"; +plan skip_all => "Test::Pod 1.00 required for testing POD" if $@; +all_pod_files_ok (); diff --git a/cpan/Config-Perl-V/t/01_pod.t b/cpan/Config-Perl-V/t/01_pod.t new file mode 100644 index 0000000..c99abc7 --- /dev/null +++ b/cpan/Config-Perl-V/t/01_pod.t @@ -0,0 +1,7 @@ +#!/usr/bin/perl + +use Test::More; + +eval "use Test::Pod::Coverage tests => 1"; +plan skip_all => "Test::Pod::Covarage required for testing POD Coverage" if $@; +pod_coverage_ok ("Config::Perl::V", "Config::Perl::V is covered"); diff --git a/cpan/Config-Perl-V/t/10_base.t b/cpan/Config-Perl-V/t/10_base.t new file mode 100644 index 0000000..b840ef5 --- /dev/null +++ b/cpan/Config-Perl-V/t/10_base.t @@ -0,0 +1,35 @@ +#!/pro/bin/perl + +use strict; +use warnings; + +BEGIN { + use Test::More; + my $tests = 9; + unless ($ENV{PERL_CORE}) { + require Test::NoWarnings; + Test::NoWarnings->import (); + $tests++; + } + + plan tests => $tests; + + use_ok ("Config::Perl::V"); + } + +ok (my $conf = Config::Perl::V::myconfig, "Read config"); +for (qw( build environment config inc )) { + ok (exists $conf->{build}, "Has build entry"); + } +is (lc $conf->{build}{osname}, lc $conf->{config}{osname}, "osname"); + +SKIP: { + # Test that the code that shells out to perl -V and parses the output + # gives the same results as the code that calls Config::* routines directly. + defined &Config::compile_date or + skip "This perl doesn't provide perl -V in the Config module", 2; + eval q{no warnings "redefine"; sub Config::compile_date { return undef }}; + is (Config::compile_date (), undef, "Successfully overriden compile_date"); + is_deeply (Config::Perl::V::myconfig, $conf, + "perl -V parsing code produces same result as the Config module"); + } diff --git a/cpan/Config-Perl-V/t/20_plv.t b/cpan/Config-Perl-V/t/20_plv.t new file mode 100644 index 0000000..a739490 --- /dev/null +++ b/cpan/Config-Perl-V/t/20_plv.t @@ -0,0 +1,57 @@ +#!/pro/bin/perl + +use strict; +use warnings; + +BEGIN { + use Test::More; + my $tests = 8; + unless ($ENV{PERL_CORE}) { + require Test::NoWarnings; + Test::NoWarnings->import (); + $tests++; + } + + plan tests => $tests; + } + +use Config::Perl::V; + +ok (my $conf = Config::Perl::V::plv2hash (<DATA>), "Read perl -v block"); +for (qw( build environment config inc )) { + ok (exists $conf->{build}, "Has build entry"); + } +is ($conf->{build}{osname}, $conf->{config}{osname}, "osname"); +is ($conf->{build}{stamp}, 0, "No build time known"); +is ($conf->{config}{version}, "5.10.0", "reconstructed \%Config{version}"); + +__END__ +Summary of my perl5 (revision 5 version 10 subversion 0) configuration: + Platform: + osname=linux, osvers=2.6.22.13-0.3-default, archname=i686-linux-64int + uname='linux nb09 2.6.22.13-0.3-default #1 smp 20071119 15:02:58 utc i686 i686 i386 gnulinux ' + config_args='-Duse64bitint -des' + hint=recommended, useposix=true, d_sigaction=define + useithreads=undef, usemultiplicity=undef + useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef + use64bitint=define, use64bitall=undef, uselongdouble=undef + usemymalloc=n, bincompat5005=undef + Compiler: + cc='cc', ccflags ='-fno-strict-aliasing -pipe -I/pro/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64', + optimize='-O2 -g', + cppflags='-fno-strict-aliasing -pipe -I/pro/local/include' + ccversion='', gccversion='4.2.1 (SUSE Linux)', gccosandvers='' + intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=12345678 + d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12 + ivtype='long long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8 + alignbytes=4, prototype=define + Linker and Libraries: + ld='cc', ldflags ='-L/pro/local/lib' + libpth=/pro/local/lib /lib /usr/lib /usr/local/lib + libs=-lnsl -lgdbm -ldb -ldl -lm -lcrypt -lutil -lc + perllibs=-lnsl -ldl -lm -lcrypt -lutil -lc + libc=/lib/libc-2.6.1.so, so=so, useshrplib=false, libperl=libperl.a + gnulibc_version='2.6.1' + Dynamic Linking: + dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E' + cccdlflags='-fPIC', lddlflags='-shared -O2 -L/pro/local/lib' -- Perl5 Master Repository
