1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164
|
#!/usr/bin/python3
"""
Generate a table of the Graphviz compile configuration for different platforms
from files generated by the ./configure command.
"""
import os
import re
import sys
from argparse import ArgumentParser
def main():
"""entry point"""
parser = ArgumentParser(
description="Generate a table of the Graphviz compile "
"configuration for different platforms from files "
"generated by the ./configure command."
)
parser.add_argument(
"--color",
"-c",
action="store_const",
dest="colors",
const="green:red",
help="Color output using default coloring. Yes is "
"colored green and No is colored red",
)
parser.add_argument(
"--colors",
help="Color output using specified COLORS. The format is "
"<Yes-color>:<No-color>",
)
parser.add_argument(
"--short", "-s", action="store_true", help="Output only Yes or No"
)
parser.add_argument("filename", nargs="*", help="Configuration log to read")
opts = parser.parse_args()
if opts.colors is None:
styles = {
"Yes": "",
"No": "",
}
else:
yes_color = "green"
no_color = "red"
if opts.colors != "":
colors = opts.colors.split(":")
if len(colors) == 2:
yes_color, no_color = colors
else:
sys.stderr.write(
f"Error: {opts.colors} color specification is illegal\n"
)
parser.print_help(file=sys.stderr)
sys.exit(1)
styles = {
"Yes": f' style="color: {yes_color};"',
"No": f' style="color: {no_color};"',
}
table: dict[str, dict[str, dict[str, str]]] = {}
table_sections: list[str] = []
component_names: dict[str, list[str]] = {}
platforms: set[str] = set()
for filename in opts.filename:
os_path = os.path.dirname(filename)
os_version_id = os.path.basename(os_path)
os_id = os.path.basename(os.path.dirname(os_path))
platform = f"{os_id.capitalize()} {os_version_id}"
platforms.add(platform)
with open(filename, "rt", encoding="utf-8") as fp:
for line in fp:
item = [item.strip() for item in line.split(":")]
if len(item) >= 2:
if item[1] == "":
section_name = item[0]
if section_name not in table:
table[section_name] = {}
table_sections.append(section_name)
component_names[section_name] = []
else:
component_name, component_value, *_ = item
short_value = re.sub("(Yes|No).*", "\\1", component_value)
if opts.short:
component_value = short_value
if component_name not in table[section_name]:
table[section_name][component_name] = {}
component_names[section_name].append(component_name)
table[section_name][component_name][platform] = component_value
colspan = len(platforms) + 1
indent = ""
print(f"{indent}<!DOCTYPE html>")
print(f"{indent}<html>")
indent += " "
print(f"{indent}<head>")
indent += " "
print(f'{indent}<meta charset="utf-8">')
print(f"{indent}<style>")
indent += " "
print(
f"{indent}table {{text-align: left; white-space: nowrap; position: relative;}}"
)
print(
f"{indent}thead tr th {{padding-right: 1em; padding-bottom: 5px; "
"position: sticky; top: 0px; background-color: white;}"
)
print(f"{indent}td, th {{padding-left: 1.5em;}}")
indent = indent[:-2]
print(f"{indent}</style>")
indent = indent[:-2]
print(f"{indent}</head>")
print(f"{indent}<body>")
indent += " "
header = table_sections[0].replace("will be", "was")
print(f"{indent}<h1>{header}:</h1>")
print(f"{indent}<table>")
indent += " "
print(f"{indent}<thead>")
indent += " "
print(f"{indent}<tr>")
indent += " "
print(f"{indent}<th></th>")
for platform in sorted(platforms):
print(f"{indent}<th>{platform}</th>")
indent = indent[:-2]
print(f"{indent} </tr>")
print(f"{indent} </thead>")
print(f"{indent} <tbody>")
indent += " "
indent = indent[:-2]
for section_name in table_sections[1:]:
print(f'{indent}<tr><th colspan="{colspan}">{section_name};</th></tr>')
for component_name in component_names[section_name]:
print(f"{indent}<tr>")
indent += " "
print(f"{indent}<td>{component_name}</td>")
for platform in sorted(platforms):
component_value = table[section_name][component_name][platform]
short_value = re.sub("(Yes|No).*", "\\1", component_value)
color_style = styles[short_value]
print(f"{indent}<td{color_style}>{component_value}</td>")
indent = indent[:-2]
print(f"{indent}</tr>")
print(f'{indent}<tr><th colspan="{colspan}"> </th></tr>')
indent = indent[:-2]
print(f"{indent}</tbody>")
indent = indent[:-2]
print(f"{indent}</table>")
indent = indent[:-2]
print(f"{indent}</body>")
indent = indent[:-2]
print(f"{indent}</html>")
# Python trick to get a main routine
if __name__ == "__main__":
main()
|