hgbook

diff en/examples/run-example @ 579:80928ea6e7ae

Add the ability to include text files and have them XML-mangled.
author Bryan O'Sullivan <bos@serpentine.com>
date Tue Mar 17 21:47:12 2009 -0700 (2009-03-17)
parents 60ee738fdc0e
children 8366882f67f2
line diff
     1.1 --- a/en/examples/run-example	Mon Mar 09 23:32:15 2009 -0700
     1.2 +++ b/en/examples/run-example	Tue Mar 17 21:47:12 2009 -0700
     1.3 @@ -54,10 +54,83 @@
     1.4      return None
     1.5          
     1.6  def result_name(name):
     1.7 -    dirname, basename = os.path.split(name)
     1.8 -    return os.path.join(dirname, 'results', basename)
     1.9 +    return os.path.join('results', name.replace(os.sep, '-'))
    1.10  
    1.11  class example:
    1.12 +    entities = dict.fromkeys(l.rstrip() for l in open('auto-snippets.xml'))
    1.13 +
    1.14 +    def __init__(self, name, verbose, keep_change):
    1.15 +        self.name = name
    1.16 +        self.verbose = verbose
    1.17 +        self.keep_change = keep_change
    1.18 +
    1.19 +    def rename_output(self, base, ignore=[]):
    1.20 +        mangle_re = re.compile('(?:' + '|'.join(ignore) + ')')
    1.21 +        def mangle(s):
    1.22 +            return mangle_re.sub('', s)
    1.23 +        def matchfp(fp1, fp2):
    1.24 +            while True:
    1.25 +                s1 = mangle(fp1.readline())
    1.26 +                s2 = mangle(fp2.readline())
    1.27 +                if cmp(s1, s2):
    1.28 +                    break
    1.29 +                if not s1:
    1.30 +                    return True
    1.31 +            return False
    1.32 +
    1.33 +        oldname = result_name(base + '.out')
    1.34 +        tmpname = result_name(base + '.tmp')
    1.35 +        errname = result_name(base + '.err')
    1.36 +        errfp = open(errname, 'w+')
    1.37 +        for line in open(tmpname):
    1.38 +            errfp.write(mangle_re.sub('', line))
    1.39 +        os.rename(tmpname, result_name(base + '.lxo'))
    1.40 +        errfp.seek(0)
    1.41 +        try:
    1.42 +            oldfp = open(oldname)
    1.43 +        except IOError, err:
    1.44 +            if err.errno != errno.ENOENT:
    1.45 +                raise
    1.46 +            os.rename(errname, oldname)
    1.47 +            return False
    1.48 +        if matchfp(oldfp, errfp):
    1.49 +            os.unlink(errname)
    1.50 +            return False
    1.51 +        else:
    1.52 +            print >> sys.stderr, '\nOutput of %s has changed!' % baseq
    1.53 +            if self.keep_change:
    1.54 +                os.rename(errname, oldname)
    1.55 +                return False
    1.56 +            else:
    1.57 +                os.system('diff -u %s %s 1>&2' % (oldname, errname))
    1.58 +            return True
    1.59 +
    1.60 +def wopen(name):
    1.61 +    path = os.path.dirname(name)
    1.62 +    if path:
    1.63 +        try:
    1.64 +            os.makedirs(path)
    1.65 +        except OSError, err:
    1.66 +            if err.errno != errno.EEXIST:
    1.67 +                raise
    1.68 +    return open(name, 'w')
    1.69 +
    1.70 +class static_example(example):
    1.71 +    def run(self):
    1.72 +        s = open(self.name).read().rstrip()
    1.73 +        s = s.replace('&', '&amp;').replace('<', '&lt;').replace('>', '&gt;')
    1.74 +        ofp = wopen(result_name(self.name + '.tmp'))
    1.75 +        ofp.write('<programlisting>')
    1.76 +        ofp.write(s)
    1.77 +        ofp.write('</programlisting>\n')
    1.78 +        ofp.close()
    1.79 +        self.rename_output(self.name)
    1.80 +        norm = self.name.replace(os.sep, '-')
    1.81 +        example.entities[
    1.82 +            '<!ENTITY %s SYSTEM "results/%s.out">' % (norm, norm)] = 1
    1.83 +
    1.84 +
    1.85 +class shell_example(example):
    1.86      shell = '/usr/bin/env bash'
    1.87      ps1 = '__run_example_ps1__ '
    1.88      ps2 = '__run_example_ps2__ '
    1.89 @@ -65,12 +138,8 @@
    1.90      
    1.91      timeout = 10
    1.92  
    1.93 -    entities = dict.fromkeys(l.rstrip() for l in open('auto-snippets.xml'))
    1.94 -
    1.95      def __init__(self, name, verbose, keep_change):
    1.96 -        self.name = name
    1.97 -        self.verbose = verbose
    1.98 -        self.keep_change = keep_change
    1.99 +        example.__init__(self, name, verbose, keep_change)
   1.100          self.poll = select.poll()
   1.101  
   1.102      def parse(self):
   1.103 @@ -153,12 +222,12 @@
   1.104          maybe_unlink(self.name + '.run')
   1.105  
   1.106          rcfile = os.path.join(tmpdir, '.hgrc')
   1.107 -        rcfp = open(rcfile, 'w')
   1.108 +        rcfp = wopen(rcfile)
   1.109          print >> rcfp, '[ui]'
   1.110          print >> rcfp, "username = Bryan O'Sullivan <bos@serpentine.com>"
   1.111          
   1.112          rcfile = os.path.join(tmpdir, '.bashrc')
   1.113 -        rcfp = open(rcfile, 'w')
   1.114 +        rcfp = wopen(rcfile)
   1.115          print >> rcfp, 'PS1="%s"' % self.ps1
   1.116          print >> rcfp, 'PS2="%s"' % self.ps2
   1.117          print >> rcfp, 'unset HISTFILE'
   1.118 @@ -248,8 +317,7 @@
   1.119                                      'SYSTEM "results/%s.out">'
   1.120                                      % (norm, norm)] = 1
   1.121                                  read_hint = ofp_basename + ' '
   1.122 -                                ofp = open(result_name(ofp_basename + '.tmp'),
   1.123 -                                           'w')
   1.124 +                                ofp = wopen(result_name(ofp_basename + '.tmp'))
   1.125                                  ofp.write('<screen>')
   1.126                              else:
   1.127                                  ofp = None
   1.128 @@ -297,52 +365,11 @@
   1.129                      elif os.WIFSIGNALED(rc):
   1.130                          print >> sys.stderr, '(signal %s)' % os.WTERMSIG(rc)
   1.131                  else:
   1.132 -                    open(result_name(self.name + '.run'), 'w')
   1.133 +                    wopen(result_name(self.name + '.run'))
   1.134                  return err
   1.135          finally:
   1.136              shutil.rmtree(tmpdir)
   1.137  
   1.138 -    def rename_output(self, base, ignore):
   1.139 -        mangle_re = re.compile('(?:' + '|'.join(ignore) + ')')
   1.140 -        def mangle(s):
   1.141 -            return mangle_re.sub('', s)
   1.142 -        def matchfp(fp1, fp2):
   1.143 -            while True:
   1.144 -                s1 = mangle(fp1.readline())
   1.145 -                s2 = mangle(fp2.readline())
   1.146 -                if cmp(s1, s2):
   1.147 -                    break
   1.148 -                if not s1:
   1.149 -                    return True
   1.150 -            return False
   1.151 -
   1.152 -        oldname = result_name(base + '.out')
   1.153 -        tmpname = result_name(base + '.tmp')
   1.154 -        errname = result_name(base + '.err')
   1.155 -        errfp = open(errname, 'w+')
   1.156 -        for line in open(tmpname):
   1.157 -            errfp.write(mangle_re.sub('', line))
   1.158 -        os.rename(tmpname, result_name(base + '.lxo'))
   1.159 -        errfp.seek(0)
   1.160 -        try:
   1.161 -            oldfp = open(oldname)
   1.162 -        except IOError, err:
   1.163 -            if err.errno != errno.ENOENT:
   1.164 -                raise
   1.165 -            os.rename(errname, oldname)
   1.166 -            return False
   1.167 -        if matchfp(oldfp, errfp):
   1.168 -            os.unlink(errname)
   1.169 -            return False
   1.170 -        else:
   1.171 -            print >> sys.stderr, '\nOutput of %s has changed!' % base
   1.172 -            if self.keep_change:
   1.173 -                os.rename(errname, oldname)
   1.174 -                return False
   1.175 -            else:
   1.176 -                os.system('diff -u %s %s 1>&2' % (oldname, errname))
   1.177 -            return True
   1.178 -
   1.179  def print_help(exit, msg=None):
   1.180      if msg:
   1.181          print >> sys.stderr, 'Error:', msg
   1.182 @@ -383,18 +410,20 @@
   1.183                  print >> sys.stderr, '%s: %s' % (a, err.strerror)
   1.184                  errs += 1
   1.185                  continue
   1.186 -            if stat.S_ISREG(st.st_mode) and st.st_mode & 0111:
   1.187 -                if example(a, verbose, keep_change).run():
   1.188 -                    errs += 1
   1.189 +            if stat.S_ISREG(st.st_mode):
   1.190 +                if st.st_mode & 0111:
   1.191 +                    if shell_example(a, verbose, keep_change).run():
   1.192 +                        errs += 1
   1.193 +                elif a.endswith('.lst'):
   1.194 +                    static_example(a, verbose, keep_change).run()
   1.195              else:
   1.196                  print >> sys.stderr, '%s: not a file, or not executable' % a
   1.197                  errs += 1
   1.198      elif run_all:
   1.199 -        names = os.listdir(path)
   1.200 +        names = glob.glob("*") + glob.glob("app*/*") + glob.glob("ch*/*")
   1.201          names.sort()
   1.202          for name in names:
   1.203 -            if name == 'run-example' or name.startswith('.'): continue
   1.204 -            if name.endswith('~'): continue
   1.205 +            if name == 'run-example' or name.endswith('~'): continue
   1.206              pathname = os.path.join(path, name)
   1.207              try:
   1.208                  st = os.lstat(pathname)
   1.209 @@ -403,14 +432,17 @@
   1.210                  if err.errno != errno.ENOENT:
   1.211                      raise
   1.212                  continue
   1.213 -            if stat.S_ISREG(st.st_mode) and st.st_mode & 0111:
   1.214 -                if example(pathname, verbose, keep_change).run():
   1.215 -                    errs += 1
   1.216 -        print >> open(os.path.join(path, '.run'), 'w'), time.asctime()
   1.217 +            if stat.S_ISREG(st.st_mode):
   1.218 +                if st.st_mode & 0111:
   1.219 +                    if shell_example(pathname, verbose, keep_change).run():
   1.220 +                        errs += 1
   1.221 +                elif pathname.endswith('.lst'):
   1.222 +                    static_example(pathname, verbose, keep_change).run()
   1.223 +        print >> wopen(os.path.join(path, '.run')), time.asctime()
   1.224      else:
   1.225          print_help(1, msg='no test names given, and --all not provided')
   1.226  
   1.227 -    fp = open('auto-snippets.xml', 'w')
   1.228 +    fp = wopen('auto-snippets.xml')
   1.229      for key in sorted(example.entities.iterkeys()):
   1.230          print >> fp, key
   1.231      fp.close()