Mercurial > hg > MakeItSo
comparison 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 |
comparison
equal
deleted
inserted
replaced
4:08a50935e941 | 5:f064be514e53 |
---|---|
1 #!/usr/bin/env python | |
2 """ | |
3 filesystem template interpreter | |
4 """ | |
5 | |
6 import os | |
7 import re | |
8 import subprocess | |
9 import sys | |
10 | |
11 from optparse import OptionParser | |
12 from tempita import Template | |
13 | |
14 shebang_re = '#!.*makeitso.*' | |
15 shebang_re = re.compile(shebang_re) | |
16 | |
17 def call(command, *args, **kw): | |
18 code = subprocess.call(command, *args, **kw) | |
19 if code: | |
20 if isinstance(command, basestring): | |
21 cmdstr = command | |
22 else: | |
23 cmdstr = ' '.join(command) | |
24 raise SystemExit("Command `%s` exited with code %d" % (cmdstr, code)) | |
25 | |
26 def get_missing(name_error): | |
27 """ | |
28 This is a horrible hack because python doesn't do the proper thing | |
29 via eval and return the name of the variable; instead, it just gives | |
30 you a message: | |
31 >>> try: | |
32 ... eval('2*foo') | |
33 ... except Exception, e: | |
34 ... pass | |
35 """ | |
36 message = name_error.args[0] | |
37 varname = message.split("'")[1] | |
38 return varname | |
39 | |
40 def missing_variables(template, variables): | |
41 """return additional variables needed""" | |
42 vars = variables.copy() | |
43 missing = set([]) | |
44 while True: | |
45 try: | |
46 template.substitute(**vars) | |
47 return missing | |
48 except NameError, e: | |
49 missed = get_missing(e) | |
50 missing.add(missed) | |
51 vars[missed] = '' | |
52 return missing | |
53 | |
54 def template_variables(template): | |
55 """return the variables needed for a template""" | |
56 return missing_variables(template, {}) | |
57 | |
58 def read_variables(variables): | |
59 retval = {} | |
60 for i in variables: | |
61 print 'Enter %s: ' % i, | |
62 retval[i] = raw_input() | |
63 return retval | |
64 | |
65 def substitute(content, fp=sys.stdout, variables=None): | |
66 | |
67 # remove makeitso shebang if it has one | |
68 if shebang_re.match(content): | |
69 content = os.linesep.join(content.splitlines()[1:]) | |
70 | |
71 variables = variables or {} | |
72 template = Template(content) | |
73 missing = missing_variables(template, variables) | |
74 if missing: | |
75 # TODO: add a switch for interactive or not | |
76 variables.update(read_variables(missing)) | |
77 print >> fp, template.substitute(**variables) | |
78 | |
79 | |
80 def main(args=sys.argv[1:]): | |
81 | |
82 # create option parser | |
83 usage = '%prog [options]' | |
84 parser = OptionParser(usage, description=__doc__) | |
85 parser.add_option('--variables', dest='variables', action='store_true', | |
86 help='print the variables in a template') | |
87 options, args = parser.parse_args(args) | |
88 | |
89 if options.variables: | |
90 variables = template_variables() # TODO: pass template | |
91 return | |
92 | |
93 # template variables | |
94 variables = {} | |
95 _vars = [] | |
96 _args = [] | |
97 for arg in args: | |
98 if '=' in arg: | |
99 key, value = arg.split('=') | |
100 variables[key] = value | |
101 else: | |
102 _args.append(arg) | |
103 args = _args | |
104 | |
105 # get the content | |
106 if args: | |
107 for arg in args: | |
108 content = file(arg).read() | |
109 substitute(content, variables=variables) | |
110 else: | |
111 content = sys.stdin.read() | |
112 substitute(content, variables=variables) | |
113 | |
114 if __name__ == '__main__': | |
115 main() |