@ -32,7 +32,6 @@ from ansible.errors import AnsibleError, AnsibleOptionsError, AnsibleParserError
from ansible . module_utils . common . text . converters import to_native , to_text
from ansible . module_utils . common . collections import is_sequence
from ansible . module_utils . common . yaml import yaml_dump
from ansible . module_utils . six import string_types
from ansible . parsing . plugin_docs import read_docstub
from ansible . parsing . yaml . dumper import AnsibleDumper
from ansible . parsing . yaml . loader import AnsibleLoader
@ -1274,7 +1273,7 @@ class DocCLI(CLI, RoleMixin):
sub_indent = inline_indent + extra_indent
if is_sequence ( opt [ ' description ' ] ) :
for entry_idx , entry in enumerate ( opt [ ' description ' ] , 1 ) :
if not isinstance ( entry , string_types ) :
if not isinstance ( entry , str ) :
raise AnsibleError ( " Expected string in description of %s at index %s , got %s " % ( o , entry_idx , type ( entry ) ) )
if entry_idx == 1 :
text . append ( key + DocCLI . warp_fill ( DocCLI . tty_ify ( entry ) , limit ,
@ -1282,7 +1281,7 @@ class DocCLI(CLI, RoleMixin):
else :
text . append ( DocCLI . warp_fill ( DocCLI . tty_ify ( entry ) , limit , initial_indent = sub_indent , subsequent_indent = sub_indent ) )
else :
if not isinstance ( opt [ ' description ' ] , string_types ) :
if not isinstance ( opt [ ' description ' ] , str ) :
raise AnsibleError ( " Expected string in description of %s , got %s " % ( o , type ( opt [ ' description ' ] ) ) )
text . append ( key + DocCLI . warp_fill ( DocCLI . tty_ify ( opt [ ' description ' ] ) , limit ,
initial_indent = inline_indent , subsequent_indent = sub_indent , initial_extra = len ( extra_indent ) ) )
@ -1344,6 +1343,51 @@ class DocCLI(CLI, RoleMixin):
text . append ( " %s %s : " % ( opt_indent , subkey ) )
DocCLI . add_fields ( text , subdata , limit , opt_indent + ' ' , return_values , opt_indent )
@staticmethod
def _add_seealso ( text : list [ str ] , seealsos : list [ dict [ str , t . Any ] ] , limit : int , opt_indent : str ) - > None :
for item in seealsos :
if ' module ' in item :
text . append ( DocCLI . warp_fill ( DocCLI . tty_ify ( ' Module %s ' % item [ ' module ' ] ) ,
limit - 6 , initial_indent = opt_indent [ : - 2 ] + " * " , subsequent_indent = opt_indent ) )
description = item . get ( ' description ' )
if description is None and item [ ' module ' ] . startswith ( ' ansible.builtin. ' ) :
description = ' The official documentation on the %s module. ' % item [ ' module ' ]
if description is not None :
text . append ( DocCLI . warp_fill ( DocCLI . tty_ify ( description ) ,
limit - 6 , initial_indent = opt_indent + ' ' , subsequent_indent = opt_indent + ' ' ) )
if item [ ' module ' ] . startswith ( ' ansible.builtin. ' ) :
relative_url = ' collections/ %s _module.html ' % item [ ' module ' ] . replace ( ' . ' , ' / ' , 2 )
text . append ( DocCLI . warp_fill ( DocCLI . tty_ify ( get_versioned_doclink ( relative_url ) ) ,
limit - 6 , initial_indent = opt_indent + ' ' , subsequent_indent = opt_indent ) )
elif ' plugin ' in item and ' plugin_type ' in item :
plugin_suffix = ' plugin ' if item [ ' plugin_type ' ] not in ( ' module ' , ' role ' ) else ' '
text . append ( DocCLI . warp_fill ( DocCLI . tty_ify ( ' %s %s %s ' % ( item [ ' plugin_type ' ] . title ( ) , plugin_suffix , item [ ' plugin ' ] ) ) ,
limit - 6 , initial_indent = opt_indent [ : - 2 ] + " * " , subsequent_indent = opt_indent ) )
description = item . get ( ' description ' )
if description is None and item [ ' plugin ' ] . startswith ( ' ansible.builtin. ' ) :
description = ' The official documentation on the %s %s %s . ' % ( item [ ' plugin ' ] , item [ ' plugin_type ' ] , plugin_suffix )
if description is not None :
text . append ( DocCLI . warp_fill ( DocCLI . tty_ify ( description ) ,
limit - 6 , initial_indent = opt_indent + ' ' , subsequent_indent = opt_indent + ' ' ) )
if item [ ' plugin ' ] . startswith ( ' ansible.builtin. ' ) :
relative_url = ' collections/ %s _ %s .html ' % ( item [ ' plugin ' ] . replace ( ' . ' , ' / ' , 2 ) , item [ ' plugin_type ' ] )
text . append ( DocCLI . warp_fill ( DocCLI . tty_ify ( get_versioned_doclink ( relative_url ) ) ,
limit - 6 , initial_indent = opt_indent + ' ' , subsequent_indent = opt_indent ) )
elif ' name ' in item and ' link ' in item and ' description ' in item :
text . append ( DocCLI . warp_fill ( DocCLI . tty_ify ( item [ ' name ' ] ) ,
limit - 6 , initial_indent = opt_indent [ : - 2 ] + " * " , subsequent_indent = opt_indent ) )
text . append ( DocCLI . warp_fill ( DocCLI . tty_ify ( item [ ' description ' ] ) ,
limit - 6 , initial_indent = opt_indent + ' ' , subsequent_indent = opt_indent + ' ' ) )
text . append ( DocCLI . warp_fill ( DocCLI . tty_ify ( item [ ' link ' ] ) ,
limit - 6 , initial_indent = opt_indent + ' ' , subsequent_indent = opt_indent + ' ' ) )
elif ' ref ' in item and ' description ' in item :
text . append ( DocCLI . warp_fill ( DocCLI . tty_ify ( ' Ansible documentation [ %s ] ' % item [ ' ref ' ] ) ,
limit - 6 , initial_indent = opt_indent [ : - 2 ] + " * " , subsequent_indent = opt_indent ) )
text . append ( DocCLI . warp_fill ( DocCLI . tty_ify ( item [ ' description ' ] ) ,
limit - 6 , initial_indent = opt_indent + ' ' , subsequent_indent = opt_indent + ' ' ) )
text . append ( DocCLI . warp_fill ( DocCLI . tty_ify ( get_versioned_doclink ( ' /#stq= %s &stp=1 ' % item [ ' ref ' ] ) ) ,
limit - 6 , initial_indent = opt_indent + ' ' , subsequent_indent = opt_indent + ' ' ) )
def get_role_man_text ( self , role , role_json ) :
""" Generate text for the supplied role suitable for display.
@ -1371,6 +1415,9 @@ class DocCLI(CLI, RoleMixin):
text . append ( " ENTRY POINT: %s %s " % ( _format ( entry_point , " BOLD " ) , desc ) )
text . append ( ' ' )
if version_added := doc . pop ( ' version_added ' , None ) :
text . append ( _format ( " ADDED IN: " , ' bold ' ) + " %s \n " % DocCLI . _format_version_added ( version_added ) )
if doc . get ( ' description ' ) :
if isinstance ( doc [ ' description ' ] , list ) :
descs = doc [ ' description ' ]
@ -1384,29 +1431,24 @@ class DocCLI(CLI, RoleMixin):
text . append ( _format ( " Options " , ' bold ' ) + " ( %s indicates it is required): " % ( " = " if C . ANSIBLE_NOCOLOR else ' red ' ) )
DocCLI . add_fields ( text , doc . pop ( ' options ' ) , limit , opt_indent )
if doc . get ( ' attributes ' , False ) :
display . deprecated (
f ' The role { role } \' s argument spec { entry_point } contains the key " attributes " , '
' which will not be displayed by ansible-doc in the future. '
' This was unintentionally allowed when plugin attributes were added, '
' but the feature does not map well to role argument specs. ' ,
version = ' 2.20 ' ,
)
if notes := doc . pop ( ' notes ' , False ) :
text . append ( " " )
text . append ( _format ( " ATTRIBUTES: " , ' bold ' ) )
for k in doc [ ' attributes ' ] . keys ( ) :
text . append ( ' ' )
text . append ( DocCLI . warp_fill ( DocCLI . tty_ify ( _format ( ' %s : ' % k , ' UNDERLINE ' ) ) , limit - 6 , initial_indent = opt_indent ,
subsequent_indent = opt_indent ) )
text . append ( DocCLI . _indent_lines ( DocCLI . _dump_yaml ( doc [ ' attributes ' ] [ k ] ) , opt_indent ) )
del doc [ ' attributes ' ]
text . append ( _format ( " NOTES: " , ' bold ' ) )
for note in notes :
text . append ( DocCLI . warp_fill ( DocCLI . tty_ify ( note ) , limit - 6 ,
initial_indent = opt_indent [ : - 2 ] + " * " , subsequent_indent = opt_indent ) )
if seealso := doc . pop ( ' seealso ' , False ) :
text . append ( " " )
text . append ( _format ( " SEE ALSO: " , ' bold ' ) )
DocCLI . _add_seealso ( text , seealso , limit = limit , opt_indent = opt_indent )
# generic elements we will handle identically
for k in ( ' author ' , ) :
if k not in doc :
continue
text . append ( ' ' )
if isinstance ( doc [ k ] , string_types ) :
if isinstance ( doc [ k ] , str ) :
text . append ( ' %s : %s ' % ( k . upper ( ) , DocCLI . warp_fill ( DocCLI . tty_ify ( doc [ k ] ) ,
limit - ( len ( k ) + 2 ) , subsequent_indent = opt_indent ) ) )
elif isinstance ( doc [ k ] , ( list , tuple ) ) :
@ -1418,7 +1460,7 @@ class DocCLI(CLI, RoleMixin):
if doc . get ( ' examples ' , False ) :
text . append ( ' ' )
text . append ( _format ( " EXAMPLES: " , ' bold ' ) )
if isinstance ( doc [ ' examples ' ] , string_types ) :
if isinstance ( doc [ ' examples ' ] , str ) :
text . append ( doc . pop ( ' examples ' ) . strip ( ) )
else :
try :
@ -1497,49 +1539,7 @@ class DocCLI(CLI, RoleMixin):
if doc . get ( ' seealso ' , False ) :
text . append ( " " )
text . append ( _format ( " SEE ALSO: " , ' bold ' ) )
for item in doc [ ' seealso ' ] :
if ' module ' in item :
text . append ( DocCLI . warp_fill ( DocCLI . tty_ify ( ' Module %s ' % item [ ' module ' ] ) ,
limit - 6 , initial_indent = opt_indent [ : - 2 ] + " * " , subsequent_indent = opt_indent ) )
description = item . get ( ' description ' )
if description is None and item [ ' module ' ] . startswith ( ' ansible.builtin. ' ) :
description = ' The official documentation on the %s module. ' % item [ ' module ' ]
if description is not None :
text . append ( DocCLI . warp_fill ( DocCLI . tty_ify ( description ) ,
limit - 6 , initial_indent = opt_indent + ' ' , subsequent_indent = opt_indent + ' ' ) )
if item [ ' module ' ] . startswith ( ' ansible.builtin. ' ) :
relative_url = ' collections/ %s _module.html ' % item [ ' module ' ] . replace ( ' . ' , ' / ' , 2 )
text . append ( DocCLI . warp_fill ( DocCLI . tty_ify ( get_versioned_doclink ( relative_url ) ) ,
limit - 6 , initial_indent = opt_indent + ' ' , subsequent_indent = opt_indent ) )
elif ' plugin ' in item and ' plugin_type ' in item :
plugin_suffix = ' plugin ' if item [ ' plugin_type ' ] not in ( ' module ' , ' role ' ) else ' '
text . append ( DocCLI . warp_fill ( DocCLI . tty_ify ( ' %s %s %s ' % ( item [ ' plugin_type ' ] . title ( ) , plugin_suffix , item [ ' plugin ' ] ) ) ,
limit - 6 , initial_indent = opt_indent [ : - 2 ] + " * " , subsequent_indent = opt_indent ) )
description = item . get ( ' description ' )
if description is None and item [ ' plugin ' ] . startswith ( ' ansible.builtin. ' ) :
description = ' The official documentation on the %s %s %s . ' % ( item [ ' plugin ' ] , item [ ' plugin_type ' ] , plugin_suffix )
if description is not None :
text . append ( DocCLI . warp_fill ( DocCLI . tty_ify ( description ) ,
limit - 6 , initial_indent = opt_indent + ' ' , subsequent_indent = opt_indent + ' ' ) )
if item [ ' plugin ' ] . startswith ( ' ansible.builtin. ' ) :
relative_url = ' collections/ %s _ %s .html ' % ( item [ ' plugin ' ] . replace ( ' . ' , ' / ' , 2 ) , item [ ' plugin_type ' ] )
text . append ( DocCLI . warp_fill ( DocCLI . tty_ify ( get_versioned_doclink ( relative_url ) ) ,
limit - 6 , initial_indent = opt_indent + ' ' , subsequent_indent = opt_indent ) )
elif ' name ' in item and ' link ' in item and ' description ' in item :
text . append ( DocCLI . warp_fill ( DocCLI . tty_ify ( item [ ' name ' ] ) ,
limit - 6 , initial_indent = opt_indent [ : - 2 ] + " * " , subsequent_indent = opt_indent ) )
text . append ( DocCLI . warp_fill ( DocCLI . tty_ify ( item [ ' description ' ] ) ,
limit - 6 , initial_indent = opt_indent + ' ' , subsequent_indent = opt_indent + ' ' ) )
text . append ( DocCLI . warp_fill ( DocCLI . tty_ify ( item [ ' link ' ] ) ,
limit - 6 , initial_indent = opt_indent + ' ' , subsequent_indent = opt_indent + ' ' ) )
elif ' ref ' in item and ' description ' in item :
text . append ( DocCLI . warp_fill ( DocCLI . tty_ify ( ' Ansible documentation [ %s ] ' % item [ ' ref ' ] ) ,
limit - 6 , initial_indent = opt_indent [ : - 2 ] + " * " , subsequent_indent = opt_indent ) )
text . append ( DocCLI . warp_fill ( DocCLI . tty_ify ( item [ ' description ' ] ) ,
limit - 6 , initial_indent = opt_indent + ' ' , subsequent_indent = opt_indent + ' ' ) )
text . append ( DocCLI . warp_fill ( DocCLI . tty_ify ( get_versioned_doclink ( ' /#stq= %s &stp=1 ' % item [ ' ref ' ] ) ) ,
limit - 6 , initial_indent = opt_indent + ' ' , subsequent_indent = opt_indent + ' ' ) )
DocCLI . _add_seealso ( text , doc [ ' seealso ' ] , limit = limit , opt_indent = opt_indent )
del doc [ ' seealso ' ]
if doc . get ( ' requirements ' , False ) :
@ -1554,7 +1554,7 @@ class DocCLI(CLI, RoleMixin):
continue
text . append ( ' ' )
header = _format ( k . upper ( ) , ' bold ' )
if isinstance ( doc [ k ] , string_types ) :
if isinstance ( doc [ k ] , str ) :
text . append ( ' %s : %s ' % ( header , DocCLI . warp_fill ( DocCLI . tty_ify ( doc [ k ] ) , limit - ( len ( k ) + 2 ) , subsequent_indent = opt_indent ) ) )
elif isinstance ( doc [ k ] , ( list , tuple ) ) :
text . append ( ' %s : %s ' % ( header , ' , ' . join ( doc [ k ] ) ) )
@ -1566,7 +1566,7 @@ class DocCLI(CLI, RoleMixin):
if doc . get ( ' plainexamples ' , False ) :
text . append ( ' ' )
text . append ( _format ( " EXAMPLES: " , ' bold ' ) )
if isinstance ( doc [ ' plainexamples ' ] , string_types ) :
if isinstance ( doc [ ' plainexamples ' ] , str ) :
text . append ( doc . pop ( ' plainexamples ' ) . strip ( ) )
else :
try :
@ -1603,7 +1603,7 @@ def _do_yaml_snippet(doc):
for o in sorted ( doc [ ' options ' ] . keys ( ) ) :
opt = doc [ ' options ' ] [ o ]
if isinstance ( opt [ ' description ' ] , string_types ) :
if isinstance ( opt [ ' description ' ] , str ) :
desc = DocCLI . tty_ify ( opt [ ' description ' ] )
else :
desc = DocCLI . tty_ify ( " " . join ( opt [ ' description ' ] ) )