File Coverage

blib/lib/App/Rakubrew.pm
Criterion Covered Total %
statement 121 368 32.8
branch 67 208 32.2
condition 33 140 23.5
subroutine 22 30 73.3
pod 0 10 0.0
total 243 756 32.1


line stmt bran cond sub pod time code
1             package App::Rakubrew;
2 14     14   270372 use strict;
  14         26  
  14         564  
3 14     14   73 use warnings;
  14         47  
  14         758  
4 14     14   232 use 5.010;
  14         61  
5             our $VERSION = '45';
6              
7 14     14   9856 use Encode::Locale;
  14         388680  
  14         1652  
8             if (-t) {
9             binmode(STDIN, ":encoding(console_in)");
10             binmode(STDOUT, ":encoding(console_out)");
11             binmode(STDERR, ":encoding(console_out)");
12             }
13 14     14   7566 use FindBin qw($RealBin);
  14         19964  
  14         2245  
14 14     14   106 use File::Path qw(remove_tree);
  14         26  
  14         1236  
15 14     14   7306 use File::Spec::Functions qw(catfile catdir splitpath updir rel2abs);
  14         13593  
  14         1359  
16              
17 14     14   8693 use App::Rakubrew::Build;
  14         59  
  14         884  
18 14     14   99 use App::Rakubrew::Config;
  14         22  
  14         1384  
19 14     14   8108 use App::Rakubrew::Download;
  14         65  
  14         1065  
20 14     14   9646 use App::Rakubrew::Shell;
  14         48  
  14         627  
21 14     14   97 use App::Rakubrew::Tools;
  14         28  
  14         1285  
22 14     14   8303 use App::Rakubrew::Update;
  14         60  
  14         837  
23 14     14   86 use App::Rakubrew::Variables;
  14         30  
  14         2394  
24 14     14   95 use App::Rakubrew::VersionHandling;
  14         30  
  14         76094  
25              
26             sub new {
27 12     12 0 58 my ($class, @argv) = @_;
28 12         133 my %opt = (
29             args => \@argv,
30             );
31 12         41 my $self = bless \%opt, $class;
32 12         43 return $self;
33             }
34              
35             sub run_script {
36 12     12 0 32 my ($self) = @_;
37 12         27 my @args = @{$self->{args}};
  12         138  
38              
39             sub _cant_access_home {
40 0     0   0 say STDERR "Can't create rakubrew home directory in $prefix";
41 0         0 say STDERR "Probably rakubrew was denied access. You can either change that folder to be writable";
42 0         0 say STDERR "or set a different rakubrew home directory by setting the `\$RAKUBREW_HOME` environment";
43 0         0 say STDERR "prior to calling the rakubrew shell hook. ";
44 0         0 exit 1;
45             }
46              
47 12 50       380 unless (-d $prefix) {
48 0 0       0 _cant_access_home() unless mkdir $prefix;
49             }
50              
51 12 100 33     607 mkdir(catdir($prefix, 'bin')) || _cant_access_home() unless (-d catdir($prefix, 'bin'));
52 12 100 33     457 mkdir(catdir($prefix, 'update')) || _cant_access_home() unless (-d catdir($prefix, 'update'));
53 12 100 33     481 mkdir(catdir($prefix, 'repos')) || _cant_access_home() unless (-d catdir($prefix, 'repos'));
54 12 100 33     369 mkdir $shim_dir || _cant_access_home() unless (-d $shim_dir);
55 12 100 33     240 mkdir $versions_dir || _cant_access_home() unless (-d $versions_dir);
56 12 100 33     354 mkdir $git_reference || _cant_access_home() unless (-d $git_reference);
57              
58             { # Check whether we are called as a shim and forward if yes.
59 12         103 my (undef, undef, $prog_name) = splitpath($0);
60              
61             # TODO: Mac is also case insensitive. Is this way to compensate for insensitivity safe?
62 12 50 33     406 if ($prog_name ne $brew_name &&
      66        
63             ($^O !~ /win32/i || $prog_name =~ /^\Q$brew_name\E\z/i)) {
64 1         7 $self->do_exec($prog_name, \@args);
65             }
66             }
67              
68             { # Detect shell environment and initialize the shell object.
69 12         32 my $shell = '';
  11         21  
  11         25  
70 11 50 33     107 $shell = $args[1] if @args >= 2 && $args[0] eq 'internal_shell_hook';
71 11 50 33     102 $shell = $args[1] if @args >= 2 && $args[0] eq 'internal_hooked';
72 11 50 66     85 $shell = $args[1] if @args == 2 && $args[0] eq 'init';
73 11 50 66     103 $shell = $args[2] if @args == 3 && $args[0] eq 'init' && $args[1] eq '--shell';
      33        
74 11         158 $self->{hook} = App::Rakubrew::Shell->initialize($shell);
75             }
76              
77 11 50 33     83 if (@args >= 2 && $args[0] eq 'internal_hooked') { # The hook is there, all good!
    0 0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
78 11         24 shift @args; # Remove the hook so processing code below doesn't need to care about it.
79 11         26 shift @args; # Remove the shell parameter for the same reason.
80             }
81             elsif (
82             get_brew_mode() eq 'env'
83             && !(@args && $args[0] eq 'mode' && $args[1] eq 'shim')
84             && !(@args && $args[0] eq 'init')
85             && !(@args && $args[0] eq 'home')
86             && !(@args && $args[0] =~ /^internal_/)
87             || @args && $args[0] eq 'shell'
88             || @args >= 2 && $args[0] eq 'mode' && $args[1] eq 'env') {
89 0         0 say STDERR << "EOL";
90             The shell hook required to run rakubrew in either 'env' mode or with the 'shell' command seems not to be installed.
91             Run '$brew_name init' for installation instructions if you want to use those features,
92             or run '$brew_name mode shim' to use 'shim' mode which doesn't require a shell hook.
93             EOL
94 0         0 exit 1;
95             }
96              
97 11   100     51 my $arg = shift(@args) // 'help';
98              
99 11 50 33     401 if ($arg eq 'version' || $arg eq 'current') {
    100 66        
    100 66        
    50 33        
    50 33        
    50 33        
    50 33        
    50          
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    50          
    100          
    50          
    100          
    50          
    50          
    50          
    50          
    50          
    50          
100 0 0       0 if (my $c = get_version()) {
101 0 0 0     0 if (@args && $args[0] eq '--short') {
102 0         0 say "$c"
103             }
104             else {
105 0         0 say "Currently running $c"
106             }
107             } else {
108 0         0 say STDERR "Not running anything at the moment. Use '$brew_name switch' to set a version";
109 0         0 exit 1;
110             }
111              
112             } elsif ($arg eq 'versions' || $arg eq 'list') {
113 5   50     26 my $cur = get_version() // '';
114             map {
115 5         22 my $version_line = '';
  14         22  
116 14 100       32 $version_line .= 'BROKEN ' if is_version_broken($_);
117 14 100       38 $version_line .= $_ eq $cur ? '* ' : ' ';
118 14         20 $version_line .= $_;
119 14 100 50     30 $version_line .= ' -> ' . (get_version_path($_, 1) || '') if is_registered_version($_);
120 14         31 say $version_line;
121             } get_versions();
122              
123             } elsif ($arg eq 'global' || $arg eq 'switch') {
124 1 50       3 if (!@args) {
125 0         0 my $version = get_global_version();
126 0 0       0 if ($version) {
127 0         0 say $version;
128             }
129             else {
130 0         0 say "$brew_name: no global version configured";
131             }
132             }
133             else {
134             $self->match_and_run($args[0], sub {
135 1     1   5 set_global_version(shift);
136 1         9 });
137             }
138              
139             } elsif ($arg eq 'shell') {
140 0 0       0 if (!@args) {
141 0         0 my $shell_version = get_shell_version();
142 0 0       0 if (defined $shell_version) {
143 0         0 say "$shell_version";
144             }
145             else {
146 0         0 say "$brew_name: no shell-specific version configured";
147             }
148             }
149             else {
150 0         0 my $version = shift @args;
151 0 0       0 if ($version ne '--unset') {
152 0         0 verify_version($version);
153             }
154             }
155              
156             } elsif ($arg eq 'local') {
157 0         0 validate_brew_mode();
158 0 0       0 if (!@args) {
159 0         0 my $version = get_local_version();
160 0 0       0 if ($version) {
161 0         0 say $version;
162             }
163             else {
164 0         0 say "$brew_name: no local version configured for this directory";
165             }
166             }
167             else {
168 0         0 my $version = shift @args;
169 0 0       0 if ($version eq '--unset') {
170 0         0 set_local_version(undef);
171             }
172             else {
173             $self->match_and_run($version, sub {
174 0     0   0 set_local_version(shift);
175 0         0 });
176             }
177             }
178              
179             } elsif ($arg eq 'nuke' || $arg eq 'unregister') {
180 0         0 my $version = shift @args;
181 0         0 $self->nuke($version);
182              
183             } elsif ($arg eq 'rehash') {
184 0         0 validate_brew_mode();
185 0         0 rehash();
186              
187             } elsif ($arg eq 'list-available' || $arg eq 'available') {
188 0   0     0 my ($cur_backend, $cur_rakudo) = split '-', (get_version() // ''), 2;
189 0   0     0 $cur_backend //= '';
190 0   0     0 $cur_rakudo //= '';
191              
192 0         0 my @downloadables = App::Rakubrew::Download::available_precomp_archives();
193 0         0 say "Available Rakudo versions:";
194             map {
195 0         0 my $ver = $_;
  0         0  
196 0 0       0 my $d = (grep {$_->{ver} eq $ver} @downloadables) ? 'D' : ' ';
  0         0  
197 0 0       0 my $s = $cur_rakudo eq $ver ? '*' : ' ';
198 0         0 say "$s$d $ver";
199             } App::Rakubrew::Build::available_rakudos();
200 0         0 say '';
201 0         0 $cur_backend |= '';
202 0         0 $cur_rakudo |= '';
203 0         0 say "Available backends:";
204 0 0       0 map { say $cur_backend eq $_ ? "* $_" : " $_" } App::Rakubrew::Variables::available_backends();
  0         0  
205              
206             } elsif ($arg eq 'build-rakudo' || $arg eq 'build') {
207 0         0 my ($impl, $ver, @args) =
208             App::Rakubrew::VersionHandling::match_version(@args);
209 0 0       0 if (!$ver) {
210 0         0 my @versions = App::Rakubrew::Build::available_rakudos();
211 0         0 @versions = grep { /^\d\d\d\d\.\d\d/ } @versions;
  0         0  
212 0         0 $ver = $versions[-1];
213             }
214              
215 0 0       0 if ($impl eq "panda") {
    0          
    0          
216 0         0 say "panda is discontinued; please use zef (rakubrew build-zef) instead";
217             } elsif ($impl eq "zef") {
218 0         0 my $version = get_version();
219 0 0       0 if (!$version) {
220 0         0 say STDERR "$brew_name: No version set.";
221 0         0 exit 1;
222             }
223 0         0 App::Rakubrew::Build::build_zef($version);
224             # Might have new executables now -> rehash.
225 0         0 rehash();
226 0         0 say "Done, built zef for $version";
227             } elsif (!exists $impls{$impl}) {
228 0         0 my $warning = "Cannot build Rakudo with backend '$impl': this backend ";
229 0 0       0 if ($impl eq "parrot") {
230 0         0 $warning .= "is no longer supported.";
231             } else {
232 0         0 $warning .= "does not exist.";
233             }
234 0         0 say $warning;
235 0         0 exit 1;
236             }
237             else {
238 0         0 my $configure_opts = '';
239 0 0 0     0 if (@args && $args[0] =~ /^--configure-opts=/) {
240 0         0 $configure_opts = shift @args;
241 0         0 $configure_opts =~ s/^\-\-configure-opts=//;
242 0         0 $configure_opts =~ s/^'//;
243 0         0 $configure_opts =~ s/'$//;
244             }
245              
246 0 0       0 if ($configure_opts =~ /--prefix/) {
247 0         0 say STDERR "Building Rakudo in a custom folder is not supported. If you need";
248 0         0 say STDERR "this it's recommended to build it manually and then use the";
249 0         0 say STDERR "`register` command to make that installation available in Rakubrew.";
250 0         0 exit 1;
251             }
252              
253 0         0 my $name = "$impl-$ver";
254 0 0 0     0 $name = $impl if $impl eq 'moar-blead' && $ver eq 'main';
255              
256 0 0 0     0 if ($impl && $impl eq 'all') {
257 0         0 for (App::Rakubrew::Variables::available_backends()) {
258 0         0 App::Rakubrew::Build::build_impl($_, $ver, $configure_opts);
259             }
260             } else {
261 0         0 App::Rakubrew::Build::build_impl($impl, $ver, $configure_opts);
262             }
263              
264             # Might have new executables now -> rehash.
265 0         0 rehash();
266 0 0       0 if (get_version() eq 'system') {
267 0         0 set_global_version($name);
268             }
269 0         0 say "Done, $name built";
270             }
271              
272             } elsif ($arg eq 'triple') {
273 0         0 my ($rakudo_ver, $nqp_ver, $moar_ver) = @args[0 .. 2];
274 0         0 my $name = App::Rakubrew::Build::build_triple($rakudo_ver, $nqp_ver, $moar_ver);
275              
276             # Might have new executables now -> rehash
277 0         0 rehash();
278 0 0       0 if (get_version() eq 'system') {
279 0         0 set_global_version($name);
280             }
281 0         0 say "Done, $name built";
282              
283             } elsif ($arg eq 'download-rakudo' || $arg eq 'download') {
284 0         0 my ($impl, $ver, @args) =
285             App::Rakubrew::VersionHandling::match_version(@args);
286              
287 0 0       0 if (!exists $impls{$impl}) {
288 0         0 say STDERR "Cannot download Rakudo on '$impl': this backend does not exist.";
289 0         0 exit 1;
290             }
291              
292 0         0 my $name = App::Rakubrew::Download::download_precomp_archive($impl, $ver);
293              
294             # Might have new executables now -> rehash
295 0         0 rehash();
296 0 0       0 if (get_version() eq 'system') {
297 0         0 set_global_version("$name");
298             }
299 0         0 say "Done, $name installed";
300             } elsif ($arg eq 'register') {
301 1         3 my ($name, $path) = @args[0 .. 1];
302 1 50 33     5 if (!$name || !$path) {
303 0         0 say STDERR "$brew_name: Need a version name and rakudo installation path";
304 0         0 exit 1;
305             }
306 1 50       5 if (version_exists($name)) {
307 0         0 say STDERR "$brew_name: Version $name already exists";
308 0         0 exit 1;
309             }
310              
311             sub invalid {
312 0     0 0 0 my $path = shift;
313 0         0 say STDERR "$brew_name: No valid rakudo installation found at '$path'";
314 0         0 exit 1;
315             }
316 1         5 $path = rel2abs($path);
317 1 50       23 invalid($path) if is_version_path_broken($path);
318 1         3 $path = clean_version_path($path);
319              
320 1         12 spurt(catfile($versions_dir, $name), $path);
321              
322             } elsif ($arg eq 'build-zef') {
323 0         0 my $version = get_version();
324 0         0 my $zef_version = shift(@args);
325 0 0       0 if (!$version) {
326 0         0 say STDERR "$brew_name: No version set.";
327 0         0 exit 1;
328             }
329 0   0     0 say("Building zef ", $zef_version || "latest");
330 0         0 App::Rakubrew::Build::build_zef($version, $zef_version);
331             # Might have new executables now -> rehash
332 0         0 rehash();
333 0         0 say "Done, built zef for $version";
334              
335             } elsif ($arg eq 'build-panda') {
336 0         0 say "panda is discontinued; please use zef (rakubrew build-zef) instead";
337              
338             } elsif ($arg eq 'exec') {
339 0         0 my $param = shift @args;
340 0 0       0 if ($param eq '--with') {
341 0         0 my $version = shift @args;
342 0         0 my $prog_name = shift @args;
343 0         0 $self->do_exec_with_version($version, $prog_name, \@args);
344             }
345             else {
346 0         0 $self->do_exec($param, \@args);
347             }
348              
349             } elsif ($arg eq 'which') {
350 0 0       0 if (!@args) {
351 0         0 say STDERR "Usage: $brew_name which ";
352             }
353             else {
354 0         0 my $version = get_version();
355 0 0       0 if (!$version) {
356 0         0 say STDERR "$brew_name: No version set.";
357 0         0 exit 1;
358             }
359 0         0 map {say $_} which($args[0], $version);
  0         0  
360             }
361              
362             } elsif ($arg eq 'whence') {
363 0 0       0 if (!@args) {
364 0         0 say STDERR "Usage: $brew_name whence [--path] ";
365             }
366             else {
367 0         0 my $param = shift @args;
368 0         0 my $pathmode = $param eq '--path';
369 0 0       0 my $prog = $pathmode ? shift(@args) : $param;
370 0         0 map {say $_} whence($prog, $pathmode);
  0         0  
371             }
372              
373             } elsif ($arg eq 'mode') {
374 1 50       4 if (!@args) {
375 0         0 say get_brew_mode();
376             }
377             else {
378 1         5 set_brew_mode($args[0]);
379             }
380              
381             } elsif ($arg eq 'self-upgrade') {
382 0         0 App::Rakubrew::Update::update();
383              
384             } elsif ($arg eq 'init') {
385 1         8 $self->init(@args);
386              
387             } elsif ($arg eq 'home') {
388 0         0 say $prefix;
389              
390             } elsif ($arg eq 'test') {
391 0         0 my $version = shift @args;
392 0 0       0 if (!$version) {
    0          
393 0         0 $self->test(get_version());
394             }
395             elsif ($version eq 'all') {
396 0         0 for (get_versions()) {
397 0         0 $self->test($_);
398             }
399             } else {
400 0         0 $self->test($version);
401             }
402             } elsif ($arg eq 'internal_shell_hook') {
403 0         0 my $shell = shift @args;
404 0         0 my $sub = shift @args;
405 0 0       0 if (my $ref = $self->{hook}->can($sub)) {
406 0         0 $self->{hook}->$sub(@args);
407             }
408              
409             } elsif ($arg eq 'internal_win_run') {
410 0         0 my $prog_name = shift @args;
411 0         0 my $path = which($prog_name, get_version());
412             # Do some filetype detection:
413             # - .exe/.bat/.cmd -> return "filename"
414             # - .nqp -> return "nqp filename"
415             # - shebang contains raku|perl6 -> return "raku|perl6 filename"
416             # - shebang contains perl -> return "perl filename"
417             # - nothing of the above -> return "filename" # if we can't
418             # figure out what to do with this
419             # filename, let Windows have a try.
420             # The first line is potentially the shebang. Thus the search for "perl" and/or perl6/raku.
421 0         0 my ($basename, undef, $suffix) = my_fileparse($prog_name);
422 0 0       0 if($suffix =~ /^\Q\.(exe|bat|cmd)\E\z/i) {
    0          
423 0         0 say $path;
424             }
425             elsif($suffix =~ /^\Q\.nqp\E\z/i) {
426 0         0 say which('nqp', get_version()).' '.$path;
427             }
428             else {
429 0         0 open(my $fh, '<', $path);
430 0         0 my $first_line = <$fh>;
431 0         0 close($fh);
432 0 0       0 if($first_line =~ /#!.*(perl6|raku)/) {
    0          
433 0         0 say get_raku(get_version()) . ' ' . $path;
434             }
435             elsif($first_line =~ /#!.*perl/) {
436 0         0 say 'perl '.$path;
437             }
438             else {
439 0         0 say $path;
440             }
441             }
442              
443             } elsif ($arg eq 'internal_update') {
444 0         0 App::Rakubrew::Update::internal_update(@args);
445              
446             } elsif ($arg eq 'rakubrew-version') {
447 0         0 say "rakubrew v$VERSION Build type: $distro_format OS: $^O";
448              
449             } else {
450 2         1344 require Pod::Usage;
451 2         126699 my $help_text = "";
452 2         27 open my $pod_fh, ">", \$help_text;
453              
454 2         6 my $verbose = 0;
455             @args = grep {
456 2 0 0     9 if ($_ eq '-v' || $_ eq '--verbose') {
  0         0  
457 0         0 $verbose = 1;
458 0         0 0;
459             }
460 0         0 else { 1; }
461             } @args;
462              
463 2 50 33     21 if ($arg eq 'help' && @args) {
464             # the user wants help for a specific command
465             # e.g., rakubrew help list
466 0         0 my $command = $args[ 0 ];
467 0 0       0 $command = 'download-rakudo' if $command eq 'download';
468 0 0       0 $command = 'build-rakudo' if $command eq 'build';
469              
470 0         0 Pod::Usage::pod2usage(
471             -exitval => "NOEXIT", # do not terminate this script!
472             -verbose => 99, # 99 = indicate the sections
473             -sections => "COMMAND: " . lc( $command ), # e.g.: COMMAND: list
474             -output => $pod_fh, # filehandle reference
475             -noperldoc => 1 # do not call perldoc
476             );
477              
478             # some cleanup
479 0         0 $help_text =~ s/\A[^\n]+\n//s;
480 0         0 $help_text =~ s/^ //gm;
481              
482 0 0       0 $help_text = "Cannot find documentation for [$command]!" if ($help_text =~ /\A\s*\Z/);
483             }
484             else {
485             # Generic help or unknown command
486 2 50       17 Pod::Usage::pod2usage(
487             -exitval => "NOEXIT", # do not terminate this script!
488             -verbose => $verbose ? 2 : 1, # 1 = only SYNOPSIS, 2 = print everything
489             -output => $pod_fh, # filehandle reference
490             -noperldoc => 1 # do not call perldoc
491             );
492             }
493              
494 2         111085 close $pod_fh;
495              
496 2         18 my $backends = join '|', App::Rakubrew::Variables::available_backends(), 'all';
497              
498 2         0 say $help_text;
499             }
500             }
501              
502             sub match_and_run {
503 1     1 0 4 my ($self, $version, $action) = @_;
504 1 50       4 if (!$version) {
505 0         0 say "Which version do you mean?";
506 0         0 say "Available builds:";
507 0         0 map {say} get_versions();
  0         0  
508 0         0 return;
509             }
510 1 50       6 if (grep { $_ eq $version } get_versions()) {
  2         8  
511 1         5 $action->($version);
512             }
513             else {
514 0         0 say "Sorry, '$version' not found.";
515 0         0 my @match = grep { /\Q$version/ } get_versions();
  0         0  
516 0 0       0 if (@match) {
517 0         0 say "Did you mean:";
518 0         0 say $_ for @match;
519             }
520             }
521             }
522              
523             sub test {
524 0     0 0 0 my ($self, $version) = @_;
525             $self->match_and_run($version, sub {
526 0     0   0 my $matched = shift;
527 0         0 verify_version($matched);
528 0         0 my $v_dir = catdir($versions_dir, $matched);
529 0 0       0 if (!-d $v_dir) {
530 0         0 say STDERR "Version $matched was not built by rakubrew.";
531 0         0 say STDERR "Refusing to try running spectest there.";
532 0         0 exit 1;
533             }
534 0         0 chdir catdir($versions_dir, $matched);
535 0         0 say "Spectesting $matched";
536 0 0       0 if (!-f 'Makefile') {
537 0         0 say STDERR "Can only run spectest in self built Rakudos.";
538 0         0 say STDERR "This Rakudo is not self built.";
539 0         0 exit 1;
540             }
541 0         0 run(App::Rakubrew::Build::determine_make($matched), 'spectest');
542 0         0 });
543             }
544              
545             sub nuke {
546 0     0 0 0 my ($self, $version) = @_;
547             $self->match_and_run($version, sub {
548 0     0   0 my $matched = shift;
549 0 0       0 if (is_registered_version($matched)) {
    0          
    0          
550 0         0 say "Unregistering $matched";
551 0         0 unlink(catfile($versions_dir, $matched));
552             }
553             elsif ($matched eq 'system') {
554 0         0 say 'I refuse to nuke system Raku!';
555 0         0 exit 1;
556             }
557             elsif ($matched eq get_version()) {
558 0         0 say "$matched is currently active. I refuse to nuke.";
559 0         0 exit 1;
560             }
561             else {
562 0         0 say "Nuking $matched";
563 0         0 remove_tree(catdir($versions_dir, $matched));
564             }
565 0         0 });
566             # Might have lost executables -> rehash
567 0         0 rehash();
568             }
569              
570             sub init {
571 1     1 0 3 my $self = shift;
572 1         11 my $brew_exec = catfile($RealBin, $brew_name);
573 1 50       5 if (+@_ == 1) {
574             # We have an argument. That has to be the shell.
575             # We already retrieved the shell above, so no need to look at the passed argument here again.
576 1         7 say $self->{hook}->get_init_code;
577             }
578             else {
579 0         0 my $shell = ref($self->{hook});
580 0         0 $shell =~ s/.+:://;
581 0         0 my $shell_text = join('|', App::Rakubrew::Shell->available_shells);
582 0         0 my $text = <
583             Your shell has been identified as $shell. If that's wrong, run
584              
585             $brew_exec init --shell $shell_text
586             EOT
587 0         0 say $text;
588 0         0 say $self->{hook}->install_note;
589             }
590             }
591              
592             sub de_par_environment {
593             # The PAR packager modifies the environment.
594             # We undo those modifications here.
595              
596             # The following code was kindly provided by Roderich Schupp
597             # via email.
598 0     0 0 0 my $ldlibpthname = $Config::Config{ldlibpthname};
599 0         0 my $path_sep = $Config::Config{path_sep};
600 0         0 $ENV{$ldlibpthname} =~ s/^ \Q$ENV{PAR_TEMP}\E $path_sep? //x;
601              
602 0         0 delete $ENV{PAR_0};
603 0         0 delete $ENV{PAR_INITIALIZED};
604 0         0 delete $ENV{PAR_PROGNAME};
605 0         0 delete $ENV{PAR_TEMP};
606             }
607              
608             sub do_exec_with_version {
609 1     1 0 5 my ($self, $version, $program, $args) = @_;
610              
611 1         6 my $target = which($program, $version);
612              
613             # Undo PAR env modifications.
614             # Only need to do this on MacOS, as only there
615             # PAR is used and rakubrew itself does the `exec`.
616             # (Windows also uses PAR, but has a .bat shim that
617             # does the `exec`.)
618 1 50 33     9 if ($distro_format eq 'macos' || $distro_format eq 'macos_arm') {
619 0         0 de_par_environment;
620             }
621            
622             # Run.
623 1         2 exec { $target } ($target, @$args);
  1         0  
624 0         0 die "Executing $target failed with: $!";
625             }
626              
627             sub do_exec {
628 1     1 0 4 my ($self, $program, $args) = @_;
629 1         7 $self->do_exec_with_version(get_version(), $program, $args);
630             }
631              
632             1;
633              
634             __END__