-
-
Notifications
You must be signed in to change notification settings - Fork 75
Description
Hi @ko1nksm
Intro
First of all lemme thank you a lot for the really great job you've done developing Shellspec.
I've expressed my respect at the special note in readme of @juliyvchirkov/sh.which project.
The bug report
The bug has been faced with the lastShellspec v0.28.1 and Yash v2.56.1.
Everything goes fine1 if Yash is launched as yash binary thus runnning in it's default mode.
But if Yash is launched in POSIX mode (either thru command line option yash -o posixlycorrect or, much more closer to the real life field case, thru symlink sh created by ln -s yash sh), Shellspec crashes to handle the shell due to fatal failure.
At libexec/shellspec-inspection.sh, line 93 and lib/general.sh, line 19 you rely on the environment variable YASH_VERSION, and assume the shell is yash is this variable is set.
But the thing is Yash shell propagates own version regardless of the mode engaded at a moment. YASH_VERSION is raised by yash binary in it's default mode, and yash binary launched as yash -o posixlycorrect or thru sh symlink raises it as well.
This leads to the conflict, arising when the shell inspection routine incorrectly treating Yash sh as the regular Yash utilizes during the inspection the functionshellspec_readfile_yash_array() at line 385 of lib/general.sh.
The first hard failure arrives at line 388 when the shell inspection routine tries to execute typeset IFS="" shellspec_readfile_line="". This directive leads to the yash refusal and uncaught error typeset: non-portable built-in is not supported in the POSIXly-correct mode reported by yash to /dev/stderr.
The try to suspend the above error with 2>/dev/null is a senseless move, since the next triple of lines 389, 391 and 393 turns out to be impassable in POSIX mode anyway.
shellspec_readfile_yash_array() {
[ -e "$2" ] || { unset "$1" ||:; return 0; }
[ -s "$2" ] || { eval "$1=''"; return 0; }
typeset IFS="" shellspec_readfile_line=""
array -- "$1"
while read -r shellspec_readfile_line; do
array -i -- "$1" -1 "${shellspec_readfile_line}${SHELLSPEC_LF}"
done < "$2"
array -i -- "$1" -1 "$shellspec_readfile_line"
eval "$1=\"\${$1[*]}\""
}The shell inspection routine, treating Yash sh as the regular Yash, tries to inspect the array built-in, which is the special extension implemented byYash vendor to enrich and simplify the arrays related routines at once. The Array built-in is the exclusive feature of yash interpreter, and the vendor warns it is not defined in the POSIX standard, thus any try to utilize it in POSIX mode results in no such command `array' error.
For the moment to avoid the above conflict with Shellspec v0.28.1 I've utilized the solution with a rough auto patch applied to Shellspec code on the fly before running tests. The conflict is resolved by injection of the following one liner to the head of lib/general.sh before the origin code.
[ -z "${YASH_VERSION:-}" ] || { set +o | grep "+o posix" >/dev/null 2>&1 || unset YASH_VERSION; }This way if Yash is running in POSIX mode, Shellspec treats it as noname sh, which forces the inspection routine to use only POSIX-compliant methods for shell inspection, and thus Shellspec processes the tests rounds withYash sh at its best.
Footnotes
-
Except for much more longer period of time
Shellspecspends onyashshell inspection before running tests vs its inspection time forbash,dash,zshet cetera. But that's kinda beyond the scope of my current report, and moreover, upon the reflection this should no wai be treated as a trouble, 'cause the key stone of a great testing framework is correct tests handling and processing, and the speed is no doubt secondary. ↩