diff --git a/.gitignore b/.gitignore index 32fc916..e2075ba 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,5 @@ venv/ dist/ build/ adr_viewer.egg-info/ -.pytest_cache/ \ No newline at end of file +.pytest_cache/ +.DS_Store diff --git a/README.md b/README.md index 27199d1..f784301 100644 --- a/README.md +++ b/README.md @@ -35,11 +35,13 @@ $ python setup.py install Usage: adr-viewer [OPTIONS] Options: - --adr-path TEXT Directory containing ADR files. [default: doc/adr/] - --output TEXT File to write output to. [default: index.html] - --serve Serve content at http://localhost:8000/ - --port INT Custom server port [default: 8000] - --help Show this message and exit. + --adr-path TEXT Directory containing ADR files. [default: doc/adr/] + --output TEXT File to write output to. [default: index.html] + --serve Serve content at http://localhost:8000/ + --port INTEGER Change port for the server [default: 8000] + --template-dir TEXT Template directory + --heading TEXT ADR Page Heading [default: ADR Viewer - ] + --help Show this message and exit ``` The default for `--adr-path` is `doc/adr/` because this is the default path generated by `adr-tools`. diff --git a/adr_viewer/__init__.py b/adr_viewer/__init__.py index 8093691..f05a5b3 100644 --- a/adr_viewer/__init__.py +++ b/adr_viewer/__init__.py @@ -8,19 +8,20 @@ from bottle import Bottle, run -def extract_statuses_from_adr(page_object): - status_section = page_object.find('h2', text='Status') +def extract_from_adr(page_object, find1, node1, node2, node3, txt): + section = page_object.find(find1, text=txt) - if status_section and status_section.nextSibling: - current_node = status_section.nextSibling + if section and section.nextSibling: + current_node = section.nextSibling - while current_node.name != 'h2' and current_node.nextSibling: + while current_node.name != find1 and current_node.nextSibling: current_node = current_node.nextSibling - if current_node.name == 'p': + if current_node.name == node1: yield current_node.text - elif current_node.name == 'ul': - yield from (li.text for li in current_node.children if li.name == "li") + elif current_node.name == node2: + yield from (li.text for li in + current_node.children if li.name == node3) else: continue @@ -30,7 +31,51 @@ def parse_adr_to_config(path): soup = BeautifulSoup(adr_as_html, features='html.parser') - status = list(extract_statuses_from_adr(soup)) + status = list(extract_from_adr(soup, 'h2', 'p', 'ul', 'li', 'Status')) + thedate = list(extract_from_adr(soup, 'h1', 'p', 'ul', 'li', '' + ))[0].replace('Date: ', '') + context = list(extract_from_adr(soup, 'h2', 'p', 'ul', 'li', 'Context')) + decision = list(extract_from_adr(soup, 'h2', 'p', 'ul', 'li', 'Decision')) + consequences = list(extract_from_adr(soup, 'h2', 'p', 'ul', 'li', + 'Consequences')) + references = list(extract_from_adr(soup, 'h2', 'p', 'ul', 'li', + 'References')) + + amended = [] + amends = [] + superceded = [] + supercedes = [] + drivenby = [] + drives = [] + + ' Extract additional status supporting information' + for line in status: + if line.startswith("Superceded") or line.startswith("Superseded"): + for supercededlink in line.split('\n'): + ln = supercededlink.replace("Superseded by ", "" + ).replace("Superceded by ", "") + superceded.append(ln) + if line.startswith("Supersedes") or line.startswith("Supercedes"): + for supercedeslink in line.split('\n'): + ln = supercedeslink.replace("Supersedes ", "" + ).replace("Supercedes ", "") + supercedes.append(ln) + if line.startswith("Amended By"): + for amendedlink in line.split('\n'): + ln = amendedlink.replace("Amended by ", "") + amended.append(ln) + if line.startswith("Amends"): + for amendslink in line.split('\n'): + ln = amendslink.replace("Amends ", "") + amends.append(ln) + if line.startswith("Driven By"): + for drivenbylink in line.split('\n'): + ln = drivenbylink.replace("Driven by ", "") + drivenby.append(ln) + if line.startswith("Drives"): + for driveslink in line.split('\n'): + ln = driveslink.replace("Drives ", "") + drives.append(ln) if any([line.startswith("Amended by") for line in status]): status = 'amended' @@ -38,7 +83,7 @@ def parse_adr_to_config(path): status = 'accepted' elif any([line.startswith("Superseded by") for line in status]): status = 'superseded' - elif any([line.startswith("Pending") for line in status]): + elif any([line.startswith("Proposed") or line.startswith("Pending") for line in status]): status = 'pending' else: status = 'unknown' @@ -46,10 +91,21 @@ def parse_adr_to_config(path): header = soup.find('h1') if header: - return { + return { 'status': status, + 'date': thedate, 'body': adr_as_html, - 'title': header.text + 'title': header.text, + 'context': context, + 'decision': decision, + 'consequences': consequences, + 'references': references, + 'superceded': superceded, + 'supercedes': supercedes, + 'amended': amended, + 'amends': amends, + 'drivenby': drivenby, + 'drives': drives } else: return None @@ -61,7 +117,6 @@ def render_html(config, template_dir_override=None): loader=PackageLoader('adr_viewer', 'templates') if template_dir_override is None else FileSystemLoader(template_dir_override), autoescape=select_autoescape(['html', 'xml']) ) - template = env.get_template('index.html') return template.render(config=config) @@ -80,15 +135,17 @@ def run_server(content, port): run(app, host='localhost', port=port, quiet=True) -def generate_content(path, template_dir_override=None): +def generate_content(path, template_dir_override=None, heading=None): files = get_adr_files("%s/*.md" % path) + if not heading: + heading = 'ADR Viewer - ' + os.path.basename(os.getcwd()) + config = { - 'project_title': os.path.basename(os.getcwd()), + 'heading': heading, 'records': [] } - for index, adr_file in enumerate(files): adr_attributes = parse_adr_to_config(adr_file) @@ -104,16 +161,39 @@ def generate_content(path, template_dir_override=None): @click.command() -@click.option('--adr-path', default='doc/adr/', help='Directory containing ADR files.', show_default=True) -@click.option('--output', default='index.html', help='File to write output to.', show_default=True) -@click.option('--serve', default=False, help='Serve content at http://localhost:8000/', is_flag=True) -@click.option('--port', default=8000, help='Change port for the server', show_default=True) -@click.option('--template-dir', default=None, help='Template directory.', show_default=True) -def main(adr_path, output, serve, port, template_dir): - content = generate_content(adr_path, template_dir) +@click.option('--adr-path', + default='doc/adr/', + help='Directory containing ADR files.', + show_default=True) +@click.option('--output', + default='index.html', + help='File to write output to.', + show_default=True) +@click.option('--serve', + default=False, + help='Serve content at http://localhost:8000/', + is_flag=True) +@click.option('--port', + default=8000, + help='Change port for the server', + show_default=True) +@click.option('--template-dir', + default=None, + help='Template directory.', + show_default=True) +@click.option('--heading', + default='ADR Viewer - ', + help='ADR Page Heading', + show_default=True) +def main(adr_path, output, serve, port, template_dir, heading): + content = generate_content(adr_path, template_dir, heading) if serve: run_server(content, port) else: with open(output, 'w') as out: out.write(content) + + +if __name__ == '__main__': + main() diff --git a/adr_viewer/templates/.DS_Store b/adr_viewer/templates/.DS_Store new file mode 100644 index 0000000..68b9258 Binary files /dev/null and b/adr_viewer/templates/.DS_Store differ diff --git a/adr_viewer/templates/timeline/index.html b/adr_viewer/templates/timeline/index.html new file mode 100644 index 0000000..c9e28af --- /dev/null +++ b/adr_viewer/templates/timeline/index.html @@ -0,0 +1,314 @@ + + + + + {{ config.heading }} + + + + + + + +

{{ config.heading }}

+ + + + + diff --git a/adr_viewer/templates/index.html b/adr_viewer/templates/vanilla/index.html similarity index 96% rename from adr_viewer/templates/index.html rename to adr_viewer/templates/vanilla/index.html index 6f5639b..07db540 100644 --- a/adr_viewer/templates/index.html +++ b/adr_viewer/templates/vanilla/index.html @@ -6,7 +6,7 @@ - ADR Viewer - {{ config.project_title }} + {{ config.heading }}