Make all actions honor the optional argument -g or --group

This make it possible to append '-g' or '--groups' followed by
space separated group names to any CLI action command, and the
set of generated files affected by the command will be limited
to the selected groups ('examples', 'tutorial', and 'demos').
Default is all groups. A simple help text is added for each of
the arguments (action and groups) to improve the autogenerated
CLI help output.

This is a squash rebase of these commits:
- p ec29076 Make all actions honor the optional argument -generate
- s e3ad11a Move open_file_append() outside the if to avoid re-open
- s ba4b900 Avoid including readme in all file groups
- s 1ca8bd1 Simplify code
- s a9e7337 Rename some variables to better reflect their contents and relations
- s 58a54b2 Move test to include readme inside collect_filenames() function
- s f2a0db0 Improve status output by adding group name
- s d3b299b Rename -generate option to -g/--groups and add argument help
This commit is contained in:
KV 2020-07-20 20:48:37 +02:00 committed by Daniel Rojas
parent 4eedd94164
commit 476f85bcf5

View File

@ -13,56 +13,59 @@ from wireviz import wireviz
from wv_helper import open_file_write, open_file_read, open_file_append from wv_helper import open_file_write, open_file_read, open_file_append
paths = {} readme = 'readme.md'
paths['examples'] = {'path': Path(script_path).parent.parent.parent / 'examples', groups = {}
groups['examples'] = {'path': Path(script_path).parent.parent.parent / 'examples',
'prefix': 'ex', 'prefix': 'ex',
readme: [], # Include no files
'title': 'Example Gallery'} 'title': 'Example Gallery'}
paths['tutorial'] = {'path': Path(script_path).parent.parent.parent / 'tutorial', groups['tutorial'] = {'path': Path(script_path).parent.parent.parent / 'tutorial',
'prefix': 'tutorial', 'prefix': 'tutorial',
readme: ['md', 'yml'], # Include .md and .yml files
'title': 'WireViz Tutorial'} 'title': 'WireViz Tutorial'}
paths['demos'] = {'path': Path(script_path).parent.parent.parent / 'examples', groups['demos'] = {'path': Path(script_path).parent.parent.parent / 'examples',
'prefix': 'demo'} 'prefix': 'demo'}
input_extensions = ['.yml'] input_extensions = ['.yml']
generated_extensions = ['.gv', '.png', '.svg', '.html', '.bom.tsv'] generated_extensions = ['.gv', '.png', '.svg', '.html', '.bom.tsv']
extensions_not_from_graphviz = [ext for ext in generated_extensions if ext[-1] == 'v'] extensions_not_from_graphviz = [ext for ext in generated_extensions if ext[-1] == 'v']
readme = 'readme.md'
def collect_filenames(description, pathkey, ext_list, extrafile = None): def collect_filenames(description, groupkey, ext_list):
path = paths[pathkey]['path'] path = groups[groupkey]['path']
patterns = [f"{paths[pathkey]['prefix']}*{ext}" for ext in ext_list] patterns = [f"{groups[groupkey]['prefix']}*{ext}" for ext in ext_list]
if extrafile is not None: if ext_list != input_extensions and readme in groups[groupkey]:
patterns.append(extrafile) patterns.append(readme)
print(f"{description} {path}") print(f"{description} {groupkey} in {path}")
return sorted([filename for pattern in patterns for filename in path.glob(pattern)]) return sorted([filename for pattern in patterns for filename in path.glob(pattern)])
def build(dirname, build_readme, include_source, include_readme): def build_generated(groupkey):
# build files # build files
path = paths[dirname]['path'] path = groups[groupkey]['path']
build_readme = readme in groups[groupkey]
if build_readme: if build_readme:
with open_file_write(path / 'readme.md') as out: include_readme = 'md' in groups[groupkey][readme]
out.write(f'# {paths[dirname]["title"]}\n\n') include_source = 'yml' in groups[groupkey][readme]
with open_file_write(path / readme) as out:
out.write(f'# {groups[groupkey]["title"]}\n\n')
# collect and iterate input YAML files # collect and iterate input YAML files
for yaml_file in collect_filenames('Building', dirname, input_extensions): for yaml_file in collect_filenames('Building', groupkey, input_extensions):
print(f' {yaml_file}') print(f' {yaml_file}')
wireviz.parse_file(yaml_file) wireviz.parse_file(yaml_file)
if build_readme: if build_readme:
i = ''.join(filter(str.isdigit, yaml_file.stem)) i = ''.join(filter(str.isdigit, yaml_file.stem))
if include_readme:
with open_file_append(path / readme) as out: with open_file_append(path / readme) as out:
with open_file_read(path / f'{yaml_file.stem}.md') as info: if include_readme:
with open_file_read(yaml_file.with_suffix('.md')) as info:
for line in info: for line in info:
out.write(line.replace('## ', '## {} - '.format(i))) out.write(line.replace('## ', f'## {i} - '))
out.write('\n\n') out.write('\n\n')
else: else:
with open_file_append(path / readme) as out:
out.write(f'## Example {i}\n') out.write(f'## Example {i}\n')
with open_file_append(path / readme) as out:
if include_source: if include_source:
with open_file_read(yaml_file) as src: with open_file_read(yaml_file) as src:
out.write('```yaml\n') out.write('```yaml\n')
@ -75,32 +78,33 @@ def build(dirname, build_readme, include_source, include_readme):
out.write(f'[Source]({yaml_file.name}) - [Bill of Materials]({yaml_file.stem}.bom.tsv)\n\n\n') out.write(f'[Source]({yaml_file.name}) - [Bill of Materials]({yaml_file.stem}.bom.tsv)\n\n\n')
def clean_examples(): def clean_generated(groupkeys):
for key in paths.keys(): for key in groupkeys:
# collect and remove files # collect and remove files
for filename in collect_filenames('Cleaning', key, generated_extensions, readme): for filename in collect_filenames('Cleaning', key, generated_extensions):
if filename.is_file(): if filename.is_file():
print(f' rm {filename}') print(f' rm {filename}')
os.remove(filename) os.remove(filename)
def compare_generated(include_from_graphviz = False): def compare_generated(groupkeys, include_from_graphviz = False):
compare_extensions = generated_extensions if include_from_graphviz else extensions_not_from_graphviz compare_extensions = generated_extensions if include_from_graphviz else extensions_not_from_graphviz
for key in paths.keys(): for key in groupkeys:
# collect and compare files # collect and compare files
for filename in collect_filenames('Comparing', key, compare_extensions, readme): for filename in collect_filenames('Comparing', key, compare_extensions):
cmd = f'git --no-pager diff {filename}' cmd = f'git --no-pager diff {filename}'
print(f' {cmd}') print(f' {cmd}')
os.system(cmd) os.system(cmd)
def restore_generated(): def restore_generated(groupkeys):
for key, value in paths.items(): for key in groupkeys:
# collect input YAML files # collect input YAML files
filename_list = collect_filenames('Restoring', key, input_extensions) filename_list = collect_filenames('Restoring', key, input_extensions)
# collect files to restore # collect files to restore
filename_list = [fn.with_suffix(ext) for fn in filename_list for ext in generated_extensions] filename_list = [fn.with_suffix(ext) for fn in filename_list for ext in generated_extensions]
filename_list.append(value['path'] / readme) if readme in groups[key]:
filename_list.append(groups[key]['path'] / readme)
# restore files # restore files
for filename in filename_list: for filename in filename_list:
cmd = f'git checkout -- {filename}' cmd = f'git checkout -- {filename}'
@ -110,27 +114,27 @@ def restore_generated():
def parse_args(): def parse_args():
parser = argparse.ArgumentParser(description='Wireviz Example Manager',) parser = argparse.ArgumentParser(description='Wireviz Example Manager',)
parser.add_argument('action', nargs='?', action='store', default='build') parser.add_argument('action', nargs='?', action='store',
parser.add_argument('-generate', nargs='*', choices=['examples', 'demos', 'tutorial'], default=['examples', 'demos', 'tutorial']) choices=['build','clean','compare','restore'], default='build',
help='what to do with the generated files (default: build)')
parser.add_argument('-g', '--groups', nargs='+',
choices=groups.keys(), default=groups.keys(),
help='the groups of generated files (default: all)')
return parser.parse_args() return parser.parse_args()
def main(): def main():
args = parse_args() args = parse_args()
if args.action == 'build': if args.action == 'build':
for gentype in args.generate: # TODO: Move this loop into the function for consistency?
if gentype == 'demos': for groupkey in args.groups:
build('demos', build_readme = False, include_source = False, include_readme = False) build_generated(groupkey)
if gentype == 'examples':
build('examples', build_readme = True, include_source = False, include_readme = False)
if gentype == 'tutorial':
build('tutorial', build_readme = True, include_source = True, include_readme = True)
elif args.action == 'clean': elif args.action == 'clean':
clean_examples() clean_generated(args.groups)
elif args.action == 'compare': elif args.action == 'compare':
compare_generated() compare_generated(args.groups)
elif args.action == 'restore': elif args.action == 'restore':
restore_generated() restore_generated(args.groups)
if __name__ == '__main__': if __name__ == '__main__':