1
0
Fork 0

docs: Build function docs from docstrings

Read the docstrings using ASTs instead of
importing the modules; this prevents the
need to install TuneD dependencies when
just building the docs (e.g., in Github Pages).
This commit is contained in:
Pavol Žáčik 2025-04-01 08:59:20 +02:00
parent 38d4414a85
commit 2c4698e750
No known key found for this signature in database
GPG key ID: B3029C97EB97E3E4
6 changed files with 64 additions and 98 deletions

1
.gitignore vendored
View file

@ -4,3 +4,4 @@ tuned-*.tar.bz2
*~
*.html
doc/manual/modules/performance/ref_available-tuned-plug-ins.adoc
doc/manual/modules/performance/ref_built-in-functions-available-in-tuned-profiles.adoc

View file

@ -1,36 +0,0 @@
import argparse
import os
import inspect
from tuned.utils.class_loader import ClassLoader
from tuned.plugins.base import Plugin
class PluginDocLoader(ClassLoader):
def __init__(self):
super(PluginDocLoader, self).__init__()
def _set_loader_parameters(self):
self._namespace = "tuned.plugins"
self._prefix = "plugin_"
self._interface = Plugin
parser = argparse.ArgumentParser()
parser.add_argument("intro")
parser.add_argument("out")
args = parser.parse_args()
with open(args.intro, "r") as intro_file:
intro = intro_file.read()
all_plugins = sorted(PluginDocLoader().load_all_classes(), key=lambda x: x.__module__)
with open(args.out, "w") as out_file:
out_file.write(intro)
for plugin in all_plugins:
plugin_file = inspect.getfile(plugin)
plugin_name = os.path.basename(plugin_file)[7:-3]
out_file.write("\n")
out_file.write("== **%s**\n" % plugin_name)
out_file.write(inspect.cleandoc(plugin.__doc__))
out_file.write("\n")

View file

@ -1,7 +1,8 @@
.PHONY: clean
index.html: master.adoc assemblies/*.adoc meta/*.adoc modules/performance/*.adoc ../../tuned/plugins/plugin_*.py
$(PYTHON) ../../compile_plugin_docs.py modules/performance/ref_available-tuned-plug-ins_intro.adoc modules/performance/ref_available-tuned-plug-ins.adoc
index.html: master.adoc assemblies/*.adoc meta/*.adoc modules/performance/*.adoc ../../tuned/plugins/plugin_*.py ../../tuned/profiles/functions/function_*.py
$(PYTHON) ./compile_plugin_docs.py ../../tuned/plugins plugin_ Plugin modules/performance/ref_available-tuned-plug-ins_intro.adoc modules/performance/ref_available-tuned-plug-ins.adoc
$(PYTHON) ./compile_plugin_docs.py ../../tuned/profiles/functions function_ Function modules/performance/ref_built-in-functions-available-in-tuned-profiles_intro.adoc modules/performance/ref_built-in-functions-available-in-tuned-profiles.adoc
asciidoctor -o index.html master.adoc || asciidoc -d book -o index.html master.adoc
install: index.html
@ -9,4 +10,5 @@ install: index.html
clean:
rm -f modules/performance/ref_available-tuned-plug-ins.adoc
rm -f modules/performance/ref_built-in-functions-available-in-tuned-profiles.adoc
rm -f *.html

View file

@ -0,0 +1,53 @@
#!/usr/bin/env python3
import argparse
import ast
import os
import inspect
class DocLoader:
def __init__(self, directory, prefix, base):
self._directory = directory
self._prefix = prefix
self._base = base
def _load_doc(self, module_path):
with open(module_path, "r") as file:
tree = ast.parse(file.read(), filename=module_path)
for node in ast.walk(tree):
if isinstance(node, ast.ClassDef) and any(
hasattr(base, "attr") and base.attr == self._base for base in node.bases
):
return inspect.cleandoc(ast.get_docstring(node))
return ""
def load_all_docs(self):
docs = {}
for filename in os.listdir(self._directory):
if not filename.startswith(self._prefix):
continue
name = filename.split(".")[0].split("_", 1)[1]
path = os.path.join(self._directory, filename)
docs[name] = self._load_doc(path)
return docs
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("directory")
parser.add_argument("prefix")
parser.add_argument("base")
parser.add_argument("intro")
parser.add_argument("out")
args = parser.parse_args()
with open(args.intro, "r") as intro_file:
intro = intro_file.read()
doc_loader = DocLoader(args.directory, args.prefix, args.base)
class_docs = doc_loader.load_all_docs()
with open(args.out, "w") as out_file:
out_file.write(intro)
for name, docs in class_docs.items():
out_file.writelines(["\n", "== **%s**\n" % name, "%s\n" % docs])

View file

@ -1,60 +0,0 @@
:_module-type: REFERENCE
[id="built-in-functions-available-in-tuned-profiles_{context}"]
= Built-in functions available in TuneD profiles
[role="_abstract"]
The following built-in functions are available in all *TuneD* profiles:
`PROFILE_DIR`::
Returns the directory path where the profile and the `tuned.conf` file are located.
`exec`::
Executes a process and returns its output.
`assertion`::
Compares two arguments. If they _do not match_, the function logs text from the first argument and aborts profile loading.
`assertion_non_equal`::
Compares two arguments. If they _match_, the function logs text from the first argument and aborts profile loading.
`kb2s`::
Converts kilobytes to disk sectors.
`s2kb`::
Converts disk sectors to kilobytes.
`strip`::
Creates a string from all passed arguments and deletes both leading and trailing white space.
`virt_check`::
Checks whether *TuneD* is running inside a virtual machine (VM) or on bare metal:
+
* Inside a VM, the function returns the first argument.
* On bare metal, the function returns the second argument, even in case of an error.
`cpulist_invert`::
Inverts a list of CPUs to make its complement. For example, on a system with 4 CPUs, numbered from 0 to 3, the inversion of the list `0,2,3` is `1`.
`cpulist2hex`::
Converts a CPU list to a hexadecimal CPU mask.
`cpulist2hex_invert`::
Converts a CPU list to a hexadecimal CPU mask and inverts it.
`hex2cpulist`::
Converts a hexadecimal CPU mask to a CPU list.
`cpulist_online`::
Checks whether the CPUs from the list are online. Returns the list containing only online CPUs.
`cpulist_present`::
Checks whether the CPUs from the list are present. Returns the list containing only present CPUs.
`cpulist_unpack`::
Unpacks a CPU list in the form of `1-3,4` to `1,2,3,4`.
`cpulist_pack`::
Packs a CPU list in the form of `1,2,3,5` to `1-3,5`.
`intel_recommended_pstate`::
Returns recommended intel_pstate CPUFreq driver mode based on processor generation.

View file

@ -0,0 +1,6 @@
:_module-type: REFERENCE
[id="built-in-functions-available-in-tuned-profiles_{context}"]
= Built-in functions available in TuneD profiles
[role="_abstract"]
The following built-in functions are available in all *TuneD* profiles: