6 use 5.8.1; # probably works with earlier versions but I'm not supporting them
7 # (patches would, of course, be welcome)
14 our $VERSION = '1.001000'; # 1.1.0
17 my ($class, $path) = @_;
18 $path = $class->resolve_path($path);
19 $class->setup_local_lib_for($path);
26 my $last = pop(@methods);
29 my ($obj, @args) = @_;
30 $obj->${pipeline @methods}(
47 { package Foo; sub foo { -$_[1] } sub bar { $_[1]+2 } sub baz { $_[1]+3 } }
48 my $foo = bless({}, 'Foo');
49 Test::More::ok($foo->${pipeline qw(foo bar baz)}(10) == -15);
56 my ($class, $path) = @_;
57 $class->${pipeline qw(
64 sub resolve_empty_path {
65 my ($class, $path) = @_;
75 #:: test classmethod setup
85 is($c->resolve_empty_path, '~/perl5');
86 is($c->resolve_empty_path('foo'), 'foo');
92 sub resolve_home_path {
93 my ($class, $path) = @_;
94 return $path unless ($path =~ /^~/);
95 my ($user) = ($path =~ /^~([^\/]+)/); # can assume ^~ so undef for 'us'
96 my $tried_file_homedir;
98 if (eval { require File::HomeDir } && $File::HomeDir::VERSION >= 0.65) {
99 $tried_file_homedir = 1;
101 File::HomeDir->users_home($user);
103 File::HomeDir->my_home;
109 if (defined $ENV{HOME}) {
117 unless (defined $homedir) {
119 "Couldn't resolve homedir for "
120 .(defined $user ? $user : 'current user')
121 .($tried_file_homedir ? '' : ' - consider installing File::HomeDir')
124 $path =~ s/^~[^\/]*/$homedir/;
128 sub resolve_relative_path {
129 my ($class, $path) = @_;
130 File::Spec->rel2abs($path);
137 local *File::Spec::rel2abs = sub { shift; 'FOO'.shift; };
138 is($c->resolve_relative_path('bar'),'FOObar');
144 sub setup_local_lib_for {
145 my ($class, $path) = @_;
146 $class->ensure_dir_structure_for($path);
148 $class->print_environment_vars_for($path);
151 $class->setup_env_hash_for($path);
152 unshift(@INC, split(':', $ENV{PERL5LIB}));
156 sub modulebuildrc_path {
157 my ($class, $path) = @_;
158 File::Spec->catfile($path, '.modulebuildrc');
161 sub install_base_bin_path {
162 my ($class, $path) = @_;
163 File::Spec->catdir($path, 'bin');
166 sub install_base_perl_path {
167 my ($class, $path) = @_;
168 File::Spec->catdir($path, 'lib', 'perl5');
171 sub install_base_arch_path {
172 my ($class, $path) = @_;
173 File::Spec->catdir($class->install_base_perl_path($path), $Config{archname});
176 sub ensure_dir_structure_for {
177 my ($class, $path) = @_;
179 warn "Attempting to create directory ${path}\n";
181 File::Path::mkpath($path);
182 my $modulebuildrc_path = $class->modulebuildrc_path($path);
183 if (-e $modulebuildrc_path) {
185 Carp::croak("${modulebuildrc_path} exists but is not a plain file");
188 warn "Attempting to create file ${modulebuildrc_path}\n";
189 open MODULEBUILDRC, '>', $modulebuildrc_path
190 || Carp::croak("Couldn't open ${modulebuildrc_path} for writing: $!");
191 print MODULEBUILDRC qq{install --install_base ${path}\n}
192 || Carp::croak("Couldn't write line to ${modulebuildrc_path}: $!");
194 || Carp::croak("Couldn't close file ${modulebuildrc_path}: $@");
198 sub INTERPOLATE_PATH () { 1 }
199 sub LITERAL_PATH () { 0 }
201 sub print_environment_vars_for {
202 my ($class, $path) = @_;
203 my @envs = $class->build_environment_vars_for($path, LITERAL_PATH);
206 # rather basic csh detection, goes on the assumption that something won't
207 # call itself csh unless it really is. also, default to bourne in the
208 # pathological situation where a user doesn't have $ENV{SHELL} defined.
209 # note also that shells with funny names, like zoid, are assumed to be
212 if(defined $ENV{'SHELL'}) {
213 my @shell_bin_path_parts = File::Spec->splitpath($ENV{'SHELL'});
214 $shellbin = $shell_bin_path_parts[-1];
217 local $_ = $shellbin;
226 my ($name, $value) = (shift(@envs), shift(@envs));
227 $value =~ s/(\\")/\\$1/g;
228 $out .= $class->${\"build_${shelltype}_env_declaration"}($name, $value);
233 # simple routines that take two arguments: an %ENV key and a value. return
234 # strings that are suitable for passing directly to the relevant shell to set
235 # said key to said value.
236 sub build_bourne_env_declaration {
238 my($name, $value) = @_;
239 return qq{export ${name}="${value}"\n};
242 sub build_csh_env_declaration {
244 my($name, $value) = @_;
245 return qq{setenv ${name} "${value}"\n};
248 sub setup_env_hash_for {
249 my ($class, $path) = @_;
250 my %envs = $class->build_environment_vars_for($path, INTERPOLATE_PATH);
251 @ENV{keys %envs} = values %envs;
254 sub build_environment_vars_for {
255 my ($class, $path, $interpolate) = @_;
257 MODULEBUILDRC => $class->modulebuildrc_path($path),
258 PERL_MM_OPT => "INSTALL_BASE=${path}",
259 PERL5LIB => join(':',
260 $class->install_base_perl_path($path),
261 $class->install_base_arch_path($path),
264 $class->install_base_bin_path($path),
265 ($interpolate == INTERPOLATE_PATH
276 File::Path::rmtree('t/var/splat');
278 $c->ensure_dir_structure_for('t/var/splat');
280 ok(-d 't/var/splat');
282 ok(-f 't/var/splat/.modulebuildrc');
288 local::lib - create and use a local lib/ for perl modules with PERL5LIB
294 use local::lib; # sets up a local lib at ~/perl5
296 use local::lib '~/foo'; # same, but ~/foo
300 use local::lib "$FindBin::Bin/../support"; # app-local support library
305 export MODULEBUILDRC=/home/username/perl/.modulebuildrc
306 export PERL_MM_OPT='INSTALL_BASE=/home/username/perl'
307 export PERL5LIB='/home/username/perl/lib/perl5:/home/username/perl/lib/perl5/i386-linux'
308 export PATH="/home/username/perl/bin:$PATH"
310 To bootstrap if you don't have local::lib itself installed -
312 <download local::lib tarball from CPAN, unpack and cd into dir>
314 $ perl Makefile.PL --bootstrap
315 $ make test && make install
317 $ echo 'eval $(perl -I$HOME/perl5/lib/perl5 -Mlocal::lib)' >>~/.bashrc
324 % perl -I$HOME/perl5/lib/perl5 -Mlocal::lib >> ~/.cshrc
326 You can also pass --boostrap=~/foo to get a different location (adjust the
327 bashrc / cshrc line appropriately)
331 This module provides a quick, convenient way of bootstrapping a user-local Perl
332 module library located within the user's home directory. It also constructs and
333 prints out for the user the list of environment variables using the syntax
334 appropriate for the user's current shell (as specified by the C<SHELL>
335 environment variable), suitable for directly adding to one's shell configuration
338 More generally, local::lib allows for the bootstrapping and usage of a directory
339 containing Perl modules outside of Perl's C<@INC>. This makes it easier to ship
340 an application with an app-specific copy of a Perl module, or collection of
341 modules. Useful in cases like when an upstream maintainer hasn't applied a patch
342 to a module of theirs that you need for your application.
344 On import, local::lib sets the following environment variables to appropriate
357 PATH is appended to, rather than clobbered.
361 These values are then available for reference by any code after import.
365 Rather basic shell detection. Right now anything with csh in its name is
366 assumed to be a C shell or something compatible, and everything else is assumed
367 to be Bourne. If the C<SHELL> environment variable is not set, a
368 Bourne-compatible shell is assumed.
370 Bootstrap is a hack and will use CPAN.pm for ExtUtils::MakeMaker even if you
371 have CPANPLUS installed.
373 Kills any existing PERL5LIB, PERL_MM_OPT or MODULEBUILDRC.
375 Should probably auto-fixup CPAN config if not already done.
377 Patches very much welcome for any of the above.
385 local::lib looks at the user's C<SHELL> environment variable when printing out
386 commands to add to the shell configuration file.
392 Matt S Trout <mst@shadowcat.co.uk> http://www.shadowcat.co.uk/
394 auto_install fixes kindly sponsored by http://www.takkle.com/
398 Patches to correctly output commands for csh style shells, as well as some
399 documentation additions, contributed by Christopher Nehren <apeiron@cpan.org>.
403 This library is free software under the same license as perl itself