prevent startup scripts in cmd/powershell
[p5sagit/local-lib.git] / t / shell.t
1 use strict;
2 use warnings;
3 use Test::More;
4 use File::Spec;
5 use File::Temp ();
6 use Config;
7 use local::lib ();
8
9 my @paths = File::Spec->path;
10 my @ext = $^O eq 'MSWin32'  ? (split /\Q$Config{path_sep}/, $ENV{PATHEXT}) : ('');
11 sub which {
12   my $shell = shift;
13   for my $dir (@paths) {
14     my $file = File::Spec->catfile($dir||'.', $shell);
15     for my $ext (@ext) {
16       my $full = $file . $ext;
17       return $full
18         if -x $full;
19     }
20   }
21   return;
22 }
23
24 my @extra_lib = do {
25   my @paths = `$^X -le"print for \@INC"`;
26   chomp @paths;
27   my %paths;
28   @paths{@paths} = ();
29   grep { !exists $paths{$_} } @INC;
30 };
31
32 my $extra_lib = join ' ', map { qq{"-I$_"} } @extra_lib;
33
34 my @shells;
35 for my $shell (
36   {
37     name => 'sh',
38   },
39   {
40     name => 'csh',
41     opt => '-f',
42   },
43   {
44     name => 'cmd',
45     opt => '/D /C',
46     ext => 'bat',
47     perl => qq{@"$^X"},
48   },
49   {
50     name => 'powershell',
51     opt => '-NoProfile -ExecutionPolicy Unrestricted',
52     ext => 'ps1',
53     perl => qq{& '$^X'},
54   },
55 ) {
56   my $name = $shell->{name};
57   next
58     if @ARGV && !grep {$_ eq $name} @ARGV;
59   $shell->{shell} = which($name) || next;
60   $shell->{ext}   ||= $name;
61   $shell->{perl}  ||= qq{"$^X"};
62   push @shells, $shell;
63 }
64
65 if (!@shells) {
66   plan skip_all => 'no supported shells found';
67 }
68 plan tests => 4*@shells;
69
70 my $sep = $Config{path_sep};
71
72 my $root = File::Spec->rootdir;
73 for my $shell (@shells) {
74   my $ll = File::Temp->newdir();
75   my $ll_dir = local::lib->normalize_path("$ll");
76   local $ENV{PERL_LOCAL_LIB_ROOT};
77   local $ENV{PATH} = $root;
78   local $ENV{PERL5LIB} = $ENV{PERL5LIB};
79   delete $ENV{PERL_LOCAL_LIB_ROOT};
80   my $env = call_ll($shell, "$ll");
81   is $env->{PERL_LOCAL_LIB_ROOT}, $ll_dir, "$shell->{name}: activate root";
82   is $env->{PATH}, local::lib->install_base_bin_path($ll_dir)."$sep$root", "$shell->{name}: activate PATH";
83
84   $ENV{$_} = $env->{$_} for qw(PATH PERL5LIB PERL_LOCAL_LIB_ROOT);
85   $env = call_ll($shell, '--deactivate', "$ll");
86
87   is $env->{PERL_LOCAL_LIB_ROOT}, undef, "$shell->{name}: deactivate root";
88   is $env->{PATH}, $root, "$shell->{name}: deactivate PATH";
89 }
90
91 sub call_ll {
92   my ($info, @options) = @_;
93   my $option = @options ? '='.join(',', @options) : '';
94
95   local $ENV{SHELL} = $info->{shell};
96
97   my $file = File::Temp->new(
98     TEMPLATE => 'll-test-script-XXXXX',
99     TMPDIR   => 1,
100     SUFFIX   => '.'.$info->{ext},
101   );
102
103   $file->print(scalar `"$^X" $extra_lib -Mlocal::lib$option` . "\n");
104   $file->print(qq{$info->{perl} -Mt::lib::ENVDumper -e1\n});
105   $file->close;
106
107   my $opt = $info->{opt} ? "$info->{opt} " : '';
108   my $out = `"$info->{shell}" $opt"$file"`;
109   if ($?) {
110     die "failed with code: $?";
111   }
112   my $VAR1;
113   eval $out or die "bad output: $@";
114   $VAR1;
115 }