add lib::core::only module
matthewt [Wed, 31 Mar 2010 16:12:02 +0000 (16:12 +0000)]
git-svn-id: http://dev.catalyst.perl.org/repos/bast/local-lib/1.000/trunk@9071 bd8105ee-0ff8-0310-8827-fb3f25b6796d

Changes
lib/lib/core/only.pm [new file with mode: 0644]
t/lib-core-only.t [new file with mode: 0644]

diff --git a/Changes b/Changes
index 94c0208..7ce7bd0 100644 (file)
--- a/Changes
+++ b/Changes
@@ -1,5 +1,9 @@
 Revision history for local::lib
 
+        - Create lib::core::only that provides the "set @INC to core dirs
+          only" functionality that was the only part of --self-contained that
+          ever worked usefully.
+
 1.005001 2010-03-10
 
         - I am an idiot.
diff --git a/lib/lib/core/only.pm b/lib/lib/core/only.pm
new file mode 100644 (file)
index 0000000..3f1ff49
--- /dev/null
@@ -0,0 +1,91 @@
+package lib::core::only;
+
+use strict;
+use warnings FATAL => 'all';
+use Config;
+
+sub import {
+  @INC = @Config{qw(privlibexp archlibexp)};
+  return
+}
+
+=head1 NAME
+
+lib::core::only - Remove all non-core paths from @INC to avoid site/vendor dirs
+
+=head1 SYNOPSIS
+
+  use lib::core::only; # now @INC contains only the two core directories
+
+  # To get only the core directories plus the ones for the local::lib in
+  # scope
+
+  $ perl -Mlib::core::only -Mlocal::lib=~/perl5 myscript.pl
+
+=head1 DESCRIPTION
+
+lib::core::only is simply a shortcut to say "please reduce my @INC to only
+the core lib and archlib directories of this perl".
+
+You might want to do this to ensure a local::lib contains only the code you
+need, or to test an L<App::FatPacker|App::FatPacker> tree, or to avoid known
+bad vendor packages.
+
+You might want to use this to try and install a self-contained tree of perl
+modules. Be warned that that probably won't work (see L</CAVEATS>).
+
+This module was extracted from L<local::lib|local::lib>'s --self-contained
+feature, and contains the only part that ever worked. I apologise to anybody
+who thought anything else did.
+
+=head1 CAVEATS
+
+This does B<not> propagate properly across perl invocations like local::lib's
+stuff does. It can't. It's only a module import, so it B<only affects the
+specific perl VM instance in which you load and import() it>.
+
+If you want to cascade it across invocations, you can set the PERL5OPT
+environment variable to '-Mlib::core::only' and it'll sort of work. But be
+aware that taint mode ignores this, so some modules' build and test code
+probably will as well.
+
+You also need to be aware that perl's command line options are not processed
+in order - -I options take effect before -M options, so
+
+  perl -Mlib::core::only -Ilib
+
+is unlike to do what you want - it's exactly equivalent to:
+
+  perl -Mlib::core::only
+
+If you want to combine a core-only @INC with additional paths, you need to
+add the additional paths using -M options and the L<lib|lib> module:
+
+  perl -Mlib::core::only -Mlib=lib
+
+  # or if you're trying to test compiled code:
+
+  perl -Mlib::core::only -Mblib
+
+For more information on the impossibility of sanely propagating this across
+module builds without help from the build program, see
+L<http://www.shadowcat.co.uk/blog/matt-s-trout/tainted-love> - and for ways
+to achieve the old --self-contained feature's results, look at
+L<App::FatPacker|App::FatPacker>'s tree function, and at
+L<App::cpanminus|cpanm>'s --local-lib-contained feature.
+
+=head1 AUTHOR
+
+Matt S. Trout <mst@shadowcat.co.uk>
+
+=head1 LICENSE
+
+This library is free software under the same terms as perl itself.
+
+=head1 COPYRIGHT
+
+(c) 2010 the lib::core::only L</AUTHOR> as specified above.
+
+=cut
+
+1;
diff --git a/t/lib-core-only.t b/t/lib-core-only.t
new file mode 100644 (file)
index 0000000..960f78c
--- /dev/null
@@ -0,0 +1,11 @@
+use strict;
+use warnings FATAL => 'all';
+use Test::More tests => 1;
+use lib::core::only ();
+use Config;
+
+is_deeply(
+  [ do { local @INC = @INC; lib::core::only->import; @INC } ],
+  [ $Config{privlibexp}, $Config{archlibexp} ],
+  'lib::core::only mangles @INC correctly'
+);