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.000000'; # 1.0.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 $ perl -MCPAN -eshell # you only need to do this if you don't have a ~/.cpan
314 <download local::lib tarball from CPAN, unpack and cd into dir>
315 $ perl Makefile.PL --bootstrap
316 $ make test && make install
317 $ echo 'eval $(perl -I$HOME/perl5/lib/perl5 -Mlocal::lib)' >>~/.bashrc
322 % perl -I$HOME/perl5/lib/perl5 -Mlocal::lib >> ~/.cshrc
324 You can also pass --boostrap=~/foo to get a different location (adjust the
325 bashrc / cshrc line appropriately)
329 This module provides a quick, convenient way of bootstrapping a user-local Perl
330 module library located within the user's home directory. It also constructs and
331 prints out for the user the list of environment variables using the syntax
332 appropriate for the user's current shell (as specified by the C<SHELL>
333 environment variable), suitable for directly adding to one's shell configuration
336 More generally, local::lib allows for the bootstrapping and usage of a directory
337 containing Perl modules outside of Perl's C<@INC>. This makes it easier to ship
338 an application with an app-specific copy of a Perl module, or collection of
339 modules. Useful in cases like when an upstream maintainer hasn't applied a patch
340 to a module of theirs that you need for your application.
342 On import, local::lib sets the following environment variables to appropriate
355 PATH is appended to, rather than clobbered.
359 These values are then available for reference by any code after import.
363 Rather basic shell detection. Right now anything with csh in its name is
364 assumed to be a C shell or something compatible, and everything else is assumed
365 to be Bourne. If the C<SHELL> environment variable is not set, a
366 Bourne-compatible shell is assumed.
368 Bootstrap is a hack and will use CPAN.pm for ExtUtils::MakeMaker even if you
369 have CPANPLUS installed.
371 Kills any existing PERL5LIB, PERL_MM_OPT or MODULEBUILDRC.
373 Should probably auto-fixup CPAN config if not already done.
375 Patches very much welcome for any of the above.
383 local::lib looks at the user's C<SHELL> environment variable when printing out
384 commands to add to the shell configuration file.
390 Matt S Trout <mst@shadowcat.co.uk> http://www.shadowcat.co.uk/
392 auto_install fixes kindly sponsored by http://www.takkle.com/
396 This library is free software under the same license as perl itself