diff makeitso/makeitso.py @ 5:f064be514e53

choose a better filename and remove some stuff from shebang
author Jeff Hammel <jhammel@mozilla.com>
date Wed, 10 Nov 2010 18:01:07 -0800
parents
children ac78e26cd568
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/makeitso/makeitso.py	Wed Nov 10 18:01:07 2010 -0800
@@ -0,0 +1,115 @@
+#!/usr/bin/env python
+"""
+filesystem template interpreter
+"""
+
+import os
+import re
+import subprocess
+import sys
+
+from optparse import OptionParser
+from tempita import Template
+
+shebang_re = '#!.*makeitso.*'
+shebang_re = re.compile(shebang_re)
+
+def call(command, *args, **kw):
+    code = subprocess.call(command, *args, **kw)
+    if code:
+        if isinstance(command, basestring):
+            cmdstr = command
+        else:
+            cmdstr = ' '.join(command)
+        raise SystemExit("Command `%s` exited with code %d" % (cmdstr, code))
+
+def get_missing(name_error):
+    """
+    This is a horrible hack because python doesn't do the proper thing
+    via eval and return the name of the variable;  instead, it just gives
+    you a message:
+    >>> try:
+    ...   eval('2*foo')
+    ... except Exception, e:
+    ...   pass
+    """
+    message = name_error.args[0]
+    varname = message.split("'")[1]
+    return varname
+
+def missing_variables(template, variables):
+    """return additional variables needed"""
+    vars = variables.copy()
+    missing = set([])
+    while True:
+        try:
+            template.substitute(**vars)
+            return missing
+        except NameError, e:
+            missed = get_missing(e)
+            missing.add(missed)
+            vars[missed] = ''
+    return missing
+
+def template_variables(template):
+    """return the variables needed for a template"""
+    return missing_variables(template, {})
+
+def read_variables(variables):
+    retval = {}
+    for i in variables:
+        print 'Enter %s: ' % i,
+        retval[i] = raw_input()
+    return retval
+        
+def substitute(content, fp=sys.stdout, variables=None):
+
+    # remove makeitso shebang if it has one
+    if shebang_re.match(content):
+        content = os.linesep.join(content.splitlines()[1:])
+
+    variables = variables or {}
+    template = Template(content)
+    missing = missing_variables(template, variables)
+    if missing:
+        # TODO: add a switch for interactive or not
+        variables.update(read_variables(missing))
+    print >> fp, template.substitute(**variables)
+
+
+def main(args=sys.argv[1:]):
+
+    # create option parser
+    usage = '%prog [options]'
+    parser = OptionParser(usage, description=__doc__)
+    parser.add_option('--variables', dest='variables', action='store_true',
+                      help='print the variables in a template')
+    options, args = parser.parse_args(args)
+
+    if options.variables:
+        variables = template_variables() # TODO: pass template
+        return
+
+    # template variables
+    variables = {}
+    _vars = []
+    _args = []
+    for arg in args:
+        if '=' in arg:
+            key, value = arg.split('=')
+            variables[key] = value
+        else:
+            _args.append(arg)
+    args = _args
+
+    # get the content
+    if args:
+        for arg in args:
+            content = file(arg).read()
+            substitute(content, variables=variables)
+    else:
+        content = sys.stdin.read()
+        substitute(content, variables=variables)
+        
+if __name__ == '__main__':
+    main()