platypush/generate_missing_docs.py

150 lines
3.5 KiB
Python

import os
from typing import Iterable, Optional
from platypush.backend import Backend
from platypush.context import get_plugin
from platypush.plugins import Plugin
from platypush.utils.manifest import get_manifests
def _get_inspect_plugin():
p = get_plugin('inspect')
assert p, 'Could not load the `inspect` plugin'
return p
def get_all_plugins():
return sorted([mf.component_name for mf in get_manifests(Plugin)])
def get_all_backends():
return sorted([mf.component_name for mf in get_manifests(Backend)])
def get_all_events():
return _get_inspect_plugin().get_all_events().output
def get_all_responses():
return _get_inspect_plugin().get_all_responses().output
def _generate_components_doc(
index_name: str,
package_name: str,
components: Iterable[str],
doc_dir: Optional[str] = None,
):
if not doc_dir:
doc_dir = index_name
index_file = os.path.join(
os.path.dirname(os.path.abspath(__file__)),
'docs',
'source',
f'{index_name}.rst',
)
docs_dir = os.path.join(
os.path.dirname(os.path.abspath(__file__)),
'docs',
'source',
'platypush',
doc_dir,
)
for comp in components:
comp_file = os.path.join(docs_dir, comp + '.rst')
if not os.path.exists(comp_file):
comp = f'platypush.{package_name}.{comp}'
header = '``' + '.'.join(comp.split('.')[2:]) + '``'
divider = '=' * len(header)
body = f'\n.. automodule:: {comp}\n :members:\n'
out = '\n'.join([header, divider, body])
with open(comp_file, 'w') as f:
f.write(out)
with open(index_file, 'w') as f:
f.write(
f'''
{index_name.title()}
{''.join(['='] * len(index_name))}
.. toctree::
:maxdepth: 1
:caption: {index_name.title()}:
'''
)
for comp in components:
f.write(f' platypush/{doc_dir}/{comp}.rst\n')
_cleanup_removed_components_docs(docs_dir, components)
def _cleanup_removed_components_docs(docs_dir: str, components: Iterable[str]):
new_components = set(components)
existing_files = {
os.path.join(root, file)
for root, _, files in os.walk(docs_dir)
for file in files
if file.endswith('.rst')
}
files_to_remove = {
file
for file in existing_files
if os.path.basename(file).removesuffix('.rst') not in new_components
}
for file in files_to_remove:
print(f'Removing unlinked component {file}')
os.unlink(file)
def generate_plugins_doc():
_generate_components_doc(
index_name='plugins', package_name='plugins', components=get_all_plugins()
)
def generate_backends_doc():
_generate_components_doc(
index_name='backends',
package_name='backend',
components=get_all_backends(),
doc_dir='backend',
)
def generate_events_doc():
_generate_components_doc(
index_name='events',
package_name='message.event',
components=sorted(event for event in get_all_events().keys() if event),
)
def generate_responses_doc():
_generate_components_doc(
index_name='responses',
package_name='message.response',
components=sorted(
response for response in get_all_responses().keys() if response
),
)
def main():
generate_plugins_doc()
generate_backends_doc()
generate_events_doc()
generate_responses_doc()
if __name__ == '__main__':
main()
# vim:sw=4:ts=4:et: