tests-always-included / mo

Mustache templates in pure bash
Other
563 stars 67 forks source link

MacOS error "conditional binary operator expected" #76

Open frehoy opened 4 days ago

frehoy commented 4 days ago

Hello,

I'm unable to run mo on my Mac running Mac OS Sequoia 15.0.1 and the bundled bash GNU bash, version 3.2.57(1)-release (arm64-apple-darwin24)

MRE:

bash --version
curl -sSL https://raw.githubusercontent.com/tests-always-included/mo/master/mo -o mo
chmod +x mo
echo "foo" | ./mo

Outputs

GNU bash, version 3.2.57(1)-release (arm64-apple-darwin24)
Copyright (C) 2007 Free Software Foundation, Inc.
./mo: line 1018: conditional binary operator expected
./mo: line 1018: syntax error near `"$1"'
./mo: line 1018: `    if declare -p "$1" &> /dev/null && [[ -v "$1" ]]; then'

I've checked on two other MacOS machines running the same bash version, same error on all of them. I have one machine with a more recent bash (5.2.37) from homebrew where mo works as expected.

I did a very crude bisection, 26ca5059d8c3e635ac237a9ca8a03152d98bd191 is the latest commit that works on my machine.

fidian commented 2 days ago

I compiled that version of bash for Linux and have found that [[ -v "variable" ]] is not supported in that version. I'll have to do a workaround and possibly use declare -p exclusively because it also operates differently.

fidian commented 2 days ago

Right now my changes should work, but my custom-compiled version of Bash is failing on printf. Would you run these lines in a real version and let me know if they work for you?

mo::indirect() {
    unset -v "$1"
    printf -v "$1" '%s' "$2"
}
mo::testStuff() {
    local "$1" && mo::indirect "$1" "foo"
}
dest="bar"
mo::testStuff dest

If that works, I have a possible fix in the issue-76 branch. It solves the parsing issue and defines a version-specific function for determining if a variable is assigned. When I run it, the last line will hang my shell and it has to be killed.

frehoy commented 2 days ago

Those lines run without error in my bash 3.2.57 but they don't output anything. 😕

Could be a gnu vs bsd thing? My man printf mentions bsd but not gnu and looks nothing like the man for printf(1) I find online.

fidian commented 2 days ago

It should be using the shell's built-in printf instead of an external program, which typically writes information to screen but will write to a variable when using -v.

So, I would guess that this is now working. Are you able to try the version in the issue-76 branch? I did not yet update tests nor the version number, but this string of commands should work. Assuming it passes on your computer, I will then finish these modifications and release a new version.

curl -sSL https://raw.githubusercontent.com/tests-always-included/mo/issue-76/mo -o mo
chmod +x mo
echo "foo" | ./mo

Thank you for reporting the bug, digging into the possible reasons why the bug happened, and the extra testing that you're providing. I really appreciate it!

frehoy commented 2 days ago

Thanks! echo "foo" | ./mo works on the latest build but as soon as I try to pass in a variable I get this

MYVAR="Bob" echo "Hello {{ MYVAR }}" | ./mo
./mo: line 904: MO_FUNCTION_CACHE_HIT[@]: unbound variable