Mercurial > hg > MakeItSo
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()