cli: accept --json/-v/-q on every subcommand, not only top level
Before this change, only the top-level parser defined --json, -v and -q.
Argparse processes arguments left-to-right and hands off to the subparser
after seeing the subcommand name, so the idiomatic
metin-release release inspect --source X --json
failed with 'unrecognized arguments: --json'. Users had to write
metin-release --json release inspect --source X
which is the opposite of what every modern CLI does. Attach a shared
--json/-v/-q flag set to every subparser via a small helper. Same dest
means the last occurrence on the command line wins, which is the intuitive
behaviour. Both placements are now accepted; tests unchanged.
This commit is contained in:
@@ -26,15 +26,27 @@ from .workspace import Context
|
|||||||
CommandFn = Callable[[Context, argparse.Namespace], Result]
|
CommandFn = Callable[[Context, argparse.Namespace], Result]
|
||||||
|
|
||||||
|
|
||||||
|
def _add_common_flags(p: argparse.ArgumentParser) -> None:
|
||||||
|
"""Attach --json / -v / -q to a parser.
|
||||||
|
|
||||||
|
These flags are accepted both at the top level and on each subcommand so
|
||||||
|
that users can write either `metin-release --json release inspect ...` or
|
||||||
|
the more common `metin-release release inspect ... --json`. The shared
|
||||||
|
`dest` means whichever occurrence argparse sees last wins, which is the
|
||||||
|
intuitive "last flag on the command line" behaviour.
|
||||||
|
"""
|
||||||
|
p.add_argument("--json", action="store_true", help="Emit only JSON on stdout.")
|
||||||
|
p.add_argument("-v", "--verbose", action="store_true", help="Verbose stderr logging.")
|
||||||
|
p.add_argument("-q", "--quiet", action="store_true", help="Suppress stderr logging.")
|
||||||
|
|
||||||
|
|
||||||
def _build_parser() -> argparse.ArgumentParser:
|
def _build_parser() -> argparse.ArgumentParser:
|
||||||
parser = argparse.ArgumentParser(
|
parser = argparse.ArgumentParser(
|
||||||
prog="metin-release",
|
prog="metin-release",
|
||||||
description="Orchestration CLI for Metin2 client releases.",
|
description="Orchestration CLI for Metin2 client releases.",
|
||||||
)
|
)
|
||||||
parser.add_argument("--version", action="version", version=f"metin-release {__version__}")
|
parser.add_argument("--version", action="version", version=f"metin-release {__version__}")
|
||||||
parser.add_argument("--json", action="store_true", help="Emit only JSON on stdout.")
|
_add_common_flags(parser)
|
||||||
parser.add_argument("-v", "--verbose", action="store_true", help="Verbose stderr logging.")
|
|
||||||
parser.add_argument("-q", "--quiet", action="store_true", help="Suppress stderr logging.")
|
|
||||||
|
|
||||||
sub = parser.add_subparsers(dest="group", metavar="<group>")
|
sub = parser.add_subparsers(dest="group", metavar="<group>")
|
||||||
sub.required = True
|
sub.required = True
|
||||||
@@ -43,14 +55,18 @@ def _build_parser() -> argparse.ArgumentParser:
|
|||||||
rsub = release.add_subparsers(dest="cmd", metavar="<command>")
|
rsub = release.add_subparsers(dest="cmd", metavar="<command>")
|
||||||
rsub.required = True
|
rsub.required = True
|
||||||
|
|
||||||
inspect.add_parser(rsub)
|
for mod in (
|
||||||
build_manifest.add_parser(rsub)
|
inspect,
|
||||||
sign.add_parser(rsub)
|
build_manifest,
|
||||||
diff_remote.add_parser(rsub)
|
sign,
|
||||||
upload_blobs.add_parser(rsub)
|
diff_remote,
|
||||||
promote.add_parser(rsub)
|
upload_blobs,
|
||||||
verify_public.add_parser(rsub)
|
promote,
|
||||||
publish.add_parser(rsub)
|
verify_public,
|
||||||
|
publish,
|
||||||
|
):
|
||||||
|
sp = mod.add_parser(rsub)
|
||||||
|
_add_common_flags(sp)
|
||||||
|
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user