From 076e375976b0c3c87db43daaf30b43b1aea72d28 Mon Sep 17 00:00:00 2001 From: Bruno Bord Date: Sat, 30 Apr 2016 22:52:19 +0200 Subject: [PATCH] improved builder using a builder class --- CHANGELOG.md | 3 +- build.py | 242 ++++++++++++++++++++++++++++++--------------------- tox.ini | 1 + 3 files changed, 146 insertions(+), 100 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6891598..fad33a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,8 +2,9 @@ ## master (unreleased) -* added the automatic version number on the built HTML page footer (#9) +* added the automatic version number on the built HTML page footer (#9). * small typo fixes in english text. +* Builder refactor (#13). ## 1.0.0 (2016-04-22) diff --git a/build.py b/build.py index 2591f4f..af1e8da 100644 --- a/build.py +++ b/build.py @@ -6,124 +6,168 @@ import shutil import os from string import Template -from os.path import join +from os.path import join, abspath +from cached_property import cached_property import markdown from mdx_gfm import GithubFlavoredMarkdownExtension -import yaml from shell import shell +import yaml -if __name__ == '__main__': +class Builder(object): + + exceptions = ('.tox', '.git', 'build', 'static', 'templates') + + def __init__(self): + self.build_path = abspath('build') + self.languages = [] + self.meta = {} + + @cached_property + def static_path(self): + return join(self.build_path, 'static') + + @cached_property + def version(self): + return shell('git describe --tags --abbrev=0').output(raw=True).strip() - version = shell('git describe --tags --abbrev=0').output(raw=True).strip() - git_version = shell('git describe --tags').output(raw=True).strip() + @cached_property + def git_version(self): + return shell('git describe --tags').output(raw=True).strip() - build_path = 'build' - static_path = join(build_path, 'static') - with open(join('templates', 'base.html')) as fd: - template_string = fd.read() - template = Template(template_string) + @cached_property + def dir_list(self): + dir_list = [d for d in os.listdir('.') if d not in self.exceptions] + dir_list = filter(lambda x: os.path.isdir(x), dir_list) + return dir_list - exceptions = ['.tox', '.git', 'build', 'static', 'templates'] - dir_list = [d for d in os.listdir('.') if d not in exceptions] - dir_list = filter(lambda x: os.path.isdir(x), dir_list) + def get_template(self, path): + "Transform a path into a template" + with open(path) as fd: + template_string = fd.read() + template = Template(template_string) + return template - if not os.path.isdir(build_path): - os.makedirs(build_path) - if os.path.isdir(static_path): - shutil.rmtree(static_path) - shutil.copytree('static', static_path) + def convert_md_source(self, source): + "Convert Markdown content into HTML" + html = markdown.markdown( + source, + extensions=[GithubFlavoredMarkdownExtension()] + ) + return html + + def convert_md(self, filepath): + "Convert a Markdown file into HTML" + with open(filepath) as fd: + source = fd.read() + return self.convert_md_source(source) - languages = [] - meta = {} + def mkdir(self, path): + "Silent make directories" + if not os.path.isdir(path): + os.makedirs(path) + + def write_html(self, target_filepath, body, title, static='static'): + "Write HTML page (body & title) in the target_filepath" + html = self.main_template.substitute( + body=body, + title=title, + static=static, + version=self.version, + git_version=self.git_version, + ) + with open(target_filepath, 'w') as fd: + fd.write(html) - for directory in dir_list: + def build_dir(self, directory): + "Build the directory" filepath = join(directory, 'the-black-hack.md') if os.path.exists(filepath): - languages.append(directory) - with open(filepath) as fd: - source = fd.read() - body = markdown.markdown( - source, - extensions=[GithubFlavoredMarkdownExtension()] - ) - html = template.substitute( - body=body, - title=directory, - static='../static', - version=version, - git_version=git_version, - ) - target_dir = join(build_path, directory) - if not os.path.isdir(target_dir): - os.makedirs(target_dir) + self.languages.append(directory) + body = self.convert_md(filepath) + target_dir = join(self.build_path, directory) + self.mkdir(target_dir) target_filepath = join(target_dir, 'index.html') - with open(target_filepath, 'w') as fd: - fd.write(html) + self.write_html( + target_filepath, + body, + directory, + "../static", + ) + + def update_meta(self, directory): + "Update meta information dictionary" # Search for meta filepath = join(directory, 'meta.yaml') if os.path.exists(filepath): with open(filepath) as fd: content = fd.read() - meta[directory] = yaml.load(content) - - # Homepage - with open(join('index.md')) as fd: - template_string = fd.read() - homepage_md = Template(template_string) - - # Build text list - text_list = [] - text_list.append('') - for language in languages: - label = language - author = None - if language in meta: - label = meta[language].get('label', label) - author = meta[language].get('author', None) - item = '* [{label}]({language}/)'.format( - label=label, - language=language + self.meta[directory] = yaml.load(content) + + def build_homepage_text_list(self): + "Build the full text list for the homepage" + # Build text list + text_list = [] + text_list.append('') + for language in self.languages: + label = language + author = None + if language in self.meta: + label = self.meta[language].get('label', label) + author = self.meta[language].get('author', None) + item = '* [{label}]({language}/)'.format( + label=label, + language=language + ) + + # Add optional author + if author: + item = '{}, by {}'.format(item, author) + text_list.append(item) + + text_list.append('') + return text_list + + def build_homepage(self): + "Build the Home page" + homepage_md = self.get_template('index.md') + text_list = self.build_homepage_text_list() + # Build generated body using text_list + body_md = homepage_md.substitute(text_list='\n'.join(text_list)) + body_html = self.convert_md_source(body_md) + # Build html page content + self.write_html( + join(self.build_path, 'index.html'), + body_html, + "Home" ) - # Add optional author - if author: - item = '{}, by {}'.format(item, author) - text_list.append(item) - - text_list.append('') - # Build generated body using text_list - body_md = homepage_md.substitute(text_list='\n'.join(text_list)) - body_html = markdown.markdown( - body_md, - extensions=[GithubFlavoredMarkdownExtension()] - ) - # Build html page content - html = template.substitute( - body=body_html, - title="Home", - static='static', - version=version, - git_version=git_version, - ) - with open(join(build_path, 'index.html'), 'w') as fd: - fd.write(html) - - # Build License page - with open('LICENSE') as fd: - license_md = fd.read() - license_html = markdown.markdown( - license_md, - extensions=[GithubFlavoredMarkdownExtension()] - ) - # Build html page content - html = template.substitute( - body=license_html, - title="Open Gaming License", - static='static', - version=version, - git_version=git_version, - ) - with open(join(build_path, 'license.html'), 'w') as fd: - fd.write(html) + def build_license(self): + "Build License page" + license_html = self.convert_md('LICENSE') + self.write_html( + join(self.build_path, 'license.html'), + license_html, + "Open Gaming License", + ) + + def build(self): + "Build main method" + self.mkdir(self.build_path) + if os.path.isdir(self.static_path): + shutil.rmtree(self.static_path) + shutil.copytree('static', self.static_path) + + self.main_template = self.get_template(join('templates', 'base.html')) + + for directory in self.dir_list: + self.build_dir(directory) + self.update_meta(directory) + self.build_homepage() + self.build_license() + +if __name__ == '__main__': + + builder = Builder() + builder.build() diff --git a/tox.ini b/tox.ini index f7131f5..c9fe498 100644 --- a/tox.ini +++ b/tox.ini @@ -8,6 +8,7 @@ deps = py-gfm PyYAML shell + cached-property # For debuggin purposes ipdb commands =