mvdan / sh

A shell parser, formatter, and interpreter with bash support; includes shfmt
https://pkg.go.dev/mvdan.cc/sh/v3
BSD 3-Clause "New" or "Revised" License
7.27k stars 345 forks source link

Leading parens incorrectly removed from some case statements #851

Closed sdball closed 2 years ago

sdball commented 2 years ago

The following bash is valid in bash 3.2+

_script_dir="$(
    _program="$0"
    case "$_program" in
    (*/*) ;;
    (*) _program=$(command -v -- "$0") ;;
    esac
    [[ -L "$_program" ]] && _program=$(readlink "$_program")
    cd -P -- "$(dirname -- "$_program")" && pwd -P
)"

But shfmt removes the leading parens on the cases which works in bash 4+ but not bash 3

_script_dir="$(
    _program="$0"
    case "$_program" in
    */*) ;;
    *) _program=$(command -v -- "$0") ;;
    esac
    [[ -L "$_program" ]] && _program=$(readlink "$_program")
    cd -P -- "$(dirname -- "$_program")" && pwd -P
)"
mvdan commented 2 years ago

See the first half of https://github.com/mvdan/sh/issues/779, which reported the same issue. In short, this is a consistent formatting choice, and it feels too small and uninteresting to warrant yet another formatting option of its own :)

sdball commented 2 years ago

Oh thanks for pointing me to the issue. I searched but missed that one.

I agree it's very much an edge, but it means I can't use shfmt on a script that I'd like to continue to work with Bash 3.2.

With the leading parens removed bash 3.2 points to the */*) as invalid

command substitution: syntax error near unexpected token `newline'

I really love shfmt, I think I'll see about rewriting this (admittedly weird) snippet to avoid the issue.