Repository: pallets/click (python)

Issue:
show envvar in error hint
```py
@click.command()
@click.option('--a', required=True, envvar="b", show_envvar=True)
def f(a): ...
f()
```
Here I would want the error message to show the env var.

Pull request:
show env var in error hint
Here we add the env var to the error hint.

<!--
Link to relevant issues or previous PRs, one per line. Use "fixes" to
automatically close an issue.
-->

- fixes #2695

<!--
Ensure each step in CONTRIBUTING.rst is complete by adding an "x" to
each box below.

If only docs were changed, these aren't relevant and can be removed.
-->

Checklist:

- [x] Add tests that demonstrate the correct behavior of the change. Tests should fail without the change.
- [x] Add or update relevant docs, in the docs folder and in code.
- [x] Add an entry in `CHANGES.rst` summarizing the change and linking to the issue.
- [x] Add `.. versionchanged::` entries in any relevant code docs.
- [x] Run `pre-commit` hooks and fix any issues.
- [x] Run `pytest` and `tox`, no tests failed.


Patch:
diff --git a/CHANGES.rst b/CHANGES.rst
index f3997a5..086ccf4 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -43,6 +43,8 @@ Unreleased
     collect stderr output and never raise an exception. Add a new
     output` stream to simulate what the user sees in its terminal. Removes
     the ``mix_stderr`` parameter in ``CliRunner``. :issue:`2522` :pr:`2523`
+-   If ``show_envvar`` then show env var in error messages.
+    :issue:`2695`
 
 
 Version 8.1.8
diff --git a/src/click/core.py b/src/click/core.py
index 9b1a846..f17a8a8 100644
--- a/src/click/core.py
+++ b/src/click/core.py
@@ -2372,8 +2372,8 @@ class Option(Parameter):
         For single option boolean flags, the default remains hidden if
         its value is ``False``.
     :param show_envvar: Controls if an environment variable should be
-        shown on the help page. Normally, environment variables are not
-        shown.
+        shown on the help page and error messages.
+        Normally, environment variables are not shown.
     :param prompt: If set to ``True`` or a non empty string then the
         user will be prompted for input. If set to ``True`` the prompt
         will be the option name capitalized.
@@ -2551,6 +2551,12 @@ class Option(Parameter):
         )
         return info_dict
 
+    def get_error_hint(self, ctx: Context) -> str:
+        result = super().get_error_hint(ctx)
+        if self.show_envvar:
+            result += f" (env var: '{self.envvar}')"
+        return result
+
     def _parse_decls(
         self, decls: cabc.Sequence[str], expose_value: bool
     ) -> tuple[str | None, list[str], list[str]]:


Test patch:
diff --git a/tests/test_options.py b/tests/test_options.py
index 293f253..74ccc5f 100644
--- a/tests/test_options.py
+++ b/tests/test_options.py
@@ -531,6 +531,22 @@ def test_missing_choice(runner):
     assert "bar" in choices
 
 
+def test_missing_envvar(runner):
+    cli = click.Command(
+        "cli", params=[click.Option(["--foo"], envvar="bar", required=True)]
+    )
+    result = runner.invoke(cli)
+    assert result.exit_code == 2
+    assert "Error: Missing option '--foo'." in result.output
+    cli = click.Command(
+        "cli",
+        params=[click.Option(["--foo"], envvar="bar", show_envvar=True, required=True)],
+    )
+    result = runner.invoke(cli)
+    assert result.exit_code == 2
+    assert "Error: Missing option '--foo' (env var: 'bar')." in result.output
+
+
 def test_case_insensitive_choice(runner):
     @click.command()
     @click.option("--foo", type=click.Choice(["Orange", "Apple"], case_sensitive=False))