fix(scripts): portable uppercase for branch-name acronym retention (bash 3.2) (#3192)

* fix(scripts): portable uppercase for branch-name acronym retention

Branch-name generation keeps short uppercase acronyms (e.g. "AI") by re-checking
the lowercased word against the original description with ${word^^}. That
parameter expansion is bash 4+ only; on macOS's default bash 3.2 it errors with
"bad substitution", so the acronym/short-word retention branch never matches and
those words are dropped ("go AI now" yields 001-now instead of 001-ai-now). Use
tr '[:lower:]' '[:upper:]' instead, which is portable.

Applies to both the core create-new-feature.sh and the git extension's
create-new-feature-branch.sh. The existing
test_branch_name_short_word_case_sensitivity / test_short_word_retention tests
cover this and now pass on bash 3.2 (CI runs on bash 4+/Linux, so they passed
there already).

(Disclosure: an AI coding agent surfaced the failure while running the suite on
macOS and pinned the root cause; fix written and reviewed by me.)

* fix(scripts): portability follow-ups from code review

- core create-new-feature.sh: match the acronym with `grep -qw` (POSIX
  whole-word) instead of `\b...\b` (GNU/BSD-only), matching the git extension
  and dropping a non-POSIX construct.
- lint: add a CI guard rejecting bash 4+ case-modification expansions in *.sh.
  shellcheck assumes bash 4+ from the shebang and can't flag them, and CI has no
  bash-3.2 lane, so this prevents silently re-shipping the macOS regression this
  PR fixes.
- update a stale PowerShell extension comment that cited the removed bash idiom.

(Disclosure: prompted by an AI code review of the PR; written and reviewed by me.)
This commit is contained in:
Pascal THUET
2026-06-30 16:34:09 +02:00
committed by GitHub
parent c47dd2b812
commit 86709f6089
4 changed files with 24 additions and 6 deletions

View File

@@ -253,9 +253,10 @@ function Get-BranchName {
if ($word.Length -ge 3) {
$meaningfulWords += $word
} elseif ($Description -cmatch "\b$($word.ToUpper())\b") {
# Case-sensitive (-cmatch) to mirror the bash twin's `grep -qw -- "${word^^}"`:
# keep a short word only when its UPPERCASE form appears in the original
# (an acronym). -match is case-insensitive and would keep every short word.
# Case-sensitive (-cmatch) to mirror the bash twin's case-sensitive
# whole-word acronym match: keep a short word only when its UPPERCASE
# form appears in the original (an acronym). -match is case-insensitive
# and would keep every short word.
$meaningfulWords += $word
}
}