Source code for govlabstatic.cli

import sys
import os
import argparse
import inspect

import argh
import colorama
import staticjinja

from . import sass, webserver, watcher, testing

def init_colors():
    if sys.platform == 'win32':
        # Workaround for https://github.com/tartley/colorama/issues/48.
        if 'TERM' in os.environ:
            del os.environ['TERM']
    colorama.init()

[docs]class Manager(object): ''' Command-line interface manager for static site generation and associated tools. :param site_name: The name of the site, e.g. ``'GovLab Academy Website'`` or ``'www.mysite.com'``. :param sass_src_path: The path to SASS source, e.g. ``'sass/styles.scss'``. :param sass_dest_path: The path to compile SASS source to, e.g. ``'static/styles/styles.css'``. :param site: A :py:class:`staticjinja.Site` object representing the site to build. ''' def __init__(self, site_name, sass_src_path, sass_dest_path, site): self.site = site self.site_name = site_name self.sass_src_path = sass_src_path self.sass_dest_path = sass_dest_path #: An :py:class:`argparse.ArgumentParser` responsible for #: parsing command-line arguments. Feel free to add to this #: via :py:func:`argh.assembling.add_commands` to add new commands to your CLI. self.parser = argparse.ArgumentParser( description='Static site generator for %s' % site_name ) #: A :py:class:`govlabstatic.watcher.Watcher` instance used #: to watch directories for changes. self.watcher = watcher.Watcher() self.watcher.add_site(site) BuiltinCommands.add_to(self)
[docs] def run(self): ''' Runs the command-line interpreter. ''' init_colors() dirs = [self.site.outpath, os.path.dirname(self.sass_dest_path)] for dirname in dirs: if not os.path.exists(dirname): os.makedirs(dirname) argh.dispatch(self.parser)
def is_instance_method(obj): ''' Returns whether the given object is an instance method (and specifically *not* a class method). ''' return inspect.ismethod(obj) and not inspect.isclass(obj.__self__) class ManagerCommands(object): ''' This is just a simple class that makes it easy for commands to access their associated Manager instance. Commands are defined as public instance methods of a ManagerCommands subclass and can access their Manager via self.manager. ''' def __init__(self, manager): self.manager = manager @classmethod def add_to(cls, manager): ''' Add all public instance methods of this class to the given Manager as commands. ''' commands = cls(manager) argh.add_commands(manager.parser, [ getattr(commands, name) for name in dir(commands) if not name.startswith('_') and is_instance_method(getattr(commands, name)) ]) class BuiltinCommands(ManagerCommands): ''' These are built-in commands that come with any :py:class:`Manager` instance. ''' @argh.arg('--port', help='port to serve on') def runserver(self, port=7000): ''' Run development server. This builds the static site, and rebuilds necessary files whenever changes are detected. ''' manager = self.manager sass.start_watch(src_path=manager.sass_src_path, dest_path=manager.sass_dest_path) webserver.start(root_dir=manager.site.outpath, port=port) manager.site.render() manager.watcher.run() def build(self): ''' Build the static site. ''' print "Building SASS..." sass.compile(src_path=self.manager.sass_src_path, dest_path=self.manager.sass_dest_path) print "Generating site..." self.manager.site.render() print "Done." @argh.arg('--skip-build', help='Skip building the site', action='store_true') def test(self, skip_build=False): ''' Run test suite. Currently, this builds the site and checks links. ''' print "Running smoke test." if not skip_build: self.build() print "Checking links." if not testing.linkcheck_site(root_dir=self.manager.site.outpath): print "Errors found while checking links, aborting." sys.exit(1) print "Tests pass!"