#!/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()