This is an automated email from the ASF dual-hosted git repository.
vincbeck pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git
The following commit(s) were added to refs/heads/main by this push:
new 31a461bddad Fix invalid command path in permissions-cleanup help
examples (#73028)
31a461bddad is described below
commit 31a461bddad4f0d29ee6650f07aca3facd07ed16
Author: Y-C <[email protected]>
AuthorDate: Mon Sep 14 22:08:28 2026 +0800
Fix invalid command path in permissions-cleanup help examples (#73028)
The examples printed by `airflow permissions-cleanup --help` told users to
run the command under a `fab-auth-manager` group that has never existed, so
copying any of them straight from the help output fails with exit code 2.
Anyone reaching for the help text is by definition the person who does not
already know the right invocation.
---
.../src/airflow/providers/fab/cli/definition.py | 8 +++----
.../fab/tests/unit/fab/cli/test_definition.py | 25 ++++++++++++++++++++++
2 files changed, 29 insertions(+), 4 deletions(-)
diff --git a/providers/fab/src/airflow/providers/fab/cli/definition.py
b/providers/fab/src/airflow/providers/fab/cli/definition.py
index 85e03757dae..4707cdefe7d 100644
--- a/providers/fab/src/airflow/providers/fab/cli/definition.py
+++ b/providers/fab/src/airflow/providers/fab/cli/definition.py
@@ -286,13 +286,13 @@ PERMISSIONS_CLEANUP_COMMAND = ActionCommand(
epilog=(
"examples:\n"
"To see what orphaned permissions would be cleaned up:\n"
- " $ airflow fab-auth-manager permissions-cleanup --dry-run\n"
+ " $ airflow permissions-cleanup --dry-run\n"
"To clean up all orphaned permissions:\n"
- " $ airflow fab-auth-manager permissions-cleanup\n"
+ " $ airflow permissions-cleanup\n"
"To clean up permissions for specific DAG:\n"
- " $ airflow fab-auth-manager permissions-cleanup --dag-id my_dag\n"
+ " $ airflow permissions-cleanup --dag-id my_dag\n"
"To clean up without confirmation:\n"
- " $ airflow fab-auth-manager permissions-cleanup --yes"
+ " $ airflow permissions-cleanup --yes"
),
)
diff --git a/providers/fab/tests/unit/fab/cli/test_definition.py
b/providers/fab/tests/unit/fab/cli/test_definition.py
index d6904683eab..4f60142c5a3 100644
--- a/providers/fab/tests/unit/fab/cli/test_definition.py
+++ b/providers/fab/tests/unit/fab/cli/test_definition.py
@@ -16,13 +16,31 @@
# under the License.
from __future__ import annotations
+import shlex
+
+import pytest
+
from airflow.providers.fab.cli.definition import (
+ PERMISSIONS_CLEANUP_COMMAND,
ROLES_COMMANDS,
SYNC_PERM_COMMAND,
USERS_COMMANDS,
+ get_parser,
)
+def _extract_epilog_examples(command):
+ examples = []
+ for line in (command.epilog or "").splitlines():
+ stripped = line.strip()
+ if stripped.startswith("$ airflow "):
+ examples.append(stripped.removeprefix("$ "))
+ if not examples:
+ # An empty parametrize set is silently skipped, which would hide the
loss of this guard.
+ raise ValueError(f"No '$ airflow ...' example found in the
{command.name} epilog")
+ return examples
+
+
class TestCliDefinition:
def test_users_commands(self):
assert len(USERS_COMMANDS) == 8
@@ -32,3 +50,10 @@ class TestCliDefinition:
def test_sync_perm_command(self):
assert SYNC_PERM_COMMAND.name == "sync-perm"
+
+ @pytest.mark.parametrize(
+ "example", _extract_epilog_examples(PERMISSIONS_CLEANUP_COMMAND),
ids=lambda e: e
+ )
+ def test_permissions_cleanup_epilog_examples_are_runnable(self, example):
+ args = get_parser().parse_args(shlex.split(example)[1:])
+ assert args.subcommand == PERMISSIONS_CLEANUP_COMMAND.name