Mercurial > hgbook
comparison en/examples/run-example @ 71:ddf533d41c09
Propagate errors correctly.
author | Bryan O'Sullivan <bos@serpentine.com> |
---|---|
date | Tue, 29 Aug 2006 22:25:18 -0700 |
parents | 365b41b6a15e |
children | 12df31afb4e1 |
comparison
equal
deleted
inserted
replaced
70:365b41b6a15e | 71:ddf533d41c09 |
---|---|
25 return s | 25 return s |
26 | 26 |
27 class example: | 27 class example: |
28 shell = '/usr/bin/env bash' | 28 shell = '/usr/bin/env bash' |
29 prompt = '__run_example_prompt__\n' | 29 prompt = '__run_example_prompt__\n' |
30 pi_re = re.compile('#\$\s*(name):\s*(.*)$') | 30 pi_re = re.compile(r'#\$\s*(name):\s*(.*)$') |
31 | 31 |
32 def __init__(self, name): | 32 def __init__(self, name): |
33 self.name = name | 33 self.name = name |
34 | 34 |
35 def parse(self): | 35 def parse(self): |
97 print >> sys.stderr, '%s: %s' % (cmdline[0], err.strerror) | 97 print >> sys.stderr, '%s: %s' % (cmdline[0], err.strerror) |
98 sys.stderr.flush() | 98 sys.stderr.flush() |
99 os._exit(0) | 99 os._exit(0) |
100 self.cfp = os.fdopen(fd, 'w+') | 100 self.cfp = os.fdopen(fd, 'w+') |
101 try: | 101 try: |
102 # setup env and prompt | 102 clean_exit = True |
103 self.sendreceive('source %s\n\n' % rcfile) | 103 try: |
104 for hunk in self.parse(): | 104 # setup env and prompt |
105 # is this line a processing instruction? | 105 self.sendreceive('source %s\n\n' % rcfile) |
106 m = self.pi_re.match(hunk) | 106 for hunk in self.parse(): |
107 if m: | 107 # is this line a processing instruction? |
108 pi, rest = m.groups() | 108 m = self.pi_re.match(hunk) |
109 if pi == 'name': | 109 if m: |
110 self.status('.') | 110 pi, rest = m.groups() |
111 out = rest | 111 if pi == 'name': |
112 assert os.sep not in out | 112 self.status('.') |
113 if out: | 113 out = rest |
114 ofp = open('%s.%s.out' % (self.name, out), 'w') | 114 assert os.sep not in out |
115 else: | 115 if out: |
116 ofp = None | 116 ofp = open('%s.%s.out' % (self.name, out), 'w') |
117 elif hunk.strip(): | 117 else: |
118 # it's something we should execute | 118 ofp = None |
119 output = self.sendreceive(hunk) | 119 elif hunk.strip(): |
120 if not ofp: | 120 # it's something we should execute |
121 continue | 121 output = self.sendreceive(hunk) |
122 # first, print the command we ran | 122 if not ofp: |
123 if not hunk.startswith('#'): | 123 continue |
124 nl = hunk.endswith('\n') | 124 # first, print the command we ran |
125 hunk = ('$ \\textbf{%s}' % | 125 if not hunk.startswith('#'): |
126 tex_escape(hunk.rstrip('\n'))) | 126 nl = hunk.endswith('\n') |
127 if nl: hunk += '\n' | 127 hunk = ('$ \\textbf{%s}' % |
128 ofp.write(hunk) | 128 tex_escape(hunk.rstrip('\n'))) |
129 # then its output | 129 if nl: hunk += '\n' |
130 ofp.write(tex_escape(output)) | 130 ofp.write(hunk) |
131 self.status('\n') | 131 # then its output |
132 open(self.name + '.run', 'w') | 132 ofp.write(tex_escape(output)) |
133 self.status('\n') | |
134 open(self.name + '.run', 'w') | |
135 except: | |
136 clean_exit = False | |
137 raise | |
133 finally: | 138 finally: |
134 try: | 139 if clean_exit: |
135 output = self.sendreceive('exit\n') | 140 try: |
136 if ofp: | 141 output = self.sendreceive('exit\n') |
137 ofp.write(output) | 142 if ofp: |
138 self.cfp.close() | 143 ofp.write(output) |
139 except IOError: | 144 self.cfp.close() |
140 pass | 145 except IOError: |
146 pass | |
141 os.kill(pid, signal.SIGTERM) | 147 os.kill(pid, signal.SIGTERM) |
142 os.wait() | 148 time.sleep(0.1) |
149 os.kill(pid, signal.SIGKILL) | |
150 pid, rc = os.wait() | |
151 if rc: | |
152 if os.WIFEXITED(rc): | |
153 print >> sys.stderr, '(exit %s)' % os.WEXITSTATUS(rc) | |
154 elif os.WIFSIGNALED(rc): | |
155 print >> sys.stderr, '(signal %s)' % os.WTERMSIG(rc) | |
143 shutil.rmtree(tmpdir) | 156 shutil.rmtree(tmpdir) |
157 return rc | |
144 | 158 |
145 def main(path='.'): | 159 def main(path='.'): |
146 args = sys.argv[1:] | 160 args = sys.argv[1:] |
161 errs = 0 | |
147 if args: | 162 if args: |
148 for a in args: | 163 for a in args: |
149 example(a).run() | 164 if example(a).run(): |
150 return | 165 errs += 1 |
166 return errs | |
151 for name in os.listdir(path): | 167 for name in os.listdir(path): |
152 if name == 'run-example' or name.startswith('.'): continue | 168 if name == 'run-example' or name.startswith('.'): continue |
153 if name.endswith('.out') or name.endswith('~'): continue | 169 if name.endswith('.out') or name.endswith('~'): continue |
154 if name.endswith('.run'): continue | 170 if name.endswith('.run'): continue |
155 pathname = os.path.join(path, name) | 171 pathname = os.path.join(path, name) |
156 st = os.lstat(pathname) | 172 st = os.lstat(pathname) |
157 if stat.S_ISREG(st.st_mode) and st.st_mode & 0111: | 173 if stat.S_ISREG(st.st_mode) and st.st_mode & 0111: |
158 example(pathname).run() | 174 if example(pathname).run(): |
175 errs += 1 | |
159 print >> open(os.path.join(path, '.run'), 'w'), time.asctime() | 176 print >> open(os.path.join(path, '.run'), 'w'), time.asctime() |
177 return errs | |
160 | 178 |
161 if __name__ == '__main__': | 179 if __name__ == '__main__': |
162 main() | 180 sys.exit(main()) |