BATsh
view release on metacpan or search on metacpan
- External-Perl PATH portability (vector C): the test suite and the
eg/ examples shell out to a bareword "perl", but a CPAN smoker
frequently does NOT have the perl under test on PATH as "perl"
(perlbrew/plenv, or perl invoked by absolute path). The bareword
then resolves to nothing ("perl: not found", empty output), which
failed t/0007 EE01/EE02 and t/0006 NF23/NF60 and -- worse -- let
t/0006 NF07/NF21/NF22 report a corrupted, empty-named "ok" when the
failed pipe disturbed the captured-STDOUT save/restore; in eg/06 it
also hung (an empty "perl" command substitution fed a
"while read ... < $EMPTY" redirect whose read fell back to terminal
STDIN and blocked). Fixed WITHOUT touching the command strings or
the examples (a bareword "perl" is the correct thing for an end
user to type, and embedding an absolute $^X path would expose a
Win32 backslash path to SH-mode quote/escape processing): each
affected test now prepends the directory of the running interpreter
($^X) to PATH so the bareword "perl" resolves to the very perl now
running the suite. The prepend is installed before the first
BATsh::Env::init() (init() snapshots %ENV into STORE and
sync_to_env() copies STORE back to %ENV before each external
command). Touched: t/0006-new-features.t, t/0007-extcmd-env.t,
t/9070-examples.t (the last for the eg/ child process). Verified on
nothing. The capture file is now tagged with the active
substitution-nesting depth.
(2) _split_sh_pipe() counted the "(" of a "$(" twice, leaving the
$( nesting depth stuck at 1 after a nested $(...); a bare "|"
that followed it was then not recognised as a pipe. "$(" now
consumes both characters and bumps the depth exactly once.
(3) _exec_sh_pipe() named its per-stage temp files with the
process id alone (batsh_shp_$$) and left its dup STDOUT/STDIN
globs un-local()ised. A nested pipeline therefore clobbered
the outer pipeline's stage file and saved handles; the outer's
final segment found no input file and blocked on the real
STDIN (a hang on Unix). The stage files are now tagged with
the active pipeline-nesting depth and the handle globs are
local()ised. All fixes are Perl 5.005_03 compatible (use vars
package globals, bareword filehandles, 2-argument open). The
command strings and the externally-visible API are unchanged.
- t/0008-nested-subst.t: new regression test for the fix above. NS01/
NS02 prove the capture-file depth fix with pure builtins (no "perl"
on PATH required); NS03 is the single-level pipeline-in-$() baseline;
NS04/NS05 cover nested $() with a pipeline at each level (defects 2
t/0005-verify_compat.t view on Meta::CPAN
},
sub {
my $out = _capture_cmd(
'SET CNT=0',
'FOR %%i IN (a b c) DO (',
' SET CNT=%%i',
' ECHO %CNT%',
')',
);
_ok($out eq "0\n0\n0\n", '5-3: FOR block %CNT% locked at FOR-line parse time (0)');
},
sub {
my $out = _capture_cmd('SET Z=first', 'SET Z=second', 'ECHO %Z%');
_ok($out eq "second\n", '5-4: outside blocks %VAR% is runtime (sees latest SET)');
},
# ==============================================================
# Step 6: FOR /F
# ==============================================================
t/0008-nested-subst.t view on Meta::CPAN
# "$(" twice, so after a nested $(...) the $( nesting depth was
# stuck at 1 and a bare '|' that followed it was not recognised as
# a pipe. Fixed by consuming both characters of "$(" and bumping
# the depth exactly once.
#
# (3) PIPE-STAGE COLLISION + UNLOCALIZED HANDLES -- _exec_sh_pipe()
# named its stage files with the process id alone (batsh_shp_$$)
# and left its dup STDOUT/STDIN globs un-local()ised. A nested
# pipeline (a segment whose $(...) body is itself a pipeline) then
# clobbered the outer pipeline's stage file and saved handles; the
# outer's final segment found no input file and blocked on the real
# STDIN (a hang on Unix). Fixed by tagging the stage files with the
# active pipeline-nesting depth and local()ising the handle globs.
#
# THIS TEST
# NS01/NS02 pure-builtin nesting (no external command): proves the
# capture-file depth fix independently of any "perl" on PATH.
# NS03 single-level $(...) that contains a pipeline (baseline).
# NS04/NS05 nested $(...) with a pipeline at each level: the core
# regression for defects (2) and (3).
# NS06 two sibling $(...) pipelines on one line: no cross-collision
( run in 0.350 second using v1.01-cache-2.11-cpan-bbe5e583499 )