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('&', '&').replace('<', '<').replace('>', '>') 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()