correct output for fish shell
[p5sagit/local-lib.git] / lib / local / lib.pm
index 248e8c5..216426b 100644 (file)
@@ -8,14 +8,17 @@ use 5.006;
 use File::Spec ();
 use Config;
 
-our $VERSION = '1.008026'; # 1.8.26
+our $VERSION = '2.000004'; # 2.0.4
 $VERSION = eval $VERSION;
 
 sub import {
   my ($class, @args) = @_;
+  push @args, @ARGV
+    if $0 eq '-';
 
   my @steps;
   my %opts;
+  my $shelltype;
 
   while (@args) {
     my $arg = shift @args;
@@ -32,7 +35,17 @@ dashes with normal minus signs.
 DEATH
     }
     elsif ($arg eq '--self-contained') {
-      die "FATAL: The local::lib --self-contained flag has never worked reliably and the original author, Mark Stosberg, was unable or unwilling to maintain it. As such, this flag has been removed from the local::lib codebase in order to prevent misunderstandings and potentially broken builds. The local::lib authors recommend that you look at the lib::core::only module shipped with this distribution in order to create a more robust environment that is equivalent to what --self-contained provided (although quite possibly not what you originally thought it provided due to the poor quality of the documentation, for which we apologise).\n";
+      die <<'DEATH';
+FATAL: The local::lib --self-contained flag has never worked reliably and the
+original author, Mark Stosberg, was unable or unwilling to maintain it. As
+such, this flag has been removed from the local::lib codebase in order to
+prevent misunderstandings and potentially broken builds. The local::lib authors
+recommend that you look at the lib::core::only module shipped with this
+distribution in order to create a more robust environment that is equivalent to
+what --self-contained provided (although quite possibly not what you originally
+thought it provided due to the poor quality of the documentation, for which we
+apologise).
+DEATH
     }
     elsif( $arg =~ /^--deactivate(?:=(.*))?$/ ) {
       my $path = defined $1 ? $1 : shift @args;
@@ -42,8 +55,7 @@ DEATH
       push @steps, ['deactivate_all'];
     }
     elsif ( $arg =~ /^--shelltype(?:=(.*))?$/ ) {
-      my $shell = defined $1 ? $1 : shift @args;
-      $opts{shelltype} = $shell;
+      $shelltype = defined $1 ? $1 : shift @args;
     }
     elsif ( $arg eq '--no-create' ) {
       $opts{no_create} = 1;
@@ -67,11 +79,11 @@ DEATH
   }
 
   if ($0 eq '-') {
-    $self->print_environment_vars_for;
+    print $self->environment_vars_string($shelltype);
     exit 0;
   }
   else {
-    $self->setup_local_lib_for;
+    $self->setup_local_lib;
   }
 }
 
@@ -159,10 +171,12 @@ sub _mb_escape_path {
 
 sub installer_options_for {
   my ($class, $path) = @_;
-  return {
-    PERL_MM_OPT => defined $path ? "INSTALL_BASE="._mm_escape_path($path) : undef,
-    PERL_MB_OPT => defined $path ? "--install_base "._mb_escape_path($path) : undef,
-  };
+  return (
+    PERL_MM_OPT =>
+      defined $path ? "INSTALL_BASE="._mm_escape_path($path) : undef,
+    PERL_MB_OPT =>
+      defined $path ? "--install_base "._mb_escape_path($path) : undef,
+  );
 }
 
 sub active_paths {
@@ -181,6 +195,7 @@ sub deactivate {
   my ($self, $path) = @_;
   $self = $self->new unless ref $self;
   $path = $self->resolve_path($path);
+  $path = $self->normalize_path($path);
 
   my @active_lls = $self->active_paths;
 
@@ -190,13 +205,16 @@ sub deactivate {
   }
 
   my %args = (
-    bins  => [ _remove_from($self->bins,  $self->install_base_bin_path($path)) ],
-    libs  => [ _remove_from($self->libs,  $self->install_base_perl_path($path)) ],
-    inc   => [ _remove_from($self->inc,   $self->lib_paths_for($path)) ],
+    bins  => [ _remove_from($self->bins,
+      $self->install_base_bin_path($path)) ],
+    libs  => [ _remove_from($self->libs,
+      $self->install_base_perl_path($path)) ],
+    inc   => [ _remove_from($self->inc,
+      $self->lib_paths_for($path)) ],
     roots => [ _remove_from($self->roots, $path) ],
   );
 
-  $args{extra} = $self->installer_options_for($args{roots}[0]);
+  $args{extra} = { $self->installer_options_for($args{roots}[0]) };
 
   $self->clone(%args);
 }
@@ -220,7 +238,7 @@ sub deactivate_all {
     );
   }
 
-  $args{extra} = $self->installer_options_for(undef);
+  $args{extra} = { $self->installer_options_for(undef) };
 
   $self->clone(%args);
 }
@@ -232,8 +250,7 @@ sub activate {
   $self->ensure_dir_structure_for($path)
     unless $self->no_create;
 
-  $path = ( Win32::GetShortPathName($path) || $path )
-    if $^O eq 'MSWin32';
+  $path = $self->normalize_path($path);
 
   my @active_lls = $self->active_paths;
 
@@ -251,22 +268,24 @@ sub activate {
     );
   }
 
-  $args{extra} = $self->installer_options_for($path);
+  $args{extra} = { $self->installer_options_for($path) };
 
   $self->clone(%args);
 }
 
-sub _legacy {
+sub normalize_path {
   my ($self, $path) = @_;
-  $self = $self->new unless ref $self;
-  if (defined $path) {
-    $self = $self->activate($path);
-  }
-  $self;
+  $path = ( Win32::GetShortPathName($path) || $path )
+    if $^O eq 'MSWin32';
+  return $path;
 }
 
 sub build_environment_vars_for {
-  my ($self) = _legacy(@_);
+  my $self = $_[0]->new->activate($_[1]);
+  $self->build_environment_vars;
+}
+sub build_environment_vars {
+  my $self = shift;
   (
     PATH                => join($_path_sep, _as_list($self->bins)),
     PERL5LIB            => join($_path_sep, _as_list($self->libs)),
@@ -276,14 +295,23 @@ sub build_environment_vars_for {
 }
 
 sub setup_local_lib_for {
-  my ($self) = _legacy(@_);
-  $self->setup_env_hash_for;
+  my $self = $_[0]->new->activate($_[1]);
+  $self->setup_local_lib;
+}
+
+sub setup_local_lib {
+  my $self = shift;
+  $self->setup_env_hash;
   @INC = @{$self->inc};
 }
 
 sub setup_env_hash_for {
+  my $self = $_[0]->new->activate($_[1]);
+  $self->setup_env_hash;
+}
+sub setup_env_hash {
   my $self = shift;
-  my %env = $self->build_environment_vars_for(@_);
+  my %env = $self->build_environment_vars;
   for my $key (keys %env) {
     if (defined $env{$key}) {
       $ENV{$key} = $env{$key};
@@ -295,14 +323,19 @@ sub setup_env_hash_for {
 }
 
 sub print_environment_vars_for {
-  my $self = shift;
-  print $self->environment_vars_string_for(@_);
+  print $_[0]->environment_vars_string_for(@_[1..$#_]);
 }
 
 sub environment_vars_string_for {
-  my $self = _legacy(@_);
+  my $self = $_[0]->new->activate($_[1]);
+  $self->environment_vars_string;
+}
+sub environment_vars_string {
+  my ($self, $shelltype) = @_;
 
-  my $build_method = 'build_' . $self->shelltype . '_env_declaration';
+  $shelltype ||= $self->guess_shelltype;
+
+  my $build_method = "build_${shelltype}_env_declaration";
 
   my @envs = (
     PATH                => $self->bins,
@@ -340,64 +373,99 @@ sub environment_vars_string_for {
 
 sub build_bourne_env_declaration {
   my ($class, $name, $args) = @_;
-  my $value = $class->_interpolate($args);
-  defined $value
-    ? qq{export ${name}="${value}";\n}
-    : qq{unset ${name};\n};
+  my $value = $class->_interpolate($args, '$%s', '"', '\\%s');
+
+  if (!defined $value) {
+    return qq{unset $name;\n};
+  }
+
+  $value =~ s/(^|\G|$_path_sep)\$$name$_path_sep/$1\$$name\${$name+$_path_sep}/g;
+  $value =~ s/$_path_sep\$$name$/\${$name+$_path_sep}\$$name/;
+
+  qq{${name}="$value";\nexport ${name};\n}
 }
+
 sub build_csh_env_declaration {
   my ($class, $name, $args) = @_;
-  my ($value, @vars) = $class->_interpolate($args, undef, undef, '"', qq{"\\"});
-  (join '', map qq{if ! \$?$_ setenv $_ "";\n}, @vars)
-    . (defined $value
-      ? qq{setenv $name "$value";\n}
-      : qq{unsetenv $name;\n});
+  my ($value, @vars) = $class->_interpolate($args, '$%s', '"', '"\\%s"');
+  if (!defined $value) {
+    return qq{unsetenv $name;\n};
+  }
+
+  my $out = '';
+  for my $var (@vars) {
+    $out .= qq{if ! \$?$name setenv $name '';\n};
+  }
+
+  my $value_without = $value;
+  if ($value_without =~ s/(?:^|$_path_sep)\$$name(?:$_path_sep|$)//g) {
+    $out .= qq{if "\$$name" != '' setenv $name "$value";\n};
+    $out .= qq{if "\$$name" == '' };
+  }
+  $out .= qq{setenv $name "$value_without";\n};
+  return $out;
 }
+
 sub build_cmd_env_declaration {
   my ($class, $name, $args) = @_;
-  my $value = $class->_interpolate($args, '%', '%', qr([()!^"<>&|]), '^');
-  defined $value
-    ? qq{\@set $name=$value\n}
-    : qq{\@set $name=\n};
+  my $value = $class->_interpolate($args, '%%%s%%', qr([()!^"<>&|]), '^%s');
+  if (!$value) {
+    return qq{\@set $name=\n};
+  }
+
+  my $out = '';
+  my $value_without = $value;
+  if ($value_without =~ s/(?:^|$_path_sep)%$name%(?:$_path_sep|$)//g) {
+    $out .= qq{\@if not "%$name%"=="" set $name=$value\n};
+    $out .= qq{\@if "%$name%"=="" };
+  }
+  $out .= qq{\@set $name=$value_without\n};
+  return $out;
 }
+
 sub build_powershell_env_declaration {
   my ($class, $name, $args) = @_;
-  my $value = $class->_interpolate($args, '$env:', '', '"', '`');
-  defined $value
-    ? qq{\$env:$name = "$value";\n}
-    : "Remove-Item Env:\\$name;\n";
+  my $value = $class->_interpolate($args, '$env:%s', '"', '`%s');
+
+  if (!$value) {
+    return qq{Remove-Item -ErrorAction 0 Env:\\$name;\n};
+  }
+
+  my $maybe_path_sep = qq{\$(if("\$env:$name"-eq""){""}else{"$_path_sep"})};
+  $value =~ s/(^|\G|$_path_sep)\$env:$name$_path_sep/$1\$env:$name"+$maybe_path_sep+"/g;
+  $value =~ s/$_path_sep\$env:$name$/"+$maybe_path_sep+\$env:$name+"/;
+
+  qq{\$env:$name = \$("$value");\n};
 }
 sub wrap_powershell_output {
   my ($class, $out) = @_;
   return $out || " \n";
 }
 
+sub build_fish_env_declaration {
+  my ($class, $name, $args) = @_;
+  my $value = $class->_interpolate($args, '$%s', '"', '\\%s');
+  if (!defined $value) {
+    return qq{set -e $name;\n};
+  }
+  $value =~ s/$_path_sep/ /g;
+  qq{set -x $name $value;\n};
+}
 
 sub _interpolate {
-  my ($class, $args, $start, $end, $escape, $escape_char) = @_;
+  my ($class, $args, $var_pat, $escape, $escape_pat) = @_;
   return
     unless defined $args;
-  $args = [ $args ]
-    unless ref $args;
+  my @args = ref $args ? @$args : $args;
   return
-    unless @$args;
-  $start = '$' unless defined $start;
-  $end = '' unless defined $end;
-  $escape = '"' unless defined $escape;
-  $escape_char = "\\" unless defined $escape_char;
-  my @vars;
-  my $string = join($Config{path_sep}, map {
-    if (ref $_ && ref $_ eq 'SCALAR') {
-      push @vars, $$_;
-      $start.$$_.$end;
-    }
-    else {
-      my $str = $_;
-      $str =~ s/($escape)/$escape_char$1/g;
-      $str;
-    }
-  } @$args);
-  return wantarray ? ($string, @vars) : $string;
+    unless @args;
+  my @vars = map { $$_ } grep { ref $_ eq 'SCALAR' } @args;
+  my $string = join $_path_sep, map {
+    ref $_ eq 'SCALAR' ? sprintf($var_pat, $$_) : do {
+      s/($escape)/sprintf($escape_pat, $1)/ge; $_;
+    };
+  } @args;
+  return wantarray ? ($string, \@vars) : $string;
 }
 
 sub pipeline;
@@ -419,20 +487,6 @@ sub pipeline {
   }
 }
 
-=begin testing
-
-#:: test pipeline
-
-package local::lib;
-
-{ package Foo; sub foo { -$_[1] } sub bar { $_[1]+2 } sub baz { $_[1]+3 } }
-my $foo = bless({}, 'Foo');
-Test::More::ok($foo->${pipeline qw(foo bar baz)}(10) == -15);
-
-=end testing
-
-=cut
-
 sub resolve_path {
   my ($class, $path) = @_;
 
@@ -454,25 +508,6 @@ sub resolve_empty_path {
   }
 }
 
-=begin testing
-
-#:: test classmethod setup
-
-my $c = 'local::lib';
-
-=end testing
-
-=begin testing
-
-#:: test classmethod
-
-is($c->resolve_empty_path, '~/perl5');
-is($c->resolve_empty_path('foo'), 'foo');
-
-=end testing
-
-=cut
-
 sub resolve_home_path {
   my ($class, $path) = @_;
   return $path unless ($path =~ /^~/);
@@ -502,17 +537,6 @@ sub resolve_relative_path {
   $path = File::Spec->rel2abs($path);
 }
 
-=begin testing
-
-#:: test classmethod
-
-local *File::Spec::rel2abs = sub { shift; 'FOO'.shift; };
-is($c->resolve_relative_path('bar'),'FOObar');
-
-=end testing
-
-=cut
-
 sub ensure_dir_structure_for {
   my ($class, $path) = @_;
   unless (-d $path) {
@@ -528,20 +552,6 @@ sub ensure_dir_structure_for {
   return;
 }
 
-=begin testing
-
-#:: test classmethod
-
-File::Path::rmtree('t/var/splat');
-
-$c->ensure_dir_structure_for('t/var/splat');
-
-ok(-d 't/var/splat');
-
-=end testing
-
-=cut
-
 sub guess_shelltype {
   my $shellbin
     = defined $ENV{SHELL}
@@ -556,12 +566,13 @@ sub guess_shelltype {
 
   for ($shellbin) {
     return
-        /csh/             ? 'csh'
-      : /command\.com/    ? 'cmd'
-      : /cmd\.exe/        ? 'cmd'
-      : /4nt\.exe/        ? 'cmd'
-      : /powershell\.exe/ ? 'powershell'
-                          : 'bourne';
+        /csh$/                   ? 'csh'
+      : /fish/                   ? 'fish'
+      : /command(?:\.com)?$/i    ? 'cmd'
+      : /cmd(?:\.exe)?$/i        ? 'cmd'
+      : /4nt(?:\.exe)?$/i        ? 'cmd'
+      : /powershell(?:\.exe)?$/i ? 'powershell'
+                                 : 'bourne';
   }
 }
 
@@ -598,6 +609,10 @@ From the shell -
   export PERL5LIB="/home/username/perl5/lib/perl5"
   export PATH="/home/username/perl5/bin:$PATH"
 
+From a .bashrc file -
+
+  [ $SHLVL -eq 1 ] && eval "$(perl -I$HOME/perl5/lib/perl5 -Mlocal::lib)"
+
 =head2 The bootstrapping technique
 
 A typical way to install local::lib is using what is known as the
@@ -614,12 +629,18 @@ By default local::lib installs itself and the CPAN modules into ~/perl5.
 
 Windows users must also see L</Differences when using this module under Win32>.
 
-1. Download and unpack the local::lib tarball from CPAN (search for "Download"
+=over 4
+
+=item 1.
+
+Download and unpack the local::lib tarball from CPAN (search for "Download"
 on the CPAN page about local::lib).  Do this as an ordinary user, not as root
 or administrator.  Unpack the file in your home directory or in any other
 convenient location.
 
-2. Run this:
+=item 2.
+
+Run this:
 
   perl Makefile.PL --bootstrap
 
@@ -631,16 +652,20 @@ to specify the name of the directory when you call bootstrap, as follows:
 
   perl Makefile.PL --bootstrap=~/foo
 
-3. Run this: (local::lib assumes you have make installed on your system)
+=item 3.
+
+Run this: (local::lib assumes you have make installed on your system)
 
   make test && make install
 
-4. Now we need to setup the appropriate environment variables, so that Perl
+=item 4.
+
+Now we need to setup the appropriate environment variables, so that Perl
 starts using our newly generated lib/ directory. If you are using bash or
 any other Bourne shells, you can add this to your shell startup script this
 way:
 
-  echo 'eval $(perl -I$HOME/perl5/lib/perl5 -Mlocal::lib)' >>~/.bashrc
+  echo '[ $SHLVL -eq 1 ] && eval "$(perl -I$HOME/perl5/lib/perl5 -Mlocal::lib)"' >>~/.bashrc
 
 If you are using C shell, you can do this as follows:
 
@@ -653,12 +678,14 @@ If you passed to bootstrap a directory other than default, you also need to
 give that as import parameter to the call of the local::lib module like this
 way:
 
-  echo 'eval $(perl -I$HOME/foo/lib/perl5 -Mlocal::lib=$HOME/foo)' >>~/.bashrc
+  echo '[ $SHLVL -eq 1 ] && eval "$(perl -I$HOME/foo/lib/perl5 -Mlocal::lib=$HOME/foo)"' >>~/.bashrc
 
 After writing your shell configuration file, be sure to re-read it to get the
 changed settings into your current shell's environment. Bourne shells use
 C<. ~/.bashrc> for this, whereas C shells use C<source ~/.cshrc>.
 
+=back
+
 If you're on a slower machine, or are operating under draconian disk space
 limitations, you can disable the automatic generation of manpages from POD when
 installing modules by using the C<--no-manpages> argument when bootstrapping:
@@ -678,6 +705,12 @@ installation to install modules in different directories directly this way:
   cd ../mydir2
   ... REPEAT ...
 
+When used in a C<.bashrc> file, it is recommended that you protect against
+re-activating a directory in a sub-shell.  This can be done by checking the
+C<$SHLVL> variable as shown in synopsis.  Without this, sub-shells created by
+the user or other programs will override changes made to the parent shell's
+environment.
+
 If you are working with several C<local::lib> environments, you may want to
 remove some of them from the current environment without disturbing the others.
 You can deactivate one environment like this (using bourne sh):
@@ -736,7 +769,7 @@ and the subdirectories are created.
 
 =head3 PowerShell
 
-local::lib also supports PowerShell, and an be used with the
+local::lib also supports PowerShell, and can be used with the
 C<Invoke-Expression> cmdlet.
 
   Invoke-Expression "$(perl -Mlocal::lib)"
@@ -791,6 +824,8 @@ values:
 
 =item PATH
 
+=item PERL_LOCAL_LIB_ROOT
+
 =back
 
 When possible, these will be appended to instead of overwritten entirely.
@@ -803,7 +838,7 @@ See L<lib::core::only> for one way to do this - but note that
 there are a number of caveats, and the best approach is always to perform a
 build against a clean perl (i.e. site and vendor as close to empty as possible).
 
-=head1 OPTIONS
+=head1 IMPORT OPTIONS
 
 Options are values that can be passed to the C<local::lib> import besides the
 directory to use. They are specified as C<use local::lib '--option'[, path];>
@@ -830,7 +865,7 @@ C<cmd>, or C<powershell>.
 Prevents C<local::lib> from creating directories when activating dirs.  This is
 likely to cause issues on Win32 systems.
 
-=head1 METHODS
+=head1 CLASS METHODS
 
 =head2 ensure_dir_structure_for
 
@@ -912,6 +947,20 @@ Returns a path describing where to install the Perl modules for this local
 library installation. Appends the directories C<lib> and C<perl5> to the given
 path.
 
+=head2 lib_paths_for
+
+=over 4
+
+=item Arguments: $path
+
+=item Return value: @lib_paths
+
+=back
+
+Returns the list of paths perl will search for libraries, given a base path.
+This includes the base path itself, the architecture specific subdirectory, and
+perl version specific subdirectories.  These paths may not all exist.
+
 =head2 install_base_bin_path
 
 =over 4
@@ -925,6 +974,19 @@ path.
 Returns a path describing where to install the executable programs for this
 local library installation. Appends the directory C<bin> to the given path.
 
+=head2 installer_options_for
+
+=over 4
+
+=item Arguments: $path
+
+=item Return value: %installer_env_vars
+
+=back
+
+Returns a hash of environment variables that should be set to cause
+installation into the given path.
+
 =head2 resolve_empty_path
 
 =over 4
@@ -982,6 +1044,141 @@ L</resolve_home_path>, which then has its result passed to
 L</resolve_relative_path>. The result of this final call is returned from
 L</resolve_path>.
 
+=head1 OBJECT INTERFACE
+
+=head2 new
+
+=over 4
+
+=item Arguments: %attributes
+
+=item Return value: $local_lib
+
+=back
+
+Constructs a new C<local::lib> object, representing the current state of
+C<@INC> and the relevant environment variables.
+
+=head1 ATTRIBUTES
+
+=head2 roots
+
+An arrayref representing active C<local::lib> directories.
+
+=head2 inc
+
+An arrayref representing C<@INC>.
+
+=head2 libs
+
+An arrayref representing the PERL5LIB environment variable.
+
+=head2 bins
+
+An arrayref representing the PATH environment variable.
+
+=head2 extra
+
+A hashref of extra environment variables (e.g. C<PERL_MM_OPT> and
+C<PERL_MB_OPT>)
+
+=head2 no_create
+
+If set, C<local::lib> will not try to create directories when activating them.
+
+=head1 OBJECT METHODS
+
+=head2 clone
+
+=over 4
+
+=item Arguments: %attributes
+
+=item Return value: $local_lib
+
+=back
+
+Constructs a new C<local::lib> object based on the existing one, overriding the
+specified attributes.
+
+=head2 activate
+
+=over 4
+
+=item Arguments: $path
+
+=item Return value: $new_local_lib
+
+=back
+
+Constructs a new instance with the specified path active.
+
+=head2 deactivate
+
+=over 4
+
+=item Arguments: $path
+
+=item Return value: $new_local_lib
+
+=back
+
+Constructs a new instance with the specified path deactivated.
+
+=head2 deactivate_all
+
+=over 4
+
+=item Arguments: None
+
+=item Return value: $new_local_lib
+
+=back
+
+Constructs a new instance with all C<local::lib> directories deactivated.
+
+=head2 environment_vars_string
+
+=over 4
+
+=item Arguments: [ $shelltype ]
+
+=item Return value: $shell_env_string
+
+=back
+
+Returns a string to set up the C<local::lib>, meant to be run by a shell.
+
+=head2 build_environment_vars
+
+=over 4
+
+=item Arguments: None
+
+=item Return value: %environment_vars
+
+=back
+
+Returns a hash with the variables listed above, properly set to use the
+given path as the base directory.
+
+=head2 setup_env_hash
+
+=over 4
+
+=item Arguments: None
+
+=item Return value: None
+
+=back
+
+Constructs the C<%ENV> keys for the given path, by calling
+L</build_environment_vars>.
+
+=head2 setup_local_lib
+
+Constructs the C<%ENV> hash using L</setup_env_hash>, and set up C<@INC>.
+
 =head1 A WARNING ABOUT UNINST=1
 
 Be careful about using local::lib in combination with "make install UNINST=1".
@@ -1012,6 +1209,24 @@ not set, a Bourne-compatible shell is assumed.
 
 =item * Should probably auto-fixup CPAN config if not already done.
 
+=item * local::lib loads L<File::Spec>.  When used to set shell variables,
+this isn't a problem.  When used inside a perl script, any L<File::Spec>
+version inside the local::lib will be ignored.  A workaround for this is using
+C<use lib "$ENV{HOME}/perl5/lib/perl5";> inside the script instead of using
+C<local::lib> directly.
+
+=item * Conflicts with L<ExtUtils::MakeMaker>'s C<PREFIX> option.
+C<local::lib> uses the C<INSTALL_BASE> option, as it has more predictable and
+sane behavior.  If something attempts to use the C<PREFIX> option when running
+a F<Makefile.PL>, L<ExtUtils::MakeMaker> will refuse to run, as the two
+options conflict.  This can be worked around by temporarily unsetting the
+C<PERL_MM_OPT> environment variable.
+
+=item * Conflicts with L<Module::Build>'s C<--prefix> option.  Similar to the
+previous limitation, but any C<--prefix> option specified will be ignored.
+This can be worked around by temporarily unsetting the C<PERL_MB_OPT>
+environment variable.
+
 =back
 
 Patches very much welcome for any of the above.
@@ -1112,9 +1327,12 @@ environment later on contributed by Andrew Rodland <arodland@cpan.org>.
 Patch for Carp version mismatch contributed by Hakim Cassimally
 <osfameron@cpan.org>.
 
+Rewrite of internals and numerous bug fixes and added features contributed by
+Graham Knop <haarg@haarg.org>.
+
 =head1 COPYRIGHT
 
-Copyright (c) 2007 - 2010 the local::lib L</AUTHOR> and L</CONTRIBUTORS> as
+Copyright (c) 2007 - 2013 the local::lib L</AUTHOR> and L</CONTRIBUTORS> as
 listed above.
 
 =head1 LICENSE