6 use 5.008001; # probably works with earlier versions but I'm not supporting them
7 # (patches would, of course, be welcome)
14 our $VERSION = '1.002000'; # 1.2.0
17 my ($class, @args) = @_;
19 # The path is required, but last in the list, so we pop, not shift here.
21 $path = $class->resolve_path($path);
22 $class->setup_local_lib_for($path);
24 # Handle the '--self-contained' option
25 my $flag = shift @args;
26 no warnings 'uninitialized'; # the flag is optional
27 if ($flag eq '--self-contained') {
28 # The only directories that remain are those that we just defined and those where core modules are stored.
29 @INC = ($Config::Config{privlibexp}, $Config::Config{archlibexp}, split ':', $ENV{PERL5LIB});
31 elsif (defined $flag) {
32 die "unrecognized import argument: $flag";
41 my $last = pop(@methods);
44 my ($obj, @args) = @_;
45 $obj->${pipeline @methods}(
62 { package Foo; sub foo { -$_[1] } sub bar { $_[1]+2 } sub baz { $_[1]+3 } }
63 my $foo = bless({}, 'Foo');
64 Test::More::ok($foo->${pipeline qw(foo bar baz)}(10) == -15);
71 my ($class, $path) = @_;
72 $class->${pipeline qw(
79 sub resolve_empty_path {
80 my ($class, $path) = @_;
90 #:: test classmethod setup
100 is($c->resolve_empty_path, '~/perl5');
101 is($c->resolve_empty_path('foo'), 'foo');
107 sub resolve_home_path {
108 my ($class, $path) = @_;
109 return $path unless ($path =~ /^~/);
110 my ($user) = ($path =~ /^~([^\/]+)/); # can assume ^~ so undef for 'us'
111 my $tried_file_homedir;
113 if (eval { require File::HomeDir } && $File::HomeDir::VERSION >= 0.65) {
114 $tried_file_homedir = 1;
116 File::HomeDir->users_home($user);
118 File::HomeDir->my_home;
124 if (defined $ENV{HOME}) {
132 unless (defined $homedir) {
134 "Couldn't resolve homedir for "
135 .(defined $user ? $user : 'current user')
136 .($tried_file_homedir ? '' : ' - consider installing File::HomeDir')
139 $path =~ s/^~[^\/]*/$homedir/;
143 sub resolve_relative_path {
144 my ($class, $path) = @_;
145 File::Spec->rel2abs($path);
152 local *File::Spec::rel2abs = sub { shift; 'FOO'.shift; };
153 is($c->resolve_relative_path('bar'),'FOObar');
159 sub setup_local_lib_for {
160 my ($class, $path) = @_;
161 $class->ensure_dir_structure_for($path);
163 $class->print_environment_vars_for($path);
166 $class->setup_env_hash_for($path);
167 unshift(@INC, split(':', $ENV{PERL5LIB}));
171 sub modulebuildrc_path {
172 my ($class, $path) = @_;
173 File::Spec->catfile($path, '.modulebuildrc');
176 sub install_base_bin_path {
177 my ($class, $path) = @_;
178 File::Spec->catdir($path, 'bin');
181 sub install_base_perl_path {
182 my ($class, $path) = @_;
183 File::Spec->catdir($path, 'lib', 'perl5');
186 sub install_base_arch_path {
187 my ($class, $path) = @_;
188 File::Spec->catdir($class->install_base_perl_path($path), $Config{archname});
191 sub ensure_dir_structure_for {
192 my ($class, $path) = @_;
194 warn "Attempting to create directory ${path}\n";
196 File::Path::mkpath($path);
197 my $modulebuildrc_path = $class->modulebuildrc_path($path);
198 if (-e $modulebuildrc_path) {
200 Carp::croak("${modulebuildrc_path} exists but is not a plain file");
203 warn "Attempting to create file ${modulebuildrc_path}\n";
204 open MODULEBUILDRC, '>', $modulebuildrc_path
205 || Carp::croak("Couldn't open ${modulebuildrc_path} for writing: $!");
206 print MODULEBUILDRC qq{install --install_base ${path}\n}
207 || Carp::croak("Couldn't write line to ${modulebuildrc_path}: $!");
209 || Carp::croak("Couldn't close file ${modulebuildrc_path}: $@");
213 sub INTERPOLATE_ENV () { 1 }
214 sub LITERAL_ENV () { 0 }
216 sub print_environment_vars_for {
217 my ($class, $path) = @_;
218 my @envs = $class->build_environment_vars_for($path, LITERAL_ENV);
221 # rather basic csh detection, goes on the assumption that something won't
222 # call itself csh unless it really is. also, default to bourne in the
223 # pathological situation where a user doesn't have $ENV{SHELL} defined.
224 # note also that shells with funny names, like zoid, are assumed to be
227 if(defined $ENV{'SHELL'}) {
228 my @shell_bin_path_parts = File::Spec->splitpath($ENV{'SHELL'});
229 $shellbin = $shell_bin_path_parts[-1];
232 local $_ = $shellbin;
241 my ($name, $value) = (shift(@envs), shift(@envs));
242 $value =~ s/(\\")/\\$1/g;
243 $out .= $class->${\"build_${shelltype}_env_declaration"}($name, $value);
248 # simple routines that take two arguments: an %ENV key and a value. return
249 # strings that are suitable for passing directly to the relevant shell to set
250 # said key to said value.
251 sub build_bourne_env_declaration {
253 my($name, $value) = @_;
254 return qq{export ${name}="${value}"\n};
257 sub build_csh_env_declaration {
259 my($name, $value) = @_;
260 return qq{setenv ${name} "${value}"\n};
263 sub setup_env_hash_for {
264 my ($class, $path) = @_;
265 my %envs = $class->build_environment_vars_for($path, INTERPOLATE_ENV);
266 @ENV{keys %envs} = values %envs;
269 sub build_environment_vars_for {
270 my ($class, $path, $interpolate) = @_;
272 MODULEBUILDRC => $class->modulebuildrc_path($path),
273 PERL_MM_OPT => "INSTALL_BASE=${path}",
274 PERL5LIB => join(':',
275 $class->install_base_perl_path($path),
276 $class->install_base_arch_path($path),
278 ($interpolate == INTERPOLATE_ENV
284 $class->install_base_bin_path($path),
285 ($interpolate == INTERPOLATE_ENV
296 File::Path::rmtree('t/var/splat');
298 $c->ensure_dir_structure_for('t/var/splat');
300 ok(-d 't/var/splat');
302 ok(-f 't/var/splat/.modulebuildrc');
308 local::lib - create and use a local lib/ for perl modules with PERL5LIB
314 use local::lib; # sets up a local lib at ~/perl5
316 use local::lib '~/foo'; # same, but ~/foo
320 use local::lib "$FindBin::Bin/../support"; # app-local support library
324 # Install LWP and it's missing dependencies to the 'my_lwp' directory
325 perl -MCPAN -Mlocal::lib=my_lwp -e 'CPAN::install(LWP)'
327 # Install LWP and *all non-core* dependencies to the 'my_lwp' directory
328 perl -MCPAN -Mlocal::lib=--self-contained,my_lwp -e 'CPAN::install(LWP)'
330 # Just print out useful shell commands
332 export MODULEBUILDRC=/home/username/perl/.modulebuildrc
333 export PERL_MM_OPT='INSTALL_BASE=/home/username/perl'
334 export PERL5LIB='/home/username/perl/lib/perl5:/home/username/perl/lib/perl5/i386-linux'
335 export PATH="/home/username/perl/bin:$PATH"
337 To bootstrap if you don't have local::lib itself installed -
339 <download local::lib tarball from CPAN, unpack and cd into dir>
341 $ perl Makefile.PL --bootstrap
342 $ make test && make install
344 $ echo 'eval $(perl -I$HOME/perl5/lib/perl5 -Mlocal::lib)' >>~/.bashrc
351 % perl -I$HOME/perl5/lib/perl5 -Mlocal::lib >> ~/.cshrc
353 You can also pass --boostrap=~/foo to get a different location (adjust the
354 bashrc / cshrc line appropriately)
358 This module provides a quick, convenient way of bootstrapping a user-local Perl
359 module library located within the user's home directory. It also constructs and
360 prints out for the user the list of environment variables using the syntax
361 appropriate for the user's current shell (as specified by the C<SHELL>
362 environment variable), suitable for directly adding to one's shell configuration
365 More generally, local::lib allows for the bootstrapping and usage of a directory
366 containing Perl modules outside of Perl's C<@INC>. This makes it easier to ship
367 an application with an app-specific copy of a Perl module, or collection of
368 modules. Useful in cases like when an upstream maintainer hasn't applied a patch
369 to a module of theirs that you need for your application.
371 On import, local::lib sets the following environment variables to appropriate
384 PATH is appended to, rather than clobbered.
388 These values are then available for reference by any code after import.
390 =head1 A WARNING ABOUT UNINST=1
392 Be careful about using local::lib in combination with "make install UNINST=1".
393 The idea of this feature is that will uninstall an old version of a module
394 before installing a new one. However it lacks a safety check that the old
395 version and the new version will go in the same directory. Used in combination
396 with local::lib, you can potentially delete a globally accessible version of a
397 module while installing the new version in a local place. Only combine if "make
398 install UNINST=1" and local::lib if you understand these possible consequences.
402 Rather basic shell detection. Right now anything with csh in its name is
403 assumed to be a C shell or something compatible, and everything else is assumed
404 to be Bourne. If the C<SHELL> environment variable is not set, a
405 Bourne-compatible shell is assumed.
407 Bootstrap is a hack and will use CPAN.pm for ExtUtils::MakeMaker even if you
408 have CPANPLUS installed.
410 Kills any existing PERL5LIB, PERL_MM_OPT or MODULEBUILDRC.
412 Should probably auto-fixup CPAN config if not already done.
414 Patches very much welcome for any of the above.
422 local::lib looks at the user's C<SHELL> environment variable when printing out
423 commands to add to the shell configuration file.
429 Matt S Trout <mst@shadowcat.co.uk> http://www.shadowcat.co.uk/
431 auto_install fixes kindly sponsored by http://www.takkle.com/
435 Patches to correctly output commands for csh style shells, as well as some
436 documentation additions, contributed by Christopher Nehren <apeiron@cpan.org>.
438 '--self-contained' feature contributed by Mark Stosberg <mark@summersault.com>.
442 This library is free software under the same license as perl itself