Last active
August 29, 2015 14:06
-
-
Save kalmanolah/b46de8369003640b6dc8 to your computer and use it in GitHub Desktop.
pdoc - a puppet documentation generator thingy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
# @python3 | |
# @author Kalman Olah <[email protected]> | |
"""pdoc - a puppet documentation generator thingy.""" | |
import os | |
import re | |
import fnmatch | |
import click | |
from datetime import datetime | |
__VERSION__ = '0.0.1' | |
__DOC_TEMPLATE__ = """ | |
# == {type}: {name} | |
# | |
# Full description of {type} {name} here. | |
# | |
# === Parameters | |
#{parameters} | |
# === Examples | |
# | |
# class {{ 'ntp': | |
# servers => [ 'pool.ntp.org', 'ntp.local.company.com' ], | |
# }} | |
# | |
# === Authors | |
# | |
# {author} <{email}> | |
# | |
# === Copyright | |
# | |
# Copyright {year} {author}, unless otherwise noted. | |
# | |
""" | |
__PARAM_TEMPLATE__ = """ | |
# [*{key}*] | |
# Explanation of what this parameter affects. | |
# Defaults to {value}. | |
# | |
""" | |
def show_version(ctx, value): | |
"""Print version information and exit.""" | |
if not value: | |
return | |
click.echo('pdoc %s' % __VERSION__) | |
ctx.exit() | |
@click.command() | |
@click.option('--version', '-v', is_flag=True, help='Print version information and exit.', | |
callback=show_version, expose_value=False, is_eager=True) | |
@click.option('--really', '-r', is_flag=True, help='Really apply changes.') | |
@click.option('--author', '-a', default='John Doe', help='Author name to use in generated documentation.') | |
@click.option('--email', '-e', default='[email protected]', help='Author email to use in generated documentation.') | |
@click.argument('path', type=click.Path(exists=False, file_okay=True, dir_okay=True, | |
writable=True, readable=True, resolve_path=True), default='./') | |
@click.pass_context | |
def pdoc(ctx, really, author, email, path): | |
"""pdoc - a puppet documentation generator thingy.""" | |
# If path if a file stick it into a paths list, if not perform some mad | |
# globbing | |
if os.path.isfile(path): | |
paths = (path) if path.endswith('.pp') else () | |
else: | |
paths = [os.path.join(dirpath, f) | |
for dirpath, dirnames, files in os.walk(path) | |
for f in fnmatch.filter(files, '*.pp')] | |
click.echo('Found %s puppet manifests; iterating..' % click.style(str(len(paths)), fg='green', bold=True)) | |
for p in paths: | |
# Read first character of the file: if it's a hashtag it means we have | |
# docs; if it's not, we should add docs | |
with open(p, 'r') as file: | |
first = file.read(1) | |
# If the first character is a hashtag, do nothing | |
if first is '#': | |
continue | |
click.echo('Adding documentation to %s' % click.style(p, fg='blue', bold=True)) | |
# Grab file contents so we can do matching and stuff | |
with open(p, 'r') as file: | |
content = file.read() | |
# Try to extract type, name and parameters | |
pattern = re.compile(r"\s*(\w+)\s+([\w:]+)[\s\w:]*([\"'\w\s,=\$\(\):]*)\s*{.*}\s*", re.DOTALL) | |
matches = re.match(pattern, content) | |
type = 'type' if matches.group(1) is 'define' else matches.group(1) | |
name = matches.group(2) | |
parameters = '' | |
params = re.sub(r"[\s\(\)]", '', matches.group(3)) | |
params = re.split(',', params) | |
for param in params: | |
split = re.split('=', param) | |
value = split[1] if len(split) > 1 else 'undef' | |
parameters += __PARAM_TEMPLATE__.rstrip().format(key=split[0], value=value) | |
docs = __DOC_TEMPLATE__.strip().format( | |
type=type, | |
name=name, | |
parameters=parameters, | |
author=author, | |
email=email, | |
year=datetime.utcnow().year | |
) | |
if really: | |
with open(p, 'w') as file: | |
file.write(docs + '\n' + content) | |
click.echo(click.style('Done!', fg='green', bold=True)) | |
"""Standard import guard.""" | |
if __name__ == '__main__': | |
pdoc(obj={}, auto_envvar_prefix='PDOC') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment