mirror of
https://github.com/RYDE-WORK/ballistica.git
synced 2026-01-19 21:37:57 +08:00
124 lines
3.6 KiB
Python
Executable File
124 lines
3.6 KiB
Python
Executable File
# Released under the MIT License. See LICENSE for details.
|
|
#
|
|
"""Documentation generation functionality."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import sys
|
|
import os
|
|
from dataclasses import dataclass
|
|
from pathlib import Path
|
|
from typing import TYPE_CHECKING
|
|
|
|
from efro.error import CleanError
|
|
from efro.terminal import Clr
|
|
|
|
if TYPE_CHECKING:
|
|
pass
|
|
|
|
|
|
@dataclass
|
|
class AttributeInfo:
|
|
"""Info about an attribute of a class."""
|
|
|
|
name: str
|
|
attr_type: str | None = None
|
|
docs: str | None = None
|
|
|
|
|
|
def parse_docs_attrs(attrs: list[AttributeInfo], docs: str) -> str:
|
|
"""Given a docs str, parses attribute descriptions contained within."""
|
|
docs_lines = docs.splitlines()
|
|
attr_line = None
|
|
for i, line in enumerate(docs_lines):
|
|
if line.strip() in ['Attributes:', 'Attrs:']:
|
|
attr_line = i
|
|
break
|
|
|
|
if attr_line is not None:
|
|
# Docs is now everything *up to* this.
|
|
docs = '\n'.join(docs_lines[:attr_line])
|
|
|
|
# Go through remaining lines creating attrs and docs for each.
|
|
cur_attr: AttributeInfo | None = None
|
|
for i in range(attr_line + 1, len(docs_lines)):
|
|
line = docs_lines[i].strip()
|
|
|
|
# A line with a single alphanumeric word preceding a colon
|
|
# is a new attr.
|
|
splits = line.split(' ', maxsplit=1)
|
|
if splits[0].replace('_', '').isalnum() and splits[-1].endswith(
|
|
':'
|
|
):
|
|
if cur_attr is not None:
|
|
attrs.append(cur_attr)
|
|
cur_attr = AttributeInfo(name=splits[0])
|
|
if len(splits) == 2:
|
|
# Remove brackets and convert from
|
|
# (type): to type.
|
|
cur_attr.attr_type = splits[1][1:-2]
|
|
|
|
# Any other line gets tacked onto the current attr.
|
|
else:
|
|
if cur_attr is not None:
|
|
if cur_attr.docs is None:
|
|
cur_attr.docs = ''
|
|
cur_attr.docs += line + '\n'
|
|
|
|
# Finish out last.
|
|
if cur_attr is not None:
|
|
attrs.append(cur_attr)
|
|
|
|
for attr in attrs:
|
|
if attr.docs is not None:
|
|
attr.docs = attr.docs.strip()
|
|
return docs
|
|
|
|
|
|
def generate(projroot: str) -> None:
|
|
"""Main entry point."""
|
|
from batools.version import get_current_version
|
|
import pdoc
|
|
|
|
# Since we're operating on source dirs, suppress .pyc generation.
|
|
# (__pycache__ dirs in source dirs causes some subtle headaches in
|
|
# the private repo)
|
|
sys.dont_write_bytecode = True
|
|
|
|
# Make sure we're running from the dir above this script.
|
|
os.chdir(projroot)
|
|
|
|
templatesdir = (
|
|
Path(projroot) / 'assets' / 'src' / 'pdoc' / 'templates'
|
|
).absolute()
|
|
pythondir = (
|
|
Path(projroot) / 'assets' / 'src' / 'ba_data' / 'python'
|
|
).absolute()
|
|
outdirname = (Path(projroot) / 'build' / 'docs_html').absolute()
|
|
sys.path.append(str(pythondir))
|
|
|
|
version, build_number = get_current_version()
|
|
|
|
try:
|
|
os.environ['BA_DOCS_GENERATION'] = '1'
|
|
pdoc.render.env.globals['ba_version'] = version
|
|
pdoc.render.env.globals['ba_build'] = build_number
|
|
pdoc.render.configure(
|
|
search=True, show_source=True, template_directory=templatesdir
|
|
)
|
|
pdoc.pdoc(
|
|
'babase',
|
|
'bastd',
|
|
'baclassic',
|
|
'bascenev1',
|
|
'bauiv1',
|
|
output_directory=outdirname,
|
|
)
|
|
except Exception as exc:
|
|
import traceback
|
|
|
|
traceback.print_exc()
|
|
raise CleanError('Docs generation failed') from exc
|
|
|
|
print(f'{Clr.GRN}Docs generation complete.{Clr.RST}')
|