22# All rights reserved
33# Licensed under the Apache license (see LICENSE)
44import inspect
5+ from contextlib import contextmanager , ExitStack
56from typing import Iterator , List , cast
67
78import click
@@ -16,11 +17,18 @@ def make_command_docs(
1617 depth : int = 0 ,
1718 style : str = "plain" ,
1819 remove_ascii_art : bool = False ,
20+ show_hidden : bool = False ,
1921 has_attr_list : bool = False ,
2022) -> Iterator [str ]:
2123 """Create the Markdown lines for a command and its sub-commands."""
2224 for line in _recursively_make_command_docs (
23- prog_name , command , depth = depth , style = style , remove_ascii_art = remove_ascii_art , has_attr_list = has_attr_list
25+ prog_name ,
26+ command ,
27+ depth = depth ,
28+ style = style ,
29+ remove_ascii_art = remove_ascii_art ,
30+ show_hidden = show_hidden ,
31+ has_attr_list = has_attr_list ,
2432 ):
2533 if line .strip () == "\b " :
2634 continue
@@ -35,21 +43,31 @@ def _recursively_make_command_docs(
3543 depth : int = 0 ,
3644 style : str = "plain" ,
3745 remove_ascii_art : bool = False ,
46+ show_hidden : bool = False ,
3847 has_attr_list : bool = False ,
3948) -> Iterator [str ]:
4049 """Create the raw Markdown lines for a command and its sub-commands."""
4150 ctx = click .Context (cast (click .Command , command ), info_name = prog_name , parent = parent )
4251
52+ if ctx .command .hidden and not show_hidden :
53+ return
54+
4355 yield from _make_title (ctx , depth , has_attr_list = has_attr_list )
4456 yield from _make_description (ctx , remove_ascii_art = remove_ascii_art )
4557 yield from _make_usage (ctx )
46- yield from _make_options (ctx , style )
58+ yield from _make_options (ctx , style , show_hidden = show_hidden )
4759
4860 subcommands = _get_sub_commands (ctx .command , ctx )
4961
5062 for command in sorted (subcommands , key = lambda cmd : cmd .name ): # type: ignore
5163 yield from _recursively_make_command_docs (
52- cast (str , command .name ), command , parent = ctx , depth = depth + 1 , style = style , has_attr_list = has_attr_list
64+ cast (str , command .name ),
65+ command ,
66+ parent = ctx ,
67+ depth = depth + 1 ,
68+ style = style ,
69+ show_hidden = show_hidden ,
70+ has_attr_list = has_attr_list ,
5371 )
5472
5573
@@ -152,37 +170,55 @@ def _make_usage(ctx: click.Context) -> Iterator[str]:
152170 yield ""
153171
154172
155- def _make_options (ctx : click .Context , style : str = "plain" ) -> Iterator [str ]:
173+ def _make_options (ctx : click .Context , style : str = "plain" , show_hidden : bool = False ) -> Iterator [str ]:
156174 """Create the Markdown lines describing the options for the command."""
157175
158176 if style == "plain" :
159- return _make_plain_options (ctx )
177+ return _make_plain_options (ctx , show_hidden = show_hidden )
160178 elif style == "table" :
161- return _make_table_options (ctx )
179+ return _make_table_options (ctx , show_hidden = show_hidden )
162180 else :
163181 raise MkDocsClickException (f"{ style } is not a valid option style, which must be either `plain` or `table`." )
164182
165183
166- def _make_plain_options (ctx : click .Context ) -> Iterator [str ]:
184+ @contextmanager
185+ def _show_options (ctx : click .Context ) -> Iterator [None ]:
186+ """Context manager that temporarily shows all hidden options."""
187+ options = [opt for opt in ctx .command .get_params (ctx ) if isinstance (opt , click .Option ) and opt .hidden ]
188+
189+ try :
190+ for option in options :
191+ option .hidden = False
192+ yield
193+ finally :
194+ for option in options :
195+ option .hidden = True
196+
197+
198+ def _make_plain_options (ctx : click .Context , show_hidden : bool = False ) -> Iterator [str ]:
167199 """Create the plain style options description."""
168- formatter = ctx .make_formatter ()
169- click .Command .format_options (ctx .command , ctx , formatter )
200+ with ExitStack () as stack :
201+ if show_hidden :
202+ stack .enter_context (_show_options (ctx ))
170203
171- option_lines = formatter .getvalue ().splitlines ()
204+ formatter = ctx .make_formatter ()
205+ click .Command .format_options (ctx .command , ctx , formatter )
172206
173- # First line is redundant "Options"
174- option_lines = option_lines [1 :]
207+ option_lines = formatter .getvalue ().splitlines ()
175208
176- if not option_lines : # pragma: no cover
177- # We expect at least `--help` to be present.
178- raise RuntimeError ("Expected at least one option" )
209+ # First line is redundant "Options"
210+ option_lines = option_lines [1 :]
179211
180- yield "**Options:**"
181- yield ""
182- yield "```"
183- yield from option_lines
184- yield "```"
185- yield ""
212+ if not option_lines : # pragma: no cover
213+ # We expect at least `--help` to be present.
214+ raise RuntimeError ("Expected at least one option" )
215+
216+ yield "**Options:**"
217+ yield ""
218+ yield "```"
219+ yield from option_lines
220+ yield "```"
221+ yield ""
186222
187223
188224# Unicode "Vertical Line" character (U+007C), HTML-compatible.
@@ -251,10 +287,11 @@ def _format_table_option_row(option: click.Option) -> str:
251287 return f"| { names } | { value_type } | { description } | { default } |"
252288
253289
254- def _make_table_options (ctx : click .Context ) -> Iterator [str ]:
290+ def _make_table_options (ctx : click .Context , show_hidden : bool = False ) -> Iterator [str ]:
255291 """Create the table style options description."""
256292
257293 options = [param for param in ctx .command .get_params (ctx ) if isinstance (param , click .Option )]
294+ options = [option for option in options if not option .hidden or show_hidden ]
258295 option_rows = [_format_table_option_row (option ) for option in options ]
259296
260297 yield "**Options:**"
0 commit comments