mirror of
https://github.com/systemd/systemd
synced 2025-10-06 00:13:24 +02:00
All those files are standalone programs that can be executed directly. Some .py files were marked executable, others weren't, probably accidentally. Mark them all as executable in preparation for subsequent changes.
144 lines
4.4 KiB
Python
Executable File
144 lines
4.4 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
# SPDX-License-Identifier: LGPL-2.1-or-later
|
|
|
|
import os
|
|
import sys
|
|
|
|
try:
|
|
import lxml.etree as tree
|
|
except ImportError as e:
|
|
print(str(e), file=sys.stderr)
|
|
sys.exit(77)
|
|
|
|
_parser = tree.XMLParser(resolve_entities=False)
|
|
tree.set_default_parser(_parser)
|
|
|
|
|
|
def find_undocumented_functions(pages, ignorelist):
|
|
undocumented = []
|
|
for page in pages:
|
|
filename = os.path.basename(page)
|
|
pagetree = tree.parse(page)
|
|
|
|
assert pagetree.getroot().tag == "refentry"
|
|
|
|
hist_section = pagetree.find("refsect1[title='History']")
|
|
for func in pagetree.findall("//funcprototype/funcdef/function"):
|
|
path = f"./refsynopsisdiv/funcsynopsis/funcprototype/funcdef/function[.='{func.text}']"
|
|
assert pagetree.findall(path) == [func]
|
|
|
|
if (
|
|
hist_section is None
|
|
or hist_section.find(f"para/function[.='{func.text}()']") is None
|
|
):
|
|
if func.text not in ignorelist:
|
|
undocumented.append((filename, func.text))
|
|
return undocumented
|
|
|
|
|
|
def construct_path(element):
|
|
tag = element.tag
|
|
|
|
if tag == "refentry":
|
|
return "."
|
|
|
|
predicate = ""
|
|
if tag == "varlistentry":
|
|
text = "".join(element.find("term").itertext())
|
|
predicate = f'[term="{text}"]'
|
|
elif tag.startswith("refsect"):
|
|
text = "".join(element.find("title").itertext())
|
|
predicate = f'[title="{text}"]'
|
|
elif tag == "variablelist":
|
|
varlists = element.getparent().findall(tag)
|
|
if len(varlists) > 1:
|
|
predicate = f"[{varlists.index(element)+1}]"
|
|
|
|
return construct_path(element.getparent()) + "/" + tag + predicate
|
|
|
|
|
|
def find_undocumented_commands(pages, ignorelist):
|
|
undocumented = []
|
|
for page in pages:
|
|
filename = os.path.basename(page)
|
|
|
|
pagetree = tree.parse(page)
|
|
if pagetree.getroot().tag != "refentry":
|
|
continue
|
|
|
|
for varlistentry in pagetree.findall("*//variablelist/varlistentry"):
|
|
path = construct_path(varlistentry)
|
|
|
|
assert pagetree.findall(path) == [varlistentry]
|
|
|
|
listitem = varlistentry.find("listitem")
|
|
parent = listitem if listitem is not None else varlistentry
|
|
|
|
rev = parent.getchildren()[-1]
|
|
if (
|
|
rev.get("href") != "version-info.xml" and
|
|
not path.startswith(tuple(entry[1] for entry in ignorelist if entry[0] == filename))
|
|
):
|
|
undocumented.append((filename, path))
|
|
|
|
return undocumented
|
|
|
|
|
|
def process_pages(pages):
|
|
command_pages = []
|
|
function_pages = []
|
|
|
|
for page in pages:
|
|
filename = os.path.basename(page)
|
|
if filename.startswith("org.freedesktop."): # dbus
|
|
continue
|
|
|
|
if (
|
|
filename.startswith("sd_")
|
|
or filename.startswith("sd-")
|
|
or filename.startswith("udev_")
|
|
):
|
|
function_pages.append(page)
|
|
continue
|
|
|
|
command_pages.append(page)
|
|
|
|
undocumented_commands = find_undocumented_commands(
|
|
command_pages, command_ignorelist
|
|
)
|
|
undocumented_functions = find_undocumented_functions(
|
|
function_pages, function_ignorelist
|
|
)
|
|
|
|
return undocumented_commands, undocumented_functions
|
|
|
|
|
|
if __name__ == "__main__":
|
|
with open(os.path.join(os.path.dirname(__file__), "command_ignorelist")) as f:
|
|
command_ignorelist = []
|
|
for l in f.read().splitlines():
|
|
if l.startswith("#"):
|
|
continue
|
|
fname, path = l.split(" ", 1)
|
|
path = path.replace("\\n", "\n")
|
|
command_ignorelist.append((fname, path))
|
|
with open(os.path.join(os.path.dirname(__file__), "function_ignorelist")) as f:
|
|
function_ignorelist = f.read().splitlines()
|
|
|
|
undocumented_commands, undocumented_functions = process_pages(sys.argv[1:])
|
|
|
|
if undocumented_commands or undocumented_functions:
|
|
for filename, func in undocumented_functions:
|
|
print(
|
|
f"Function {func}() in {filename} isn't documented in the History section."
|
|
)
|
|
for filename, path in undocumented_commands:
|
|
print(filename, path, "is undocumented")
|
|
if undocumented_commands:
|
|
print(
|
|
"Hint: if you reorganized this part of the documentation, "
|
|
"please update tools/commands_ignorelist."
|
|
)
|
|
|
|
sys.exit(1)
|