1010import shutil
1111import sys
1212import tempfile
13+
1314from argparse import ArgumentParser
1415from functools import partial
1516from pathlib import Path
1617from typing import Optional
1718
1819import yaml
20+
1921from ansible .module_utils ._text import to_text
2022from ansible .module_utils .common .collections import is_sequence
2123from ansible .module_utils .six import string_types
2224from ansible .plugins .loader import fragment_loader
2325from ansible .utils import plugin_docs
24- from ansible .utils .collection_loader ._collection_finder import (
25- _AnsibleCollectionFinder ,
26- )
27- from jinja2 import Environment , FileSystemLoader
28-
29- from collection_prep .jinja_utils import (
30- documented_type ,
31- from_kludge_ns ,
32- html_ify ,
33- rst_ify ,
34- to_kludge_ns ,
35- )
26+ from ansible .utils .collection_loader ._collection_finder import _AnsibleCollectionFinder
27+ from jinja2 import Environment
28+ from jinja2 import FileSystemLoader
29+
30+ from collection_prep .jinja_utils import documented_type
31+ from collection_prep .jinja_utils import from_kludge_ns
32+ from collection_prep .jinja_utils import html_ify
33+ from collection_prep .jinja_utils import rst_ify
34+ from collection_prep .jinja_utils import to_kludge_ns
35+
3636
3737try :
3838 import argcomplete
@@ -91,9 +91,7 @@ def convert_descriptions(data):
9191 if data :
9292 for definition in data .values ():
9393 if "description" in definition :
94- definition ["description" ] = ensure_list (
95- definition ["description" ]
96- )
94+ definition ["description" ] = ensure_list (definition ["description" ])
9795 if "suboptions" in definition :
9896 convert_descriptions (definition ["suboptions" ])
9997 if "contains" in definition :
@@ -137,30 +135,27 @@ def update_readme(content, path, gh_url, branch_name):
137135 :type branch_name: str
138136 """
139137 data = []
138+ gh_url = re .sub (r"\.git$" , "" , gh_url )
140139 for plugin_type , plugins in content .items ():
141140 logging .info ("Processing '%s' for README" , plugin_type )
142141 if not plugins :
143142 continue
144143 if plugin_type == "modules" :
145144 data .append ("### Modules" )
146145 else :
147- data .append (
148- "### {plugin_type} plugins" .format (
149- plugin_type = plugin_type .capitalize ()
150- )
151- )
146+ data .append (f"### { plugin_type .capitalize ()} plugins" )
152147 if "_description" in plugins :
153148 data .append (plugins .pop ("_description" ))
154149 data .append ("" )
155150 data .append ("Name | Description" )
156151 data .append ("--- | ---" )
157152 for plugin , info in sorted (plugins .items ()):
158153 if info ["has_rst" ]:
159- link = "[{plugin}]({gh_url}/blob/{branch_name}/docs/{plugin}_{plugin_type}.rst)" . format (
160- branch_name = branch_name ,
161- gh_url = re . sub ( r"\.git$" , "" , gh_url ),
162- plugin = plugin ,
163- plugin_type = plugin_type . replace ( "modules" , "module" ),
154+ link = (
155+ f"[ { plugin } ]( { gh_url } /blob/ { branch_name } /docs/ { plugin } _"
156+ "{plugin_type}.rst)" . format (
157+ plugin_type = plugin_type . replace ( "modules" , "module" ) ,
158+ )
164159 )
165160 else :
166161 link = plugin
@@ -232,9 +227,7 @@ def handle_simple(collection, fullpath, kind):
232227 if isinstance (node , ast .FunctionDef )
233228 }
234229 classdef = [
235- node
236- for node in module .body
237- if isinstance (node , ast .ClassDef ) and node .name == class_name
230+ node for node in module .body if isinstance (node , ast .ClassDef ) and node .name == class_name
238231 ]
239232 if not classdef :
240233 return plugins
@@ -263,13 +256,13 @@ def handle_simple(collection, fullpath, kind):
263256 if not simple_func :
264257 return plugins
265258
266- # The filter map is either looked up using the filter_map = {} assignment or if return returns a dict literal.
259+ # The filter map is either looked up using the filter_map = {}
260+ # assignment or if return returns a dict literal.
267261 simple_map = next (
268262 (
269263 node
270264 for node in simple_func [0 ].body
271- if isinstance (node , ast .Return )
272- and isinstance (node .value , ast .Dict )
265+ if isinstance (node , ast .Return ) and isinstance (node .value , ast .Dict )
273266 ),
274267 None ,
275268 )
@@ -283,25 +276,18 @@ def handle_simple(collection, fullpath, kind):
283276 simple_map = dict (zip (keys , values ))
284277 for name , func in simple_map .items ():
285278 if func in function_definitions :
286- comment = function_definitions [
287- func
288- ] or "{collection} {name} {kind} plugin" .format (
279+ comment = function_definitions [func ] or "{collection} {name} {kind} plugin" .format (
289280 collection = collection , name = name , kind = kind
290281 )
291282
292- # Get the first line from the docstring for the description and make that the short description.
293- comment = next (
294- c for c in comment .splitlines () if c and not c .startswith (":" )
295- )
296- plugins [
297- "{collection}.{name}" .format (collection = collection , name = name )
298- ] = {"has_rst" : False , "comment" : comment }
283+ # Get the first line from the docstring for the description and
284+ # make that the short description.
285+ comment = next (c for c in comment .splitlines () if c and not c .startswith (":" ))
286+ plugins [f"{ collection } .{ name } " ] = {"has_rst" : False , "comment" : comment }
299287 return plugins
300288
301289
302- def process (
303- collection : str , path : Path
304- ): # pylint: disable-msg=too-many-locals
290+ def process (collection : str , path : Path ): # pylint: disable-msg=too-many-locals
305291 """
306292 Process the files in each subdirectory
307293
@@ -340,27 +326,22 @@ def process(
340326 examples ,
341327 returndocs ,
342328 metadata ,
343- ) = plugin_docs .get_docstring (
344- to_text (fullpath ), fragment_loader
345- )
329+ ) = plugin_docs .get_docstring (to_text (fullpath ), fragment_loader )
346330 if doc is None and subdir in ["filter" , "test" ]:
347331 name_only = filename .rsplit ("." )[0 ]
348- combined_ptype = "%s %s" % (name_only , subdir )
349- content [combined_ptype ] = handle_simple (
350- collection , fullpath , subdir
351- )
332+ combined_ptype = f"{ name_only } { subdir } "
333+ content [combined_ptype ] = handle_simple (collection , fullpath , subdir )
352334 else :
353335 if doc :
354336 doc ["plugin_type" ] = plugin_type
355337
356338 if returndocs :
357- # Seems a recent change in devel makes this return a dict not a yaml string.
339+ # Seems a recent change in devel makes this
340+ # return a dict not a yaml string.
358341 if isinstance (returndocs , dict ):
359342 doc ["returndocs" ] = returndocs
360343 else :
361- doc ["returndocs" ] = yaml .safe_load (
362- returndocs
363- )
344+ doc ["returndocs" ] = yaml .safe_load (returndocs )
364345 convert_descriptions (doc ["returndocs" ])
365346
366347 doc ["metadata" ] = (metadata ,)
@@ -369,18 +350,12 @@ def process(
369350 else :
370351 doc ["examples" ] = examples
371352
372- doc [
373- "module"
374- ] = "{collection}.{plugin_name}" .format (
353+ doc ["module" ] = "{collection}.{plugin_name}" .format (
375354 collection = collection ,
376- plugin_name = doc .get (
377- plugin_type , doc .get ("name" )
378- ),
355+ plugin_name = doc .get (plugin_type , doc .get ("name" )),
379356 )
380357 doc ["author" ] = ensure_list (doc ["author" ])
381- doc ["description" ] = ensure_list (
382- doc ["description" ]
383- )
358+ doc ["description" ] = ensure_list (doc ["description" ])
384359 try :
385360 convert_descriptions (doc ["options" ])
386361 except KeyError :
@@ -389,9 +364,7 @@ def process(
389364 module_rst_path = Path (
390365 path ,
391366 "docs" ,
392- doc ["module" ]
393- + "_{0}" .format (plugin_type )
394- + ".rst" ,
367+ doc ["module" ] + f"_{ plugin_type } " + ".rst" ,
395368 )
396369
397370 with open (module_rst_path , "w" ) as fd :
@@ -410,10 +383,10 @@ def load_galaxy(path):
410383 :return: The collection name and gh url
411384 """
412385 try :
413- with open (Path (path , "galaxy.yml" ), "r" ) as stream :
386+ with open (Path (path , "galaxy.yml" )) as stream :
414387 try :
415388 return yaml .safe_load (stream )
416- except yaml .YAMLError as _exc :
389+ except yaml .YAMLError :
417390 logging .error ("Unable to parse galaxy.yml in %s" , path )
418391 sys .exit (1 )
419392 except FileNotFoundError :
@@ -428,20 +401,18 @@ def load_runtime(path):
428401 :return: The runtime dict
429402 """
430403 try :
431- with open (Path (path , "meta/runtime.yml" ), "r" ) as stream :
404+ with open (Path (path , "meta/runtime.yml" )) as stream :
432405 try :
433406 return yaml .safe_load (stream )
434- except yaml .YAMLError as _exc :
407+ except yaml .YAMLError :
435408 logging .error ("Unable to parse runtime.yml in %s" , path )
436409 sys .exit (1 )
437410 except FileNotFoundError :
438411 logging .error ("Unable to find runtime.yml in %s" , path )
439412 sys .exit (1 )
440413
441414
442- def link_collection (
443- path : Path , galaxy : dict , collection_root : Optional [Path ] = None
444- ):
415+ def link_collection (path : Path , galaxy : dict , collection_root : Optional [Path ] = None ):
445416 """Link the provided collection into the Ansible default collection path
446417
447418 :param path: A path
@@ -451,17 +422,13 @@ def link_collection(
451422 """
452423
453424 if collection_root is None :
454- collection_root = Path (
455- Path .home (), ".ansible/collections/ansible_collections"
456- )
425+ collection_root = Path (Path .home (), ".ansible/collections/ansible_collections" )
457426
458427 namespace_directory = Path (collection_root , galaxy ["namespace" ])
459428 collection_directory = Path (namespace_directory , galaxy ["name" ])
460429
461430 logging .info ("Linking collection to collection path %s" , collection_root )
462- logging .info (
463- "This is required for the Ansible fragment loader to find doc fragments"
464- )
431+ logging .info ("This is required for the Ansible fragment loader to find doc fragments" )
465432
466433 if collection_directory .exists ():
467434 logging .info ("Attempting to remove existing %s" , collection_directory )
@@ -480,9 +447,7 @@ def link_collection(
480447 collection_directory .symlink_to (path )
481448
482449
483- def add_collection (
484- path : Path , galaxy : dict
485- ) -> Optional [tempfile .TemporaryDirectory ]:
450+ def add_collection (path : Path , galaxy : dict ) -> Optional [tempfile .TemporaryDirectory ]:
486451 """Add path to collections dir so we can find local doc_fragments"""
487452 collections_path = None
488453 tempdir = None
@@ -494,9 +459,7 @@ def add_collection(
494459
495460 # Check that parent dir is named ansible_collections
496461 if collections_path and collections_path .name != "ansible_collections" :
497- logging .info (
498- "%s doesn't look enough like a collection" , collections_path
499- )
462+ logging .info ("%s doesn't look enough like a collection" , collections_path )
500463 collections_path = None
501464
502465 if collections_path is None :
@@ -509,9 +472,7 @@ def add_collection(
509472 logging .info ("Collection path is %s" , full_path )
510473
511474 # Tell ansible about the path
512- _AnsibleCollectionFinder (
513- paths = [collections_path , "~/.ansible/collections" ]
514- )._install ()
475+ _AnsibleCollectionFinder (paths = [collections_path , "~/.ansible/collections" ])._install ()
515476
516477 # This object has to outlive this method or it will be cleaned up before
517478 # we can use it
@@ -528,9 +489,7 @@ def add_ansible_compatibility(runtime, path):
528489 """
529490 requires_ansible = runtime .get ("requires_ansible" )
530491 if not requires_ansible :
531- logging .error (
532- "Unable to find requires_ansible in runtime.yml, not added to README"
533- )
492+ logging .error ("Unable to find requires_ansible in runtime.yml, not added to README" )
534493 return
535494 readme = os .path .join (path , "README.md" )
536495 try :
@@ -543,22 +502,16 @@ def add_ansible_compatibility(runtime, path):
543502 try :
544503 start = content .index ("<!--start requires_ansible-->" )
545504 end = content .index ("<!--end requires_ansible-->" )
546- except ValueError as _err :
505+ except ValueError :
547506 logging .error ("requires_ansible anchors not found in %s" , readme )
548- logging .error (
549- "README.md not updated with ansible compatibility information"
550- )
507+ logging .error ("README.md not updated with ansible compatibility information" )
551508 sys .exit (1 )
552509 if start and end :
553- data = ANSIBLE_COMPAT .format (
554- requires_ansible = requires_ansible
555- ).splitlines ()
510+ data = ANSIBLE_COMPAT .format (requires_ansible = requires_ansible ).splitlines ()
556511 new = content [0 : start + 1 ] + data + content [end :]
557512 with open (readme , "w" ) as fhand :
558513 fhand .write ("\n " .join (new ))
559- logging .info (
560- "README.md updated with ansible compatibility information"
561- )
514+ logging .info ("README.md updated with ansible compatibility information" )
562515
563516
564517def main ():
@@ -592,9 +545,7 @@ def main():
592545 args = parser .parse_args ()
593546 path = Path (args .path ).absolute ()
594547 galaxy = load_galaxy (path = path )
595- collection = "{namespace}.{name}" .format (
596- namespace = galaxy ["namespace" ], name = galaxy ["name" ]
597- )
548+ collection = "{namespace}.{name}" .format (namespace = galaxy ["namespace" ], name = galaxy ["name" ])
598549 logging .info ("Setting collection name to %s" , collection )
599550 gh_url = galaxy ["repository" ]
600551 logging .info ("Setting GitHub repository url to %s" , gh_url )
0 commit comments