hgbook

changeset 71:ddf533d41c09

Propagate errors correctly.
author Bryan O'Sullivan <bos@serpentine.com>
date Tue Aug 29 22:25:18 2006 -0700 (2006-08-29)
parents 365b41b6a15e
children 12df31afb4e1
files en/examples/run-example
line diff
     1.1 --- a/en/examples/run-example	Tue Aug 08 14:13:28 2006 -0700
     1.2 +++ b/en/examples/run-example	Tue Aug 29 22:25:18 2006 -0700
     1.3 @@ -27,7 +27,7 @@
     1.4  class example:
     1.5      shell = '/usr/bin/env bash'
     1.6      prompt = '__run_example_prompt__\n'
     1.7 -    pi_re = re.compile('#\$\s*(name):\s*(.*)$')
     1.8 +    pi_re = re.compile(r'#\$\s*(name):\s*(.*)$')
     1.9      
    1.10      def __init__(self, name):
    1.11          self.name = name
    1.12 @@ -99,55 +99,71 @@
    1.13                  os._exit(0)
    1.14          self.cfp = os.fdopen(fd, 'w+')
    1.15          try:
    1.16 -            # setup env and prompt
    1.17 -            self.sendreceive('source %s\n\n' % rcfile)
    1.18 -            for hunk in self.parse():
    1.19 -                # is this line a processing instruction?
    1.20 -                m = self.pi_re.match(hunk)
    1.21 -                if m:
    1.22 -                    pi, rest = m.groups()
    1.23 -                    if pi == 'name':
    1.24 -                        self.status('.')
    1.25 -                        out = rest
    1.26 -                        assert os.sep not in out
    1.27 -                        if out:
    1.28 -                            ofp = open('%s.%s.out' % (self.name, out), 'w')
    1.29 -                        else:
    1.30 -                            ofp = None
    1.31 -                elif hunk.strip():
    1.32 -                    # it's something we should execute
    1.33 -                    output = self.sendreceive(hunk)
    1.34 -                    if not ofp:
    1.35 -                        continue
    1.36 -                    # first, print the command we ran
    1.37 -                    if not hunk.startswith('#'):
    1.38 -                        nl = hunk.endswith('\n')
    1.39 -                        hunk = ('$ \\textbf{%s}' %
    1.40 -                                tex_escape(hunk.rstrip('\n')))
    1.41 -                        if nl: hunk += '\n'
    1.42 -                    ofp.write(hunk)
    1.43 -                    # then its output
    1.44 -                    ofp.write(tex_escape(output))
    1.45 -            self.status('\n')
    1.46 -            open(self.name + '.run', 'w')
    1.47 +            clean_exit = True
    1.48 +            try:
    1.49 +                # setup env and prompt
    1.50 +                self.sendreceive('source %s\n\n' % rcfile)
    1.51 +                for hunk in self.parse():
    1.52 +                    # is this line a processing instruction?
    1.53 +                    m = self.pi_re.match(hunk)
    1.54 +                    if m:
    1.55 +                        pi, rest = m.groups()
    1.56 +                        if pi == 'name':
    1.57 +                            self.status('.')
    1.58 +                            out = rest
    1.59 +                            assert os.sep not in out
    1.60 +                            if out:
    1.61 +                                ofp = open('%s.%s.out' % (self.name, out), 'w')
    1.62 +                            else:
    1.63 +                                ofp = None
    1.64 +                    elif hunk.strip():
    1.65 +                        # it's something we should execute
    1.66 +                        output = self.sendreceive(hunk)
    1.67 +                        if not ofp:
    1.68 +                            continue
    1.69 +                        # first, print the command we ran
    1.70 +                        if not hunk.startswith('#'):
    1.71 +                            nl = hunk.endswith('\n')
    1.72 +                            hunk = ('$ \\textbf{%s}' %
    1.73 +                                    tex_escape(hunk.rstrip('\n')))
    1.74 +                            if nl: hunk += '\n'
    1.75 +                        ofp.write(hunk)
    1.76 +                        # then its output
    1.77 +                        ofp.write(tex_escape(output))
    1.78 +                self.status('\n')
    1.79 +                open(self.name + '.run', 'w')
    1.80 +            except:
    1.81 +                clean_exit = False
    1.82 +                raise
    1.83          finally:
    1.84 -            try:
    1.85 -                output = self.sendreceive('exit\n')
    1.86 -                if ofp:
    1.87 -                    ofp.write(output)
    1.88 -                self.cfp.close()
    1.89 -            except IOError:
    1.90 -                pass
    1.91 +            if clean_exit:
    1.92 +                try:
    1.93 +                    output = self.sendreceive('exit\n')
    1.94 +                    if ofp:
    1.95 +                        ofp.write(output)
    1.96 +                    self.cfp.close()
    1.97 +                except IOError:
    1.98 +                    pass
    1.99              os.kill(pid, signal.SIGTERM)
   1.100 -            os.wait()
   1.101 +            time.sleep(0.1)
   1.102 +            os.kill(pid, signal.SIGKILL)
   1.103 +            pid, rc = os.wait()
   1.104 +            if rc:
   1.105 +                if os.WIFEXITED(rc):
   1.106 +                    print >> sys.stderr, '(exit %s)' % os.WEXITSTATUS(rc)
   1.107 +                elif os.WIFSIGNALED(rc):
   1.108 +                    print >> sys.stderr, '(signal %s)' % os.WTERMSIG(rc)
   1.109              shutil.rmtree(tmpdir)
   1.110 +            return rc
   1.111  
   1.112  def main(path='.'):
   1.113      args = sys.argv[1:]
   1.114 +    errs = 0
   1.115      if args:
   1.116          for a in args:
   1.117 -            example(a).run()
   1.118 -        return
   1.119 +            if example(a).run():
   1.120 +                errs += 1
   1.121 +        return errs
   1.122      for name in os.listdir(path):
   1.123          if name == 'run-example' or name.startswith('.'): continue
   1.124          if name.endswith('.out') or name.endswith('~'): continue
   1.125 @@ -155,8 +171,10 @@
   1.126          pathname = os.path.join(path, name)
   1.127          st = os.lstat(pathname)
   1.128          if stat.S_ISREG(st.st_mode) and st.st_mode & 0111:
   1.129 -            example(pathname).run()
   1.130 +            if example(pathname).run():
   1.131 +                errs += 1
   1.132      print >> open(os.path.join(path, '.run'), 'w'), time.asctime()
   1.133 +    return errs
   1.134  
   1.135  if __name__ == '__main__':
   1.136 -    main()
   1.137 +    sys.exit(main())