Mercurial > hgbook
diff en/examples/run-example @ 679:80928ea6e7ae
Add the ability to include text files and have them XML-mangled.
author | Bryan O'Sullivan <bos@serpentine.com> |
---|---|
date | Tue, 17 Mar 2009 21:47:12 -0700 |
parents | 60ee738fdc0e |
children | 8366882f67f2 |
line wrap: on
line diff
--- a/en/examples/run-example Tue Mar 10 22:40:47 2009 -0700 +++ b/en/examples/run-example Tue Mar 17 21:47:12 2009 -0700 @@ -54,10 +54,83 @@ return None def result_name(name): - dirname, basename = os.path.split(name) - return os.path.join(dirname, 'results', basename) + return os.path.join('results', name.replace(os.sep, '-')) class example: + entities = dict.fromkeys(l.rstrip() for l in open('auto-snippets.xml')) + + def __init__(self, name, verbose, keep_change): + self.name = name + self.verbose = verbose + self.keep_change = keep_change + + def rename_output(self, base, ignore=[]): + mangle_re = re.compile('(?:' + '|'.join(ignore) + ')') + def mangle(s): + return mangle_re.sub('', s) + def matchfp(fp1, fp2): + while True: + s1 = mangle(fp1.readline()) + s2 = mangle(fp2.readline()) + if cmp(s1, s2): + break + if not s1: + return True + return False + + oldname = result_name(base + '.out') + tmpname = result_name(base + '.tmp') + errname = result_name(base + '.err') + errfp = open(errname, 'w+') + for line in open(tmpname): + errfp.write(mangle_re.sub('', line)) + os.rename(tmpname, result_name(base + '.lxo')) + errfp.seek(0) + try: + oldfp = open(oldname) + except IOError, err: + if err.errno != errno.ENOENT: + raise + os.rename(errname, oldname) + return False + if matchfp(oldfp, errfp): + os.unlink(errname) + return False + else: + print >> sys.stderr, '\nOutput of %s has changed!' % baseq + if self.keep_change: + os.rename(errname, oldname) + return False + else: + os.system('diff -u %s %s 1>&2' % (oldname, errname)) + return True + +def wopen(name): + path = os.path.dirname(name) + if path: + try: + os.makedirs(path) + except OSError, err: + if err.errno != errno.EEXIST: + raise + return open(name, 'w') + +class static_example(example): + def run(self): + s = open(self.name).read().rstrip() + s = s.replace('&', '&').replace('<', '<').replace('>', '>') + ofp = wopen(result_name(self.name + '.tmp')) + ofp.write('<programlisting>') + ofp.write(s) + ofp.write('</programlisting>\n') + ofp.close() + self.rename_output(self.name) + norm = self.name.replace(os.sep, '-') + example.entities[ + '<!ENTITY %s SYSTEM "results/%s.out">' % (norm, norm)] = 1 + + +class shell_example(example): shell = '/usr/bin/env bash' ps1 = '__run_example_ps1__ ' ps2 = '__run_example_ps2__ ' @@ -65,12 +138,8 @@ timeout = 10 - entities = dict.fromkeys(l.rstrip() for l in open('auto-snippets.xml')) - def __init__(self, name, verbose, keep_change): - self.name = name - self.verbose = verbose - self.keep_change = keep_change + example.__init__(self, name, verbose, keep_change) self.poll = select.poll() def parse(self): @@ -153,12 +222,12 @@ maybe_unlink(self.name + '.run') rcfile = os.path.join(tmpdir, '.hgrc') - rcfp = open(rcfile, 'w') + rcfp = wopen(rcfile) print >> rcfp, '[ui]' print >> rcfp, "username = Bryan O'Sullivan <bos@serpentine.com>" rcfile = os.path.join(tmpdir, '.bashrc') - rcfp = open(rcfile, 'w') + rcfp = wopen(rcfile) print >> rcfp, 'PS1="%s"' % self.ps1 print >> rcfp, 'PS2="%s"' % self.ps2 print >> rcfp, 'unset HISTFILE' @@ -248,8 +317,7 @@ 'SYSTEM "results/%s.out">' % (norm, norm)] = 1 read_hint = ofp_basename + ' ' - ofp = open(result_name(ofp_basename + '.tmp'), - 'w') + ofp = wopen(result_name(ofp_basename + '.tmp')) ofp.write('<screen>') else: ofp = None @@ -297,52 +365,11 @@ elif os.WIFSIGNALED(rc): print >> sys.stderr, '(signal %s)' % os.WTERMSIG(rc) else: - open(result_name(self.name + '.run'), 'w') + wopen(result_name(self.name + '.run')) return err finally: shutil.rmtree(tmpdir) - def rename_output(self, base, ignore): - mangle_re = re.compile('(?:' + '|'.join(ignore) + ')') - def mangle(s): - return mangle_re.sub('', s) - def matchfp(fp1, fp2): - while True: - s1 = mangle(fp1.readline()) - s2 = mangle(fp2.readline()) - if cmp(s1, s2): - break - if not s1: - return True - return False - - oldname = result_name(base + '.out') - tmpname = result_name(base + '.tmp') - errname = result_name(base + '.err') - errfp = open(errname, 'w+') - for line in open(tmpname): - errfp.write(mangle_re.sub('', line)) - os.rename(tmpname, result_name(base + '.lxo')) - errfp.seek(0) - try: - oldfp = open(oldname) - except IOError, err: - if err.errno != errno.ENOENT: - raise - os.rename(errname, oldname) - return False - if matchfp(oldfp, errfp): - os.unlink(errname) - return False - else: - print >> sys.stderr, '\nOutput of %s has changed!' % base - if self.keep_change: - os.rename(errname, oldname) - return False - else: - os.system('diff -u %s %s 1>&2' % (oldname, errname)) - return True - def print_help(exit, msg=None): if msg: print >> sys.stderr, 'Error:', msg @@ -383,18 +410,20 @@ print >> sys.stderr, '%s: %s' % (a, err.strerror) errs += 1 continue - if stat.S_ISREG(st.st_mode) and st.st_mode & 0111: - if example(a, verbose, keep_change).run(): - errs += 1 + if stat.S_ISREG(st.st_mode): + if st.st_mode & 0111: + if shell_example(a, verbose, keep_change).run(): + errs += 1 + elif a.endswith('.lst'): + static_example(a, verbose, keep_change).run() else: print >> sys.stderr, '%s: not a file, or not executable' % a errs += 1 elif run_all: - names = os.listdir(path) + names = glob.glob("*") + glob.glob("app*/*") + glob.glob("ch*/*") names.sort() for name in names: - if name == 'run-example' or name.startswith('.'): continue - if name.endswith('~'): continue + if name == 'run-example' or name.endswith('~'): continue pathname = os.path.join(path, name) try: st = os.lstat(pathname) @@ -403,14 +432,17 @@ if err.errno != errno.ENOENT: raise continue - if stat.S_ISREG(st.st_mode) and st.st_mode & 0111: - if example(pathname, verbose, keep_change).run(): - errs += 1 - print >> open(os.path.join(path, '.run'), 'w'), time.asctime() + if stat.S_ISREG(st.st_mode): + if st.st_mode & 0111: + if shell_example(pathname, verbose, keep_change).run(): + errs += 1 + elif pathname.endswith('.lst'): + static_example(pathname, verbose, keep_change).run() + print >> wopen(os.path.join(path, '.run')), time.asctime() else: print_help(1, msg='no test names given, and --all not provided') - fp = open('auto-snippets.xml', 'w') + fp = wopen('auto-snippets.xml') for key in sorted(example.entities.iterkeys()): print >> fp, key fp.close()