Repository: clap-rs/clap (language: rust)

Issue:
Bash completion emits error about invalid nosort option
### Please complete the following tasks

- [X] I have searched the [discussions](https://github.com/clap-rs/clap/discussions)
- [X] I have searched the [open](https://github.com/clap-rs/clap/issues) and [rejected](https://github.com/clap-rs/clap/issues?q=is%3Aissue+label%3AS-wont-fix+is%3Aclosed) issues

### Rust Version

rustc 1.73.0 (cc66ad468 2023-10-03)

### Clap Version

`ruff` package version `0.0.292`which specifies `clap = { version = "4.4.7", features = ["derive"] }`

### Minimal reproducible code

not relevant

### Steps to reproduce the bug with the above code

`brew install ruff`
and somewhere in your `.bash_profile` or `.bashrc`
```bash
if [ -f $(brew --prefix)/etc/bash_completion ]; then
    . $(brew --prefix)/etc/bash_completion
fi
```

### Actual Behaviour

When I open a new shell, the following error message is displayed
```bash
bash: complete: nosort: invalid option name
```

### Expected Behaviour

No error message should be displayed.

### Additional Context

Hello beautiful `clap` people. I come from [this issue](https://github.com/astral-sh/ruff/issues/8361) with the `ruff` package (plugin ? crate ? I'm not a rust person). I'll say here again the issue I described there : 
- am macOS user
- use `ruff` (which relies on `clap`) installed through `homebrew`
- use `bash_completions` for the installed homebrew packages (see *Steps to reproduce* above)
- this triggers the issue
Presumably, the issue is that the `nosort` option is supported starting from bash v4 only, while macOS still uses bash v3. See [this comment by @zanieb](https://github.com/astral-sh/ruff/issues/8361#issuecomment-1785981659) which locates where this happens in `clap`.

I'm not sure if this is a bug or if `clap` is not trying to support old bash versions. Again I'm not a `clap` nor even a rust user.

### Debug Output

_No response_


Discussion / hints:
Completions are mostly community maintained on a best-effort.  If there is a reasonable way to skip `nosort` for bash v3 but to keep it for v4+, I'm willing to accept for it.
Thanks for the quick response. The bash version is accessible with the `${BASH_VERSINFO[0]}` variable. I'd wait for the input of someone who knows bash more than I do but I suppose something like
```diff
- complete -F _{name} -o nosort -o bashdefault -o default {name}
+ if [ ${BASH_VERSINFO[0]} -ge 4 ]; then
+     complete -F _{name} -o nosort -o bashdefault -o default {name}
+ else
+     complete -F _{name} -o bashdefault -o default {name}
+ fi
```
would be good enough.
It was added in bash 4.4, checking >= 4 isn't enough
Whats the likelihood someone is using <4.4 who isn't on Mac and using v3?
@epage I think CentOS 7 uses Bash 4.2, which is one of the platforms that led to https://github.com/sharkdp/fd/issues/1407.

A fully correct check is not too hard, something like

```sh
major=${BASH_VERSINFO[0]}
minor=${BASH_VERSINFO[1]}
if ((major > 4 || (major == 4 && minor >= 4))); then
    complete -F _{name} -o nosort -o bashdefault -o default {name}
else
    complete -F _{name} -o bashdefault -o default {name}
fi
```
> Whats the likelihood someone is using <4.4 who isn't on Mac and using v3?

FYI, I just hit this on a supercomputing cluster (via fd) which is rocking SLES12 and:
```
$ bash --version
GNU bash, version 4.3.48(1)-release (x86_64-suse-linux-gnu)
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
```
So, yeah, old OSs and old bashes live out there. Though I'm apparently right at the edge :)

(NOTE: Soon we will move to SLES15 and be closer to modern day.)
Ouch :)  Enjoy the upgrade!
(btw to be clear, a PR fixing this from anyone would be welcome)

Fix patch:
diff --git a/clap_complete/src/shells/bash.rs b/clap_complete/src/shells/bash.rs
index 2a97e1de2fe..726078ab366 100644
--- a/clap_complete/src/shells/bash.rs
+++ b/clap_complete/src/shells/bash.rs
@@ -58,7 +58,11 @@ impl Generator for Bash {
     esac
 }}
 
-complete -F _{name} -o nosort -o bashdefault -o default {name}
+if [[ \"${{BASH_VERSINFO[0]}}\" -eq 4 && \"${{BASH_VERSINFO[1]}}\" -ge 4 || \"${{BASH_VERSINFO[0]}}\" -gt 4 ]]; then
+    complete -F _{name} -o nosort -o bashdefault -o default {name}
+else
+    complete -F _{name} -o bashdefault -o default {name}
+fi
 ",
                 name = bin_name,
                 cmd = bin_name.replace('-', "__"),


Test patch:
diff --git a/clap_complete/tests/snapshots/aliases.bash b/clap_complete/tests/snapshots/aliases.bash
index 15651587242..ff9b1b8324c 100644
--- a/clap_complete/tests/snapshots/aliases.bash
+++ b/clap_complete/tests/snapshots/aliases.bash
@@ -51,4 +51,8 @@ _my-app() {
     esac
 }
 
-complete -F _my-app -o nosort -o bashdefault -o default my-app
+if [[ "${BASH_VERSINFO[0]}" -eq 4 && "${BASH_VERSINFO[1]}" -ge 4 || "${BASH_VERSINFO[0]}" -gt 4 ]]; then
+    complete -F _my-app -o nosort -o bashdefault -o default my-app
+else
+    complete -F _my-app -o bashdefault -o default my-app
+fi
diff --git a/clap_complete/tests/snapshots/basic.bash b/clap_complete/tests/snapshots/basic.bash
index 6ccd2e9deca..eab7065acff 100644
--- a/clap_complete/tests/snapshots/basic.bash
+++ b/clap_complete/tests/snapshots/basic.bash
@@ -103,4 +103,8 @@ _my-app() {
     esac
 }
 
-complete -F _my-app -o nosort -o bashdefault -o default my-app
+if [[ "${BASH_VERSINFO[0]}" -eq 4 && "${BASH_VERSINFO[1]}" -ge 4 || "${BASH_VERSINFO[0]}" -gt 4 ]]; then
+    complete -F _my-app -o nosort -o bashdefault -o default my-app
+else
+    complete -F _my-app -o bashdefault -o default my-app
+fi
diff --git a/clap_complete/tests/snapshots/feature_sample.bash b/clap_complete/tests/snapshots/feature_sample.bash
index e5119ae6109..2506f3beab9 100644
--- a/clap_complete/tests/snapshots/feature_sample.bash
+++ b/clap_complete/tests/snapshots/feature_sample.bash
@@ -107,4 +107,8 @@ _my-app() {
     esac
 }
 
-complete -F _my-app -o nosort -o bashdefault -o default my-app
+if [[ "${BASH_VERSINFO[0]}" -eq 4 && "${BASH_VERSINFO[1]}" -ge 4 || "${BASH_VERSINFO[0]}" -gt 4 ]]; then
+    complete -F _my-app -o nosort -o bashdefault -o default my-app
+else
+    complete -F _my-app -o bashdefault -o default my-app
+fi
diff --git a/clap_complete/tests/snapshots/home/static/exhaustive/bash/.bashrc b/clap_complete/tests/snapshots/home/static/exhaustive/bash/.bashrc
index f28713111d7..490fcbf3c1d 100644
--- a/clap_complete/tests/snapshots/home/static/exhaustive/bash/.bashrc
+++ b/clap_complete/tests/snapshots/home/static/exhaustive/bash/.bashrc
@@ -1002,5 +1002,9 @@ _exhaustive() {
     esac
 }
 
-complete -F _exhaustive -o nosort -o bashdefault -o default exhaustive
+if [[ "${BASH_VERSINFO[0]}" -eq 4 && "${BASH_VERSINFO[1]}" -ge 4 || "${BASH_VERSINFO[0]}" -gt 4 ]]; then
+    complete -F _exhaustive -o nosort -o bashdefault -o default exhaustive
+else
+    complete -F _exhaustive -o bashdefault -o default exhaustive
+fi
 
diff --git a/clap_complete/tests/snapshots/quoting.bash b/clap_complete/tests/snapshots/quoting.bash
index 7f8236061b7..27064ea48eb 100644
--- a/clap_complete/tests/snapshots/quoting.bash
+++ b/clap_complete/tests/snapshots/quoting.bash
@@ -273,4 +273,8 @@ _my-app() {
     esac
 }
 
-complete -F _my-app -o nosort -o bashdefault -o default my-app
+if [[ "${BASH_VERSINFO[0]}" -eq 4 && "${BASH_VERSINFO[1]}" -ge 4 || "${BASH_VERSINFO[0]}" -gt 4 ]]; then
+    complete -F _my-app -o nosort -o bashdefault -o default my-app
+else
+    complete -F _my-app -o bashdefault -o default my-app
+fi
diff --git a/clap_complete/tests/snapshots/special_commands.bash b/clap_complete/tests/snapshots/special_commands.bash
index 12b3d154348..164eed449ba 100644
--- a/clap_complete/tests/snapshots/special_commands.bash
+++ b/clap_complete/tests/snapshots/special_commands.bash
@@ -213,4 +213,8 @@ _my-app() {
     esac
 }
 
-complete -F _my-app -o nosort -o bashdefault -o default my-app
+if [[ "${BASH_VERSINFO[0]}" -eq 4 && "${BASH_VERSINFO[1]}" -ge 4 || "${BASH_VERSINFO[0]}" -gt 4 ]]; then
+    complete -F _my-app -o nosort -o bashdefault -o default my-app
+else
+    complete -F _my-app -o bashdefault -o default my-app
+fi
diff --git a/clap_complete/tests/snapshots/sub_subcommands.bash b/clap_complete/tests/snapshots/sub_subcommands.bash
index 0b64301de04..ef1925b6f94 100644
--- a/clap_complete/tests/snapshots/sub_subcommands.bash
+++ b/clap_complete/tests/snapshots/sub_subcommands.bash
@@ -233,4 +233,8 @@ _my-app() {
     esac
 }
 
-complete -F _my-app -o nosort -o bashdefault -o default my-app
+if [[ "${BASH_VERSINFO[0]}" -eq 4 && "${BASH_VERSINFO[1]}" -ge 4 || "${BASH_VERSINFO[0]}" -gt 4 ]]; then
+    complete -F _my-app -o nosort -o bashdefault -o default my-app
+else
+    complete -F _my-app -o bashdefault -o default my-app
+fi
diff --git a/clap_complete/tests/snapshots/subcommand_last.bash b/clap_complete/tests/snapshots/subcommand_last.bash
index 86b9cf47dee..32a9dd54bbb 100644
--- a/clap_complete/tests/snapshots/subcommand_last.bash
+++ b/clap_complete/tests/snapshots/subcommand_last.bash
@@ -137,4 +137,8 @@ _my-app() {
     esac
 }
 
-complete -F _my-app -o nosort -o bashdefault -o default my-app
+if [[ "${BASH_VERSINFO[0]}" -eq 4 && "${BASH_VERSINFO[1]}" -ge 4 || "${BASH_VERSINFO[0]}" -gt 4 ]]; then
+    complete -F _my-app -o nosort -o bashdefault -o default my-app
+else
+    complete -F _my-app -o bashdefault -o default my-app
+fi
diff --git a/clap_complete/tests/snapshots/two_multi_valued_arguments.bash b/clap_complete/tests/snapshots/two_multi_valued_arguments.bash
index 262a1fac955..a6e98b5db69 100644
--- a/clap_complete/tests/snapshots/two_multi_valued_arguments.bash
+++ b/clap_complete/tests/snapshots/two_multi_valued_arguments.bash
@@ -35,4 +35,8 @@ _my-app() {
     esac
 }
 
-complete -F _my-app -o nosort -o bashdefault -o default my-app
+if [[ "${BASH_VERSINFO[0]}" -eq 4 && "${BASH_VERSINFO[1]}" -ge 4 || "${BASH_VERSINFO[0]}" -gt 4 ]]; then
+    complete -F _my-app -o nosort -o bashdefault -o default my-app
+else
+    complete -F _my-app -o bashdefault -o default my-app
+fi
diff --git a/clap_complete/tests/snapshots/value_hint.bash b/clap_complete/tests/snapshots/value_hint.bash
index 0fb4696e82d..61e2f61e96e 100644
--- a/clap_complete/tests/snapshots/value_hint.bash
+++ b/clap_complete/tests/snapshots/value_hint.bash
@@ -115,4 +115,8 @@ _my-app() {
     esac
 }
 
-complete -F _my-app -o nosort -o bashdefault -o default my-app
+if [[ "${BASH_VERSINFO[0]}" -eq 4 && "${BASH_VERSINFO[1]}" -ge 4 || "${BASH_VERSINFO[0]}" -gt 4 ]]; then
+    complete -F _my-app -o nosort -o bashdefault -o default my-app
+else
+    complete -F _my-app -o bashdefault -o default my-app
+fi
diff --git a/clap_complete/tests/snapshots/value_terminator.bash b/clap_complete/tests/snapshots/value_terminator.bash
index fb2e3d5e9fd..d37b205a295 100644
--- a/clap_complete/tests/snapshots/value_terminator.bash
+++ b/clap_complete/tests/snapshots/value_terminator.bash
@@ -35,4 +35,8 @@ _my-app() {
     esac
 }
 
-complete -F _my-app -o nosort -o bashdefault -o default my-app
+if [[ "${BASH_VERSINFO[0]}" -eq 4 && "${BASH_VERSINFO[1]}" -ge 4 || "${BASH_VERSINFO[0]}" -gt 4 ]]; then
+    complete -F _my-app -o nosort -o bashdefault -o default my-app
+else
+    complete -F _my-app -o bashdefault -o default my-app
+fi