Commits

Anonymous committed f592db5

Added docs/_temp/ directory and changed build process to support continuous builds.

Comments (0)

Files changed (2)

 *.pyc
 .DS_Store
 docs/_html
+docs/_tmp
 
 
 docroot = path(__file__).abspath().dirname()
-template_dir = docroot / '_templates'
-static_dir = docroot / '_static'
-html_dir = docroot / '_html'
 
 options(
     docroot = docroot,
-    template_dir = template_dir,
-    static_dir = static_dir,
-    html_dir = html_dir,
-    
+    template_dir = docroot / '_templates',
+    static_dir = docroot / '_static',
+    html_dir = docroot / '_html',
+    temp_dir = docroot / '_tmp',
+)
+
+options(
     markdown_file_extensions = ('.md', '.mdown', '.markdown'),
     markdown_extensions = (
         'abbr',
         'toc'),
     
     jinja2_env = jinja2.Environment(
-        loader=jinja2.FileSystemLoader([template_dir])),
+        loader=jinja2.FileSystemLoader([options.template_dir])),
 )
 
 
 @task
 def sync_static(options):
-    """Synchronize static files into docroot/_html."""
+    """Synchronize static files from docroot/_static -> docroot/_html."""
     
-    old_cwd = path.getcwd()
-    options.docroot.chdir()
     options.html_dir.makedirs()
     
-    try:
-        sh('rsync -vax --delete --ignore-errors '
-           '--exclude=".*" --exclude="_*" _static/ _html/')
-    finally:
-        old_cwd.chdir()
+    sh('rsync -vax --delete --ignore-errors '
+       '--exclude=".*" --exclude="_*" _static/ _html/', cwd=options.docroot)
+
 
 @task
-def clean(options):
-    """Clean old HTML from docroot/_html."""
+def sync_html(options):
+    """Synchronize built HTML from docroot/_tmp -> docroot/_html."""
     
-    options.html_dir.rmtree()
+    options.html_dir.makedirs()
+    sh('rsync -vax --delete --ignore-errors '
+       '--exclude=".*" --exclude="_*" _tmp/ _static/ _html/', cwd=options.docroot)
+
+
+@task
+def clean_temp(options):
+    """Clean old build HTML from docroot/_tmp."""
+    
+    if options.temp_dir.exists():
+        options.temp_dir.rmtree()
+    options.temp_dir.makedirs()
+
+@task
+def clean_html(options):
+    """Clean built HTML from docroot/_html."""
+    
+    if options.html_dir.exists():
+        options.html_dir.rmtree()
     options.html_dir.makedirs()
 
 
 @task
-@needs('clean', 'sync_static')
+@needs('clean_temp')
 def build(options):
     """Generate and output HTML into the `docroot/_html` directory."""
     
     doc_template = options.jinja2_env.get_template('document.html')
-    html_dir = options.docroot / '_html'
     
     for filename in options.docroot.walkfiles():
         rel_filename = options.docroot.relpathto(filename)
         if filename.ext not in options.markdown_file_extensions:
             continue
         
+        ## Content
         doc_text = read_from(filename)
         doc_html = render(doc_text)
         
+        ## Title
         if rel_filename == 'index.md':
             title = 'Index'
         else:
         if title is None:
             title = re.sub(r'[-_]+', ' ', rel_filename.basename()).title()
         
+        ## Breadcrumbs
         crumbs = rel_filename.splitall()
         if crumbs and crumbs[0] == '':
             del crumbs[0]
         if crumbs and crumbs[-1] == 'index.md':
             del crumbs[-1]
-        if crumbs and crumbs[-1].endswith('.md'):
-            crumbs[-1] = crumbs[-1][:-3]
+        if crumbs and path(crumbs[-1]).ext == '.md':
+            crumbs[-1] = path(crumbs[-1]).splitext()[0]
         
         full_html = doc_template.render({
             'title': title,
             'content': doc_html,
             'crumbs': crumbs})
-        output_filename = html_dir / rel_filename.splitext()[0] + '.html'
-        write_to(output_filename, data=full_html)
+        output_filename = options.temp_dir / rel_filename.splitext()[0] + '.html'
+        write_to(output_filename, data=full_html, relto=options.temp_dir)
+    
+    call_task('sync_html')
 
 
 @task
-@needs('build')
 @cmdopts([
+    ('build', 'b', 'Build the documentation before serving.'),
     ('port=', 'p', 'Specify which port to serve on (default 8008).'),
     ('interface=', 'i', 'Serve on a given interface (default 127.0.0.1).')])
 def serve(options):
     """Serve the documentation via HTTP."""
     
+    if options.get('build', False):
+        call_task('build')
+    
     server = DocServer(options)
     interface = options.get('interface', '127.0.0.1')
     port = int(options.get('port', 8008))
         fp.close()
 
 
-def write_to(filename, data=None, encoding='utf-8'):
+def write_to(filename, data=None, encoding='utf-8', relto=None):
     """Write the given data to a filename, using an encoding."""
     
     # Ensure the path to the file exists.
         finally:
             fp.close()
     
-    dry('Writing data to %r' % filename, write)
+    if relto is not None:
+        dry_path = path(relto).relpathto(filename)
+    else:
+        dry_path = filename
+    
+    dry('Writing data to "%s"' % dry_path, write)
 
 
 def render(text):
             raise ImportError('WebOb not found. Try `easy_install webob`.')
         
         self.options = options
-        self.docroot = options.html_dir
+        self.htroot = options.html_dir
     
     def __call__(self, environ, start_response):
-        """Call the application object (WSGI-compatible)."""
+        """Call the WSGI application object."""
         
         request = webob.Request(environ)
+        response = self.get_response(request)
+        return response(environ, start_response)
+    
+    def get_response(self, request):
         path = request.path_info.lstrip('/') or 'index.html'
         
-        if (self.docroot / path).isfile():
-            response = self.serve_file(self.docroot / path)
+        if (self.htroot / path).isfile():
+            return self.serve_file(self.htroot / path)
         
-        elif (self.docroot / (path + '.html')).isfile():
-            response = self.serve_file(self.docroot / (path + '.html'))
+        elif (self.htroot / (path + '.html')).isfile():
+            return self.serve_file(self.htroot / (path + '.html'))
         
-        elif (self.docroot / path / 'index.html').isfile():
+        elif (self.htroot / path / 'index.html').isfile():
             if path.endswith('/'):
-                response = self.serve_file(self.docroot / path / 'index.html')
+                return self.serve_file(self.htroot / path / 'index.html')
             else:
-                response = self.temp_redirect(path + '/')
+                return self.temp_redirect(path + '/')
         
-        elif (self.docroot / path).isdir():
+        elif (self.htroot / path).isdir():
             if path.endswith('/'):
-                response = self.list_directory(self.docroot / path)
+                return self.list_directory(self.htroot / path)
             else:
-                response = self.temp_redirect(path + '/')
+                return self.temp_redirect(path + '/')
         
         else:
-            response = self.not_found(path)
-        
-        return response(environ, start_response)
+            return self.not_found(path)
     
     def temp_redirect(self, location):
         return webob.Response(status=302, location=location)
         response = webob.Response()
         
         directory = path(directory)
-        rel_directory = self.docroot.relpathto(directory) / ''
+        rel_directory = self.htroot.relpathto(directory) / ''
         sub_dirs, files = [], []
         for filename in directory.listdir():
             rel_filename = directory.relpathto(filename)
-            if rel_filename[:1] in '_.':
+            if re.match(r'^[_\.]', rel_filename):
                 continue
             
             if filename.isdir():
+                # Directories are displayed with a trailing slash.
                 sub_dirs.append(rel_filename / '')
             elif filename.isfile():
                 files.append(rel_filename)
         title = 'Directory listing for ' + rel_directory
         content = content_template.render({
             'directory': rel_directory,
-            'sub_directories': sub_dirs,
-            'files': files
-        })
+            'sub_directories': sorted(sub_dirs),
+            'files': sorted(files)})
         
         response.content_type = 'application/xhtml+xml'
         response.unicode_body = document_template.render({
     
     def serve_forever(self, interface='127.0.0.1', port=8008):
         httpd = wsgiref.simple_server.make_server(interface, port, self)
-        httpd.serve_forever()
+        try:
+            httpd.serve_forever()
+        except KeyboardInterrupt:
+            sys.exit(0)