#!/usr/bin/env python import sys import os import shutil import glob import re # Build script for the AWS Flow Framework for Ruby samples and recipes. # # Relies on the presence of both rst2html and pandoc. # # This script iterates over the ``Recipes`` and ``Samples`` directories. For # each, it performs the following actions: # # 1. Process each ``.rst`` file, which is named exactly as *dirname*.rst for # each of the directories in the recipes or samples. # # 2. Descriptions for each recipe/sample are in the includes directory, and # are named as *dirname*_*sample*_desc.rst. These descriptions are used in # both the sample readme and in the master README that sits at the top of the # heirarchy. The includes directory also contains any other bits of text # shared by the various READMEs. # # 3. The files are first processed from RST to HTML, and then from HTML to # Markdown. This overcomes the inability of GitHub to process RST # directives (and the lack of these in Markdown in the first place), yet # takes advantage of the very nice Markdown rendering on GitHub. You want # to have your cake and to eat it too, you say? Yes! # # BUILD PARAMETERS # BUILD_DIR = 'build' INCLUDES_DIR = 'includes' DIRS_TO_BUILD = ['Samples', 'Recipes'] # # OTHER CONSTANTS # DESC_FILE_NAME = 'all_descs.rst' # # FUNCTIONS # def remove_literals(filename): """Remove the {.literal-block} and {.docutils .literal} tags that are added to code fragments.""" f = open(filename) contents = f.read() f.close() contents = re.sub(' {\.literal-block}', '', contents) contents = re.sub('{\.docutils.*?}', '', contents) contents = re.sub('{\.docutils\s*$', '', contents, flags=re.MULTILINE) # catches a line-break. contents = re.sub('^\s*\.literal}', '', contents, flags=re.MULTILINE) # gets the other side of the line break. f = open(filename, "w") f.write(contents) f.close() def rst2md(in_path, out_path): """Convert the .rst file on in_path to a markdown file on out_path""" os.system('rst2html.py --no-doc-title %s >%s/tmp.html' % (in_path, BUILD_DIR)) os.system('pandoc -t markdown %s/tmp.html -o %s' % (BUILD_DIR, out_path)) remove_literals(out_path) def build_readmes(path, BUILD_DIR): """Build readmes within a given path. Returns True if the build was successful; False otherwise. """ if not os.path.isdir(path): print "Invalid path: '%s'" % path return False print "Building READMEs in %s..." % path # Gather all of the .rst files files_to_process = glob.glob("%s/*.rst" % path) if len(files_to_process) < 1: print " *** none found ***" return True all_desc_file = open("%s/%s" % (BUILD_DIR, DESC_FILE_NAME), "a+") # append instead of write # Write the title of this section (named after the path) all_desc_file.write('%s\n%s\n\n' % (path, '~' * len(path))) directory_desc_file = open("%s/%s_descs.rst" % (BUILD_DIR, path), "w+") for filename in files_to_process: # Make README.md for each sample (basename, extension) = os.path.splitext(os.path.basename(filename)) print " * %s" % basename out_path = '../%s/%s/README.md' % (path, basename) rst2md(filename, out_path) # Add this entry to the descriptions file: # 1. write the title title_text = '%s\n%s\n\n' % (basename, '.' * len(basename)) directory_desc_file.write(title_text) all_desc_file.write(title_text) # 2. write the description desc_text = '.. include:: ../%s/%s_%s_desc.rst\n\n' % (INCLUDES_DIR, path, basename) directory_desc_file.write(desc_text) all_desc_file.write(desc_text) # 3. link to the sample directory directory_desc_file.write('Code + info: `%s <%s/>`_\n\n' % (basename, basename)) all_desc_file.write('Code + info: `%s/%s <%s/%s/>`_\n\n' % (path, basename, path, basename)) directory_desc_file.close() all_desc_file.close() # make the directory-level README. print " * README.md" in_path = "%s/%s.rst" % (INCLUDES_DIR, path) out_path = "../%s/README.md" % path rst2md(in_path, out_path) # so far, so good, eh? return True # # THE SCRIPT # print "Preparing build..." # remove old docs if os.path.exists(BUILD_DIR): if os.path.isdir(BUILD_DIR): shutil.rmtree(BUILD_DIR) else: print "Error: %s exists, but is a regular file. Please remove or rename it!" sys.exit() # make new docs os.makedirs(BUILD_DIR) result = False for subdir in DIRS_TO_BUILD: result = build_readmes(subdir, BUILD_DIR) if result is False: break if result is True: # generate the master README print "Building master README.md" rst2md('%s/BASE_README.rst' % INCLUDES_DIR, '../README.md') # That's all, folks! print "Finished!" sys.exit()