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}(
45 { package Foo; sub foo { -$_[1] } sub bar { $_[1]+2 } sub baz { $_[1]+3 } }
46 my $foo = bless({}, 'Foo');
47 Test::More::ok($foo->${pipeline qw(foo bar baz)}(10) == -15);
52 my ($class, $path) = @_;
53 $class->${pipeline qw(
60 sub resolve_empty_path {
61 my ($class, $path) = @_;
69 =for test classmethod setup
77 is($c->resolve_empty_path, '~/perl5');
78 is($c->resolve_empty_path('foo'), 'foo');
82 sub resolve_home_path {
83 my ($class, $path) = @_;
84 return $path unless ($path =~ /^~/);
85 my ($user) = ($path =~ /^~([^\/]+)/); # can assume ^~ so undef for 'us'
86 my $tried_file_homedir;
88 if (eval { require File::HomeDir } && $File::HomeDir::VERSION >= 0.65) {
89 $tried_file_homedir = 1;
91 File::HomeDir->users_home($user);
93 File::HomeDir->my_home;
99 if (defined $ENV{HOME}) {
107 unless (defined $homedir) {
109 "Couldn't resolve homedir for "
110 .(defined $user ? $user : 'current user')
111 .($tried_file_homedir ? '' : ' - consider installing File::HomeDir')
114 $path =~ s/^~[^\/]*/$homedir/;
118 sub resolve_relative_path {
119 my ($class, $path) = @_;
120 File::Spec->rel2abs($path);
123 =for test classmethod
125 local *File::Spec::rel2abs = sub { shift; 'FOO'.shift; };
126 is($c->resolve_relative_path('bar'),'FOObar');
130 sub setup_local_lib_for {
131 my ($class, $path) = @_;
132 $class->ensure_dir_structure_for($path);
134 $class->print_environment_vars_for($path);
137 $class->setup_env_hash_for($path);
138 unshift(@INC, split(':', $ENV{PERL5LIB}));
142 sub modulebuildrc_path {
143 my ($class, $path) = @_;
144 File::Spec->catfile($path, '.modulebuildrc');
147 sub install_base_bin_path {
148 my ($class, $path) = @_;
149 File::Spec->catdir($path, 'bin');
152 sub install_base_perl_path {
153 my ($class, $path) = @_;
154 File::Spec->catdir($path, 'lib', 'perl5');
157 sub install_base_arch_path {
158 my ($class, $path) = @_;
159 File::Spec->catdir($class->install_base_perl_path($path), $Config{archname});
162 sub ensure_dir_structure_for {
163 my ($class, $path) = @_;
165 warn "Attempting to create directory ${path}\n";
167 File::Path::mkpath($path);
168 my $modulebuildrc_path = $class->modulebuildrc_path($path);
169 if (-e $modulebuildrc_path) {
171 Carp::croak("${modulebuildrc_path} exists but is not a plain file");
174 warn "Attempting to create file ${modulebuildrc_path}\n";
175 open MODULEBUILDRC, '>', $modulebuildrc_path
176 || Carp::croak("Couldn't open ${modulebuildrc_path} for writing: $!");
177 print MODULEBUILDRC qq{install --install_base ${path}\n}
178 || Carp::croak("Couldn't write line to ${modulebuildrc_path}: $!");
180 || Carp::croak("Couldn't close file ${modulebuildrc_path}: $@");
184 sub INTERPOLATE_PATH () { 1 }
185 sub LITERAL_PATH () { 0 }
187 sub print_environment_vars_for {
188 my ($class, $path) = @_;
189 my @envs = $class->build_environment_vars_for($path, LITERAL_PATH);
192 my ($name, $value) = (shift(@envs), shift(@envs));
193 $value =~ s/(\\")/\\$1/g;
195 # rather basic csh detection, goes on the assumption that something won't
196 # call itself csh unless it really is. also, default to bourne in the
197 # pathological situation where a user doesn't have $ENV{SHELL} defined.
198 # note also that shells with funny names, like zoid, are assumed to be
201 if(defined $ENV{'SHELL'}) {
202 my @shell_bin_path_parts = File::Spec->splitpath($ENV{'SHELL'});
203 $shellbin = $shell_bin_path_parts[-1];
205 if($shellbin =~ /csh/) {
206 $out .= qq{setenv ${name} "${value}"\n};
209 $out .= qq{export ${name}="${value}"\n};
215 sub setup_env_hash_for {
216 my ($class, $path) = @_;
217 my %envs = $class->build_environment_vars_for($path, INTERPOLATE_PATH);
218 @ENV{keys %envs} = values %envs;
221 sub build_environment_vars_for {
222 my ($class, $path, $interpolate) = @_;
224 MODULEBUILDRC => $class->modulebuildrc_path($path),
225 PERL_MM_OPT => "INSTALL_BASE=${path}",
226 PERL5LIB => join(':',
227 $class->install_base_perl_path($path),
228 $class->install_base_arch_path($path),
231 $class->install_base_bin_path($path),
232 ($interpolate == INTERPOLATE_PATH
239 =for test classmethod
241 File::Path::rmtree('t/var/splat');
243 $c->ensure_dir_structure_for('t/var/splat');
245 ok(-d 't/var/splat');
247 ok(-f 't/var/splat/.modulebuildrc');
251 local::lib - create and use a local lib/ for perl modules with PERL5LIB
257 use local::lib; # sets up a local lib at ~/perl5
259 use local::lib '~/foo'; # same, but ~/foo
264 export MODULEBUILDRC=/home/username/perl/.modulebuildrc
265 export PERL_MM_OPT='INSTALL_BASE=/home/username/perl'
266 export PERL5LIB='/home/username/perl/lib/perl5:/home/username/perl/lib/perl5/i386-linux'
267 export PATH="/home/username/perl/bin:$PATH"
269 To bootstrap if you don't have local::lib itself installed -
271 $ perl -MCPAN -eshell # you only need to do this if you don't have a ~/.cpan
273 <download local::lib tarball from CPAN, unpack and cd into dir>
274 $ perl Makefile.PL --bootstrap
275 $ make test && make install
276 $ echo 'eval $(perl -I$HOME/perl5/lib/perl5 -Mlocal::lib)' >>~/.bashrc
281 % perl -I$HOME/perl5/lib/perl5 -Mlocal::lib >> ~/.cshrc
283 You can also pass --boostrap=~/foo to get a different location (adjust the
284 bashrc / cshrc line appropriately)
288 This module provides a quick, convenient way of bootstrapping a user-local Perl
289 module library located within the user's home directory. It also constructs and
290 prints out for the user the list of environment variables using the syntax
291 appropriate for the user's current shell (as specified by the C<SHELL>
292 environment variable), suitable for directly adding to one's shell configuration
297 Rather basic shell detection. Right now anything with csh in its name is
298 assumed to be a C shell or something compatible, and everything else is assumed
301 Bootstrap is a hack and will use CPAN.pm for ExtUtils::MakeMaker even if you
302 have CPANPLUS installed.
304 Kills any existing PERL5LIB, PERL_MM_OPT or MODULEBUILDRC.
306 Should probably auto-fixup CPAN config if not already done.
308 Patches very much welcome for any of the above.
316 local::lib looks at the user's C<SHELL> environment variable when printing out
317 commands to add to the shell configuration file.
323 Matt S Trout <mst@shadowcat.co.uk> http://www.shadowcat.co.uk/
327 This library is free software under the same license as perl itself