Hello community, here is the log from the commit of package perl-Devel-Hide for openSUSE:Factory checked in at 2020-02-18 10:42:09 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/perl-Devel-Hide (Old) and /work/SRC/openSUSE:Factory/.perl-Devel-Hide.new.26092 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "perl-Devel-Hide" Tue Feb 18 10:42:09 2020 rev:6 rq:774955 version:0.0013 Changes: -------- --- /work/SRC/openSUSE:Factory/perl-Devel-Hide/perl-Devel-Hide.changes 2020-02-14 16:38:44.743631593 +0100 +++ /work/SRC/openSUSE:Factory/.perl-Devel-Hide.new.26092/perl-Devel-Hide.changes 2020-02-18 10:42:31.121203213 +0100 @@ -1,0 +2,15 @@ +Mon Feb 17 03:07:35 UTC 2020 - <timueller+p...@suse.de> + +- updated to 0.0013 + see /usr/share/doc/packages/perl-Devel-Hide/Changes + + 0.0013 2020-01-16 + + - Cope with changes to how the hints hash works in perl 5.31.7 + + 0.0012 2020-01-15 + + - Add -lexically argument to import() to support hiding modules + just during the current scope + +------------------------------------------------------------------- Old: ---- Devel-Hide-0.0011.tar.gz New: ---- Devel-Hide-0.0013.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ perl-Devel-Hide.spec ++++++ --- /var/tmp/diff_new_pack.NWCPa8/_old 2020-02-18 10:42:31.897204796 +0100 +++ /var/tmp/diff_new_pack.NWCPa8/_new 2020-02-18 10:42:31.897204796 +0100 @@ -17,7 +17,7 @@ Name: perl-Devel-Hide -Version: 0.0011 +Version: 0.0013 Release: 0 %define cpan_name Devel-Hide Summary: Forces the unavailability of specified Perl modules (for testing) @@ -70,11 +70,23 @@ There are three alternative ways to include modules in the hidden list: - * setting @Devel::Hide::HIDDEN +* import() - * environment variable DEVEL_HIDE_PM +this is probably the most commonly used method, called automagically when +you do this: - * import() + use Devel::Hide qw(Foo Bar::Baz); + +or + + perl -MDevel::Hide=... + +* setting @Devel::Hide::HIDDEN + +* environment variable DEVEL_HIDE_PM + +both of these two only support 'global' hiding, whereas 'import()' supports +lexical hiding as well. Optionally, you can provide some arguments *before* the list of modules: @@ -82,7 +94,16 @@ propagate the list of hidden modules to your process' child processes. This works by populating 'PERL5OPT', and is incompatible with Taint mode, as -explained in perlrun. +explained in perlrun. Of course, this is unnecessary if your child +processes are just forks of the current one. + +* -lexically + +This is only available on perl 5.10.0 and later. It is a fatal error to try +to use it on an older perl. + +Everything following this will only have effect until the end of the +current scope. Yes, that includes '-quiet'. * -quiet ++++++ Devel-Hide-0.0011.tar.gz -> Devel-Hide-0.0013.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Devel-Hide-0.0011/Changes new/Devel-Hide-0.0013/Changes --- old/Devel-Hide-0.0011/Changes 2020-02-13 00:50:15.000000000 +0100 +++ new/Devel-Hide-0.0013/Changes 2020-02-16 22:04:46.000000000 +0100 @@ -1,5 +1,14 @@ Revision history for Perl extension Devel::Hide. +0.0013 2020-01-16 + + - Cope with changes to how the hints hash works in perl 5.31.7 + +0.0012 2020-01-15 + + - Add -lexically argument to import() to support hiding modules + just during the current scope + 0.0011 2020-02-12 - Fix https://rt.cpan.org/Public/Bug/Display.html?id=120220 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Devel-Hide-0.0011/MANIFEST new/Devel-Hide-0.0013/MANIFEST --- old/Devel-Hide-0.0011/MANIFEST 2020-02-13 00:55:52.000000000 +0100 +++ new/Devel-Hide-0.0013/MANIFEST 2020-02-16 22:06:56.000000000 +0100 @@ -15,6 +15,7 @@ t/098pod-coverage.t Tests for POD coverage t/quiet.t Test that -quiet suppresses (some) warnings t/too-late-quiet.t Test that -quiet doesn't suppress warnings about not hiding stuff +t/lexically.t Test that restricting hiding to a lexical scope works t/P.pm Dummy module used in tests t/Q.pm " diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Devel-Hide-0.0011/META.json new/Devel-Hide-0.0013/META.json --- old/Devel-Hide-0.0011/META.json 2020-02-13 00:55:51.000000000 +0100 +++ new/Devel-Hide-0.0013/META.json 2020-02-16 22:06:56.000000000 +0100 @@ -4,13 +4,13 @@ "Adriano Ferreira <ferre...@cpan.org>" ], "dynamic_config" : 0, - "generated_by" : "ExtUtils::MakeMaker version 7.34, CPAN::Meta::Converter version 2.150010", + "generated_by" : "ExtUtils::MakeMaker version 7.24, CPAN::Meta::Converter version 2.150010", "license" : [ "perl_5" ], "meta-spec" : { "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", - "version" : 2 + "version" : "2" }, "name" : "Devel-Hide", "no_index" : { @@ -56,6 +56,6 @@ "web" : "https://github.com/aferreira/cpan-Devel-Hide" } }, - "version" : "0.0011", - "x_serialization_backend" : "JSON::PP version 4.02" + "version" : "0.0013", + "x_serialization_backend" : "JSON::PP version 2.27400_02" } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Devel-Hide-0.0011/META.yml new/Devel-Hide-0.0013/META.yml --- old/Devel-Hide-0.0011/META.yml 2020-02-13 00:55:51.000000000 +0100 +++ new/Devel-Hide-0.0013/META.yml 2020-02-16 22:06:56.000000000 +0100 @@ -8,7 +8,7 @@ configure_requires: ExtUtils::MakeMaker: '0' dynamic_config: 0 -generated_by: 'ExtUtils::MakeMaker version 7.34, CPAN::Meta::Converter version 2.150010' +generated_by: 'ExtUtils::MakeMaker version 7.24, CPAN::Meta::Converter version 2.150010' license: perl meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html @@ -23,5 +23,5 @@ perl: '5.006001' resources: repository: https://github.com/aferreira/cpan-Devel-Hide.git -version: '0.0011' +version: '0.0013' x_serialization_backend: 'CPAN::Meta::YAML version 0.018' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Devel-Hide-0.0011/lib/Devel/Hide.pm new/Devel-Hide-0.0013/lib/Devel/Hide.pm --- old/Devel-Hide-0.0011/lib/Devel/Hide.pm 2020-02-13 00:47:41.000000000 +0100 +++ new/Devel-Hide-0.0013/lib/Devel/Hide.pm 2020-02-16 22:03:55.000000000 +0100 @@ -4,76 +4,57 @@ use strict; use warnings; -our $VERSION = '0.0011'; +our $VERSION = '0.0013'; # blech! package variables -use vars qw( @HIDDEN $VERBOSE ); - -# a map ( $hidden_file => 1 ) to speed determining if a module/file is hidden -my %IS_HIDDEN; - -# whether to hide modules from ... -my %HIDE_FROM = ( - children => 0, # child processes or not +# +# @HIDDEN is one of the ways to populate the global hidden list +# $phase is used to identify which version of the hints hash to +# use - either %^H when we're updating it, or pulling it out +# of caller() when we want to read it +use vars qw( @HIDDEN $phase ); +BEGIN { $phase = 'runtime'; } + +# settings are a comma- (and only comma, no quotes or spaces) +# -separated list of key,value,key,value,... There is no +# attempt to support data containing commas. +# +# The list of hidden modules is a comma (and *only* comma, +# no white space, no quotes) separated list of module +# names. +# +# yes, this is a ridiculous way of storing data. It is, +# however, compatible with what we're going to have to +# store in the hints hash for lexical hiding, as that +# only supports string data. +my %GLOBAL_SETTINGS; +_set_setting('global', children => 0); +_set_setting('global', verbose => + defined $ENV{DEVEL_HIDE_VERBOSE} + ? $ENV{DEVEL_HIDE_VERBOSE} + : 1 ); -=begin private - -=item B<_to_filename> - - $fn = _to_filename($pm); - -Turns a Perl module name (like 'A' or 'P::Q') into -a filename ("A.pm", "P/Q.pm"). - -=end private - -=cut - -sub _to_filename { - my $pm = shift; - $pm =~ s|::|/|g; - $pm .= '.pm'; - return $pm; -} - -=begin private - -=item B<_as_filenames> - - @fn = _as_filenames(@args); - @fn = _as_filenames(qw(A.pm X B/C.pm File::Spec)); # returns qw(A.pm X.pm B/C.pm File/Spec.pm) - -Copies the argument list, turning what looks like -a Perl module name to filenames and leaving everything -else as it is. To look like a Perl module name is -to match C< /^(\w+::)*\w+$/ >. - -=end private - -=cut - +# convert a mixed list of modules and filenames to a list of +# filenames sub _as_filenames { - return map { /^(\w+::)*\w+$/ ? _to_filename($_) : $_ } @_; -} - -BEGIN { - - unless ( defined $VERBOSE ) { # unless user-defined elsewhere, set default - $VERBOSE - = defined $ENV{DEVEL_HIDE_VERBOSE} ? $ENV{DEVEL_HIDE_VERBOSE} : 1; - } - + return map { /^(\w+::)*\w+$/ + ? do { my $f = "$_.pm"; $f =~ s|::|/|g; $f } + : $_ + } @_; } # Pushes a list to the set of hidden modules/filenames # warns about the modules which could not be hidden (always) -# and about the ones that were successfully hidden (if $VERBOSE) +# and about the ones that were successfully hidden (if verbose) # # It works as a batch producing warning messages # at each invocation (when appropriate). # +# the first arg is a reference to the config hash to use, +# either global or lexical sub _push_hidden { + my $config = shift; return unless @_; @@ -83,59 +64,35 @@ push @too_late, $_; } else { - $IS_HIDDEN{$_}++; + $config->{'Devel::Hide/hidden'} = + $config->{'Devel::Hide/hidden'} + ? join(',', $config->{'Devel::Hide/hidden'}, $_) + : $_; } } if ( @too_late ) { warn __PACKAGE__, ': Too late to hide ', join( ', ', @too_late ), "\n"; } - if ( $VERBOSE && keys %IS_HIDDEN ) { - warn __PACKAGE__, ' hides ', join( ', ', sort keys %IS_HIDDEN ), "\n"; - } -} - -# $ENV{DEVEL_HIDE_PM} is split in ' ' -# as well as @HIDDEN it accepts Module::Module as well as File/Names.pm - -BEGIN { - - # unless @HIDDEN was user-defined elsewhere, set default - if ( !@HIDDEN && $ENV{DEVEL_HIDE_PM} ) { - _push_hidden( split q{ }, $ENV{DEVEL_HIDE_PM} ); - - # NOTE. "split ' ', $s" is special. Read "perldoc -f split". - } - else { - _push_hidden(@HIDDEN); + if ( _get_setting('verbose') && $config->{'Devel::Hide/hidden'}) { + no warnings 'uninitialized'; + warn __PACKAGE__ . ' hides ' . + join( + ', ', + sort split( + /,/, $config->{'Devel::Hide/hidden'} + ) + ) . "\n"; } - - # NOTE. @HIDDEN is not changed anymore - } sub _dont_load { my $filename = shift; - my $hidden_by = $VERBOSE ? 'hidden' : 'hidden by ' . __PACKAGE__; + my $hidden_by = _get_setting('verbose') + ? 'hidden' + : 'hidden by ' . __PACKAGE__; die "Can't locate $filename in \@INC ($hidden_by)\n"; } -sub _is_hidden { - my $filename = shift; - return $IS_HIDDEN{$filename}; -} - -sub _inc_hook { - my ( $coderef, $filename ) = @_; - if ( _is_hidden($filename) ) { - return _dont_load($filename); # stop right here, with error - } - else { - return undef; # go on with the search - } -} - -use lib ( \&_inc_hook ); - =begin private =item B<_core_modules> @@ -170,31 +127,139 @@ } +sub _is_hidden { + no warnings 'uninitialized'; + my $module = shift; + + +{ + map { $_ => 1 } + map { + split(',', _get_config_ref($_)->{'Devel::Hide/hidden'}) + } qw(global lexical) + }->{$module}; +} + +sub _get_setting { + my $name = shift; + _exists_setting('lexical', $name) + ? _get_setting_from('lexical', $name) + : _get_setting_from('global', $name) +} + +sub _get_setting_from { + my($source, $name) = @_; + + my $config = _get_config_ref($source); + _setting_hashref($config)->{$name}; +} + +sub _exists_setting { + my($source, $name) = @_; + + my $config = _get_config_ref($source); + exists(_setting_hashref($config)->{$name}); +} + +sub _set_setting { + my($source, $name, $value) = @_; + + my $config = _get_config_ref($source); + my %hash = ( + %{_setting_hashref($config)}, + $name => $value + ); + _get_config_ref($source) + ->{'Devel::Hide/settings'} = join(',', %hash); +} + +sub _setting_hashref { + my $settings = shift->{'Devel::Hide/settings'}; + no warnings 'uninitialized'; + +{ split(/,/, $settings) }; +} + +sub _get_config_ref { + my $type = shift; + if($type eq 'lexical') { + if($phase eq 'compile') { + return \%^H; + } else { + my $depth = 1; + while(my @fields = caller($depth)) { + my $hints_hash = $fields[10]; + if($hints_hash && grep { /^Devel::Hide\// } keys %{$hints_hash}) { + # return a copy + return { %{$hints_hash} }; + } + $depth++; + } + return {}; + } + } else { + return \%GLOBAL_SETTINGS; + } +} + sub import { shift; + my $which_config = 'global'; + local $phase = 'compile'; while(@_ && $_[0] =~ /^-/) { - if( $_[0] eq '-from:children' ) { - $HIDE_FROM{children} = 1; + if( $_[0] eq '-lexically' ) { + $which_config = 'lexical'; + if($] < 5.010) { + die("Can't 'use Devel::Hide qw(-lexically ...)' on perl 5.8 and below\n"); + } + } elsif( $_[0] eq '-from:children' ) { + _set_setting($which_config, children => 1); } elsif( $_[0] eq '-quiet' ) { - $VERBOSE = 0; - $HIDE_FROM{children_quietly} = 1; + _set_setting($which_config, verbose => 0); } else { die("Devel::Hide: don't recognize $_[0]\n"); } shift; } if (@_) { - _push_hidden(@_); - if ($HIDE_FROM{children}) { + _push_hidden( + _get_config_ref($which_config), + @_ + ); + if (_get_setting('children')) { _append_to_perl5opt( - ($HIDE_FROM{children_quietly} ? '-quiet' : ()), + (_get_setting('verbose') ? () : '-quiet'), @_ ); } } +} + +# $ENV{DEVEL_HIDE_PM} is split in ' ' +# as well as @HIDDEN it accepts Module::Module as well as File/Names.pm +BEGIN { + # unless @HIDDEN was user-defined elsewhere, set default + if ( !@HIDDEN && $ENV{DEVEL_HIDE_PM} ) { + # NOTE. "split ' ', $s" is special. Read "perldoc -f split". + _push_hidden( + _get_config_ref('global'), + split q{ }, $ENV{DEVEL_HIDE_PM} + ); + } + else { + _push_hidden( + _get_config_ref('global'), + @HIDDEN + ); + } +} +sub _inc_hook { + my ( $coderef, $filename ) = @_; + if ( _is_hidden($filename) ) { _dont_load($filename); } + else { return undef; } } +use lib ( \&_inc_hook ); + # TO DO: # * write unimport() sub # * write decent docs @@ -208,7 +273,7 @@ how to implement -%IS_HIDDEN +%GLOBAL_SETTINGS %IS_EXCEPTION if there is an exception, all but the set of exceptions are to be hidden plus the set of hidden modules @@ -231,6 +296,8 @@ =head1 SYNOPSIS + # hide modules globally, across the entire process + use Devel::Hide qw(Module/ToHide.pm); require Module::ToHide; # fails @@ -238,19 +305,47 @@ require Test::More; # ok use Test::Pod 1.18; # fails + # hide modules lexically + { + use Devel::Hide qw(-lexically Foo::Bar); + # this will fail to load + eval 'use Foo::Bar'; + } + # but this will load + use Foo::Bar; + Other common usage patterns: $ perl -MDevel::Hide=Module::ToHide Makefile.PL + $ perl -MDevel::Hide=Module::ToHide,Test::Pod Makefile.PL + + $ PERL5OPT=-MDevel::Hide + $ DEVEL_HIDE_PM='Module::ToHide Test::Pod' + $ export PERL5OPT DEVEL_HIDE_PM + $ perl Makefile.PL - bash$ PERL5OPT=MDevel::Hide - bash$ DEVEL_HIDE_PM='Module::Which Test::Pod' - bash$ export PERL5OPT DEVEL_HIDE_PM - bash$ perl Makefile.PL +=head1 COMPATIBILITY -outputs (like blib) +=over + +=item global hiding - Devel::Hide hides Module::Which, Test::Pod, etc. +At some point global hiding may B<go away> and only lexical +hiding be supported. At that point support for perl versions +below 5.10 will be dropped. There will be at least a two year +deprecation cycle before that happens. + +You are strongly encouraged to only use lexical hiding and to +update existing code. + +=item perl 5.6 + +Support will be dropped at some point after 2022-01-01 with no +further warning. This is because bugs in older perls prevent +some code improvements. See commit dd27e50 in the repository +if you care to know what those are. +=back =head1 DESCRIPTION @@ -299,17 +394,23 @@ =over 4 -=item * +=item import() + +this is probably the most commonly used method, called automagically +when you do this: -setting @Devel::Hide::HIDDEN + use Devel::Hide qw(Foo Bar::Baz); -=item * +or -environment variable DEVEL_HIDE_PM + perl -MDevel::Hide=... -=item * +=item setting @Devel::Hide::HIDDEN -import() +=item environment variable DEVEL_HIDE_PM + +both of these two only support 'global' hiding, whereas C<import()> +supports lexical hiding as well. =back @@ -323,7 +424,24 @@ propagate the list of hidden modules to your process' child processes. This works by populating C<PERL5OPT>, and is incompatible with Taint mode, as -explained in L<perlrun>. +explained in L<perlrun>. Of course, this is unnecessary +if your child processes are just forks of the current one. + +=item -lexically + +This is only available on perl 5.10.0 and later. It is a fatal +error to try to use it on an older perl. + +Everything following this will only have effect until the +end of the current scope. Yes, that includes C<-quiet>. + +=begin private + +PERL5OPT is populated globally even when -lexically is in use. +How can its value be lexicalised? Or how can all the various ways +of spawning a child be lexicalised? + +=end private =item -quiet @@ -333,7 +451,7 @@ =back -=head2 CAVEATS +=head1 CAVEATS There is some interaction between C<lib> and this module @@ -342,7 +460,9 @@ In this case, 'my_lib' enters the include path before the Devel::Hide hook and if F<Module/ToHide.pm> is found -in 'my_lib', it succeeds. +in 'my_lib', it succeeds. More generally, any code that +adds anything to the front of the C<@INC> list after +Devel::Hide is loaded will have this effect. Also for modules that were loaded before Devel::Hide, C<require> and C<use> succeeds. @@ -352,12 +472,10 @@ $ perl -MDevel::Hide=Devel::Hide -e '' Devel::Hide: Too late to hide Devel/Hide.pm - -=head2 EXPORTS +=head1 EXPORTS Nothing is exported. - =head1 ENVIRONMENT VARIABLES DEVEL_HIDE_PM - if defined, the list of modules is added @@ -369,18 +487,26 @@ PERL5OPT - used if you specify '-from:children' - =head1 SEE ALSO L<perldoc -f require> L<Test::Without::Module> - =head1 BUGS -Please report bugs via CPAN RT L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=Devel-Hide>. +=over + +=item bug +C<-from:children> and C<-lexically> don't like each other. Anything +hidden lexically may be hidden from all child processes without +regard for scope. Don't use them together. + +=back + +Please report any other bugs you find via CPAN RT +L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=Devel-Hide>. =head1 AUTHORS @@ -388,7 +514,6 @@ with contributions from David Cantrell E<lt>dcantr...@cpan.orge<gt> - =head1 COPYRIGHT AND LICENSE Copyright (C) 2005-2007, 2018 by Adriano R. Ferreira diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Devel-Hide-0.0011/t/002basic.t new/Devel-Hide-0.0013/t/002basic.t --- old/Devel-Hide-0.0011/t/002basic.t 2020-02-13 00:40:39.000000000 +0100 +++ new/Devel-Hide-0.0013/t/002basic.t 2020-02-15 18:37:21.000000000 +0100 @@ -32,7 +32,7 @@ eval { require R }; like($@, qr/^Can't locate R\.pm in \@INC/, - "correctly moaned about loading Q". + "correctly moaned about loading R". ($pass == 2 ? ' again' : '')); ok(!exists($INC{"R.pm"}), "correctly didn't load R"); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Devel-Hide-0.0011/t/lexically.t new/Devel-Hide-0.0013/t/lexically.t --- old/Devel-Hide-0.0011/t/lexically.t 1970-01-01 01:00:00.000000000 +0100 +++ new/Devel-Hide-0.0013/t/lexically.t 2020-02-16 21:16:46.000000000 +0100 @@ -0,0 +1,66 @@ +use strict; +use warnings; + +BEGIN { + require Test::More; + $] < 5.010 + ? Test::More->import(skip_all => "perl too old") + : Test::More->import(tests => 9); +} + +use lib 't'; + +my @expected_warnings; +BEGIN { + push @expected_warnings, + 'Devel::Hide hides R.pm', + 'Devel::Hide hides Q.pm'; + $SIG{__WARN__} = sub { + if(!@expected_warnings) { + fail("Got unexpected warning '$_[0]'") + } else { + is($_[0], shift(@expected_warnings)."\n", + "got expected warning: $_[0]"); + } + } +} +END { ok(!@expected_warnings, "got all expected warnings") } + +# hide R globally +use Devel::Hide qw(R); +note("R hidden globally, and noisily"); + +eval { require R }; +like($@, qr/^Can't locate R\.pm in \@INC/, + "correctly moaned about hiding R (globally)"); + +{ + use Devel::Hide qw(-lexically -quiet Q.pm); + note("Q hidden lexically, quietly"); + + eval { require Q }; + like($@, qr/^Can't locate Q\.pm in \@INC/, + "correctly moaned about loading Q"); + + eval { require R }; + like($@, qr/^Can't locate R\.pm in \@INC/, + "still can't load R which is globally hidden"); +} + +{ + use Devel::Hide qw(-lexically Q); + note("Q hidden in a different scope, noisily"); + + eval { require Q }; + like($@, qr/^Can't locate Q\.pm in \@INC/, + "correctly moaned about loading Q"); +} + +note("Now we're outside that lexical scope"); + +eval { require Q }; +ok(!$@, "nothing moaned about loading Q"); + +eval { require R }; +like($@, qr/^Can't locate R\.pm in \@INC/, + "still can't load R");