My urfave/cli version is
v3 (main branch)
Checklist
Dependency Management
- My project is using go modules.
Describe the bug
The generated bash completion script incorrectly parses token:description lines when the description itself contains colons.
The bash autocomplete template in autocomplete/bash_autocomplete has:
Because the template is rendered via fmt.Sprintf, the %% is interpreted as an escape sequence that produces a single %. The rendered output becomes:
${line%:*} (single %) removes the shortest suffix from the last colon, which is incorrect. The correct bash parameter expansion is ${line%%:*} (double %%), which removes the longest suffix from the first colon.
This means a completion line like export:Export various configurations such as: compose-config, user-service gets its token parsed as the entire string minus the last : compose-config, user-service fragment, producing broken spurious completions via compgen -W.
To reproduce
- Define a command with a colon in its
Usage string (e.g. Usage: "Export configs such as: compose-config")
- Source the generated bash completion script:
source <(myapp completion bash)
- Press TAB to trigger completions
- Observe spurious completion entries split from the description text
Expected behavior
Only the command name (before the first colon) should appear as a completion candidate. Descriptions containing colons should not leak into the token list.
Additional context
The fix is to use %%%% in the template so that after fmt.Sprintf, the rendered script contains %% (greedy match from first colon):
token="${line%%%%:*}" # template source
token="${line%%:*}" # rendered output (correct)
My urfave/cli version is
v3(main branch)Checklist
Dependency Management
Describe the bug
The generated bash completion script incorrectly parses
token:descriptionlines when the description itself contains colons.The bash autocomplete template in
autocomplete/bash_autocompletehas:token="${line%%:*}"Because the template is rendered via
fmt.Sprintf, the%%is interpreted as an escape sequence that produces a single%. The rendered output becomes:token="${line%:*}"${line%:*}(single%) removes the shortest suffix from the last colon, which is incorrect. The correct bash parameter expansion is${line%%:*}(double%%), which removes the longest suffix from the first colon.This means a completion line like
export:Export various configurations such as: compose-config, user-servicegets its token parsed as the entire string minus the last: compose-config, user-servicefragment, producing broken spurious completions viacompgen -W.To reproduce
Usagestring (e.g.Usage: "Export configs such as: compose-config")source <(myapp completion bash)Expected behavior
Only the command name (before the first colon) should appear as a completion candidate. Descriptions containing colons should not leak into the token list.
Additional context
The fix is to use
%%%%in the template so that afterfmt.Sprintf, the rendered script contains%%(greedy match from first colon):