normalize path whenever possible, not only on activate
[p5sagit/local-lib.git] / lib / local / lib.pm
index 68baba7..9d7d69e 100644 (file)
@@ -181,6 +181,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;
 
@@ -232,8 +233,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;
 
@@ -256,6 +256,13 @@ sub activate {
   $self->clone(%args);
 }
 
+sub normalize_path {
+  my ($self, $path) = @_;
+  $path = ( Win32::GetShortPathName($path) || $path )
+    if $^O eq 'MSWin32';
+  return $path;
+}
+
 sub _legacy {
   my ($self, $path) = @_;
   $self = $self->new unless ref $self;
@@ -341,30 +348,51 @@ sub environment_vars_string_for {
 sub build_bourne_env_declaration {
   my ($class, $name, $args) = @_;
   my $value = $class->_interpolate($args);
+  my $joined;
+  for (@$value) {
+    if (!defined $joined) {
+      $joined = $_;
+    }
+    elsif ($_ eq "\$$name") {
+      $joined .= "\${$name+$Config{path_sep}}$_";
+    }
+    else {
+      $joined .= "$Config{path_sep}$_";
+    }
+  }
   defined $value
-    ? qq{export ${name}="${value}";\n}
+    ? qq{export ${name}="$joined";\n}
     : qq{unset ${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 $out = '';
+  if (@vars) {
+    $out = qq{if \$?$name };
+  }
+  $out .= defined $value ? qq{setenv $name "}.join($Config{path_sep},@$value).qq{";\n} : qq{unsetenv $name;\n};
+  if (@vars) {
+    my $no_var = $class->_interpolate([ grep { !ref } @$args ], undef, undef, '"', qq{"\\"});
+    if (defined $no_var) {
+      $out .= qq{if ! \$?$name setenv $name "}.join($Config{path_sep},@$no_var).qq{";\n};
+    }
+  }
+  $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};
+    ? qq{\@set $name=}.join($Config{path_sep},@$value).qq{\n}
+    : qq{\@set $name=\n};
 }
 sub build_powershell_env_declaration {
   my ($class, $name, $args) = @_;
   my $value = $class->_interpolate($args, '$env:', '', '"', '`');
   defined $value
-    ? qq{\$env:$name = "$value";\n}
+    ? qq{\$env:$name = "}.join($Config{path_sep},@$value).qq{";\n}
     : "Remove-Item Env:\\$name;\n";
 }
 sub wrap_powershell_output {
@@ -377,7 +405,7 @@ sub _interpolate {
   my ($class, $args, $start, $end, $escape, $escape_char) = @_;
   return
     unless defined $args;
-  return $args
+  $args = [ $args ]
     unless ref $args;
   return
     unless @$args;
@@ -386,7 +414,7 @@ sub _interpolate {
   $escape = '"' unless defined $escape;
   $escape_char = "\\" unless defined $escape_char;
   my @vars;
-  my $string = join($Config{path_sep}, map {
+  my $string = [ map {
     if (ref $_ && ref $_ eq 'SCALAR') {
       push @vars, $$_;
       $start.$$_.$end;
@@ -396,7 +424,7 @@ sub _interpolate {
       $str =~ s/($escape)/$escape_char$1/g;
       $str;
     }
-  } @$args);
+  } @$args ];
   return wantarray ? ($string, @vars) : $string;
 }
 
@@ -556,12 +584,12 @@ sub guess_shelltype {
 
   for ($shellbin) {
     return
-        /csh/             ? 'csh'
-      : /command\.com/    ? 'cmd'
-      : /cmd\.exe/        ? 'cmd'
-      : /4nt\.exe/        ? 'cmd'
-      : /powershell\.exe/ ? 'powershell'
-                          : 'bourne';
+        /csh/              ? 'csh'
+      : /command\.com/i    ? 'cmd'
+      : /cmd\.exe/i        ? 'cmd'
+      : /4nt\.exe/i        ? 'cmd'
+      : /powershell\.exe/i ? 'powershell'
+                           : 'bourne';
   }
 }
 
@@ -647,7 +675,7 @@ If you are using C shell, you can do this as follows:
   /bin/csh
   echo $SHELL
   /bin/csh
-  perl -I$HOME/perl5/lib/perl5 -Mlocal::lib >> ~/.cshrc
+  echo 'eval `perl -I$HOME/perl5/lib/perl5 -Mlocal::lib`' >> ~/.cshrc
 
 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
@@ -725,7 +753,7 @@ C<CMD.exe>, you can use this:
   C:\>perl -Mlocal::lib > %TEMP%\tmp.bat && %TEMP%\tmp.bat && del %TEMP%\tmp.bat
   ### instead of $(perl -Mlocal::lib=./)
 
-If you want the environment entries to persist, you'll need to add then to the
+If you want the environment entries to persist, you'll need to add them to the
 Control Panel's System applet yourself or use L<App::local::lib::Win32Helper>.
 
 The "~" is translated to the user's profile directory (the directory named for
@@ -734,6 +762,13 @@ the user under "Documents and Settings" (Windows XP or earlier) or "Users"
 directory is translated to a short name (which means the directory must exist)
 and the subdirectories are created.
 
+=head3 PowerShell
+
+local::lib also supports PowerShell, and an be used with the
+C<Invoke-Expression> cmdlet.
+
+  Invoke-Expression "$(perl -Mlocal::lib)"
+
 =head1 RATIONALE
 
 The version of a Perl package on your machine is not always the version you