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_ENV () { 1 }
199 sub LITERAL_ENV () { 0 }
201 sub print_environment_vars_for {
202 my ($class, $path) = @_;
203 my @envs = $class->build_environment_vars_for($path, LITERAL_ENV);
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_ENV);
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),
263 ($interpolate == INTERPOLATE_ENV
269 $class->install_base_bin_path($path),
270 ($interpolate == INTERPOLATE_ENV
281 File::Path::rmtree('t/var/splat');
283 $c->ensure_dir_structure_for('t/var/splat');
285 ok(-d 't/var/splat');
287 ok(-f 't/var/splat/.modulebuildrc');
293 local::lib - create and use a local lib/ for perl modules with PERL5LIB
299 use local::lib; # sets up a local lib at ~/perl5
301 use local::lib '~/foo'; # same, but ~/foo
305 use local::lib "$FindBin::Bin/../support"; # app-local support library
310 export MODULEBUILDRC=/home/username/perl/.modulebuildrc
311 export PERL_MM_OPT='INSTALL_BASE=/home/username/perl'
312 export PERL5LIB='/home/username/perl/lib/perl5:/home/username/perl/lib/perl5/i386-linux'
313 export PATH="/home/username/perl/bin:$PATH"
315 To bootstrap if you don't have local::lib itself installed -
317 <download local::lib tarball from CPAN, unpack and cd into dir>
319 $ perl Makefile.PL --bootstrap
320 $ make test && make install
322 $ echo 'eval $(perl -I$HOME/perl5/lib/perl5 -Mlocal::lib)' >>~/.bashrc
329 % perl -I$HOME/perl5/lib/perl5 -Mlocal::lib >> ~/.cshrc
331 You can also pass --boostrap=~/foo to get a different location (adjust the
332 bashrc / cshrc line appropriately)
336 This module provides a quick, convenient way of bootstrapping a user-local Perl
337 module library located within the user's home directory. It also constructs and
338 prints out for the user the list of environment variables using the syntax
339 appropriate for the user's current shell (as specified by the C<SHELL>
340 environment variable), suitable for directly adding to one's shell configuration
343 More generally, local::lib allows for the bootstrapping and usage of a directory
344 containing Perl modules outside of Perl's C<@INC>. This makes it easier to ship
345 an application with an app-specific copy of a Perl module, or collection of
346 modules. Useful in cases like when an upstream maintainer hasn't applied a patch
347 to a module of theirs that you need for your application.
349 On import, local::lib sets the following environment variables to appropriate
362 PATH is appended to, rather than clobbered.
366 These values are then available for reference by any code after import.
370 Rather basic shell detection. Right now anything with csh in its name is
371 assumed to be a C shell or something compatible, and everything else is assumed
372 to be Bourne. If the C<SHELL> environment variable is not set, a
373 Bourne-compatible shell is assumed.
375 Bootstrap is a hack and will use CPAN.pm for ExtUtils::MakeMaker even if you
376 have CPANPLUS installed.
378 Kills any existing PERL5LIB, PERL_MM_OPT or MODULEBUILDRC.
380 Should probably auto-fixup CPAN config if not already done.
382 Patches very much welcome for any of the above.
390 local::lib looks at the user's C<SHELL> environment variable when printing out
391 commands to add to the shell configuration file.
397 Matt S Trout <mst@shadowcat.co.uk> http://www.shadowcat.co.uk/
399 auto_install fixes kindly sponsored by http://www.takkle.com/
403 Patches to correctly output commands for csh style shells, as well as some
404 documentation additions, contributed by Christopher Nehren <apeiron@cpan.org>.
408 This library is free software under the same license as perl itself