WireViz/src/wireviz/build_examples.py
2021-10-16 22:26:59 +02:00

195 lines
6.2 KiB
Python
Executable File

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import argparse
import os
import sys
from pathlib import Path
script_path = Path(__file__).absolute()
sys.path.insert(0, str(script_path.parent.parent)) # to find wireviz module
from wv_helper import open_file_append, open_file_read, open_file_write
from wireviz import APP_NAME, __version__, wireviz
dir = script_path.parent.parent.parent
readme = "readme.md"
groups = {
"examples": {
"path": dir / "examples",
"prefix": "ex",
readme: [], # Include no files
"title": "Example Gallery",
},
"tutorial": {
"path": dir / "tutorial",
"prefix": "tutorial",
readme: ["md", "yml"], # Include .md and .yml files
"title": f"{APP_NAME} Tutorial",
},
"demos": {
"path": dir / "examples",
"prefix": "demo",
},
}
input_extensions = [".yml"]
extensions_not_containing_graphviz_output = [".gv", ".bom.tsv"]
extensions_containing_graphviz_output = [".png", ".svg", ".html"]
generated_extensions = (
extensions_not_containing_graphviz_output + extensions_containing_graphviz_output
)
def collect_filenames(description, groupkey, ext_list):
path = groups[groupkey]["path"]
patterns = [f"{groups[groupkey]['prefix']}*{ext}" for ext in ext_list]
if ext_list != input_extensions and readme in groups[groupkey]:
patterns.append(readme)
print(f'{description} {groupkey} in "{path}"')
return sorted([filename for pattern in patterns for filename in path.glob(pattern)])
def build_generated(groupkeys):
for key in groupkeys:
# preparation
path = groups[key]["path"]
build_readme = readme in groups[key]
if build_readme:
include_readme = "md" in groups[key][readme]
include_source = "yml" in groups[key][readme]
with open_file_write(path / readme) as out:
out.write(f'# {groups[key]["title"]}\n\n')
# collect and iterate input YAML files
for yaml_file in collect_filenames("Building", key, input_extensions):
print(f' "{yaml_file}"')
wireviz.parse(yaml_file, output_formats=("gv", "html", "png", "svg", "tsv"))
if build_readme:
i = "".join(filter(str.isdigit, yaml_file.stem))
with open_file_append(path / readme) as out:
if include_readme:
with open_file_read(yaml_file.with_suffix(".md")) as info:
for line in info:
out.write(line.replace("## ", f"## {i} - "))
out.write("\n\n")
else:
out.write(f"## Example {i}\n")
if include_source:
with open_file_read(yaml_file) as src:
out.write("```yaml\n")
for line in src:
out.write(line)
out.write("```\n")
out.write("\n")
out.write(f"![]({yaml_file.stem}.png)\n\n")
out.write(
f"[Source]({yaml_file.name}) - [Bill of Materials]({yaml_file.stem}.bom.tsv)\n\n\n"
)
def clean_generated(groupkeys):
for key in groupkeys:
# collect and remove files
for filename in collect_filenames("Cleaning", key, generated_extensions):
if filename.is_file():
print(f' rm "{filename}"')
Path(filename).unlink()
def compare_generated(groupkeys, branch="", include_graphviz_output=False):
if branch:
branch = f" {branch.strip()}"
compare_extensions = (
generated_extensions
if include_graphviz_output
else extensions_not_containing_graphviz_output
)
for key in groupkeys:
# collect and compare files
for filename in collect_filenames("Comparing", key, compare_extensions):
cmd = f'git --no-pager diff{branch} -- "{filename}"'
print(f" {cmd}")
os.system(cmd)
def restore_generated(groupkeys, branch=""):
if branch:
branch = f" {branch.strip()}"
for key in groupkeys:
# collect input YAML files
filename_list = collect_filenames("Restoring", key, input_extensions)
# collect files to restore
filename_list = [
fn.with_suffix(ext) for fn in filename_list for ext in generated_extensions
]
if readme in groups[key]:
filename_list.append(groups[key]["path"] / readme)
# restore files
for filename in filename_list:
cmd = f'git checkout{branch} -- "{filename}"'
print(f" {cmd}")
os.system(cmd)
def parse_args():
parser = argparse.ArgumentParser(
description=f"{APP_NAME} Example Manager",
)
parser.add_argument(
"-V",
"--version",
action="version",
version=f"%(prog)s - {APP_NAME} {__version__}",
)
parser.add_argument(
"action",
nargs="?",
action="store",
choices=["build", "clean", "compare", "diff", "restore"],
default="build",
help="what to do with the generated files (default: build)",
)
parser.add_argument(
"-c",
"--compare-graphviz-output",
action="store_true",
help="the Graphviz output is also compared (default: False)",
)
parser.add_argument(
"-b",
"--branch",
action="store",
default="",
help="branch or commit to compare with or restore from",
)
parser.add_argument(
"-g",
"--groups",
nargs="+",
choices=groups.keys(),
default=groups.keys(),
help="the groups of generated files (default: all)",
)
return parser.parse_args()
def main():
args = parse_args()
if args.action == "build":
build_generated(args.groups)
elif args.action == "clean":
clean_generated(args.groups)
elif args.action == "compare" or args.action == "diff":
compare_generated(args.groups, args.branch, args.compare_graphviz_output)
elif args.action == "restore":
restore_generated(args.groups, args.branch)
if __name__ == "__main__":
main()