hgbook
changeset 6:69d90ab9fd80
Really run example command sequences under a single shell.
Grotesque hackery involved. Bring strong stomachs.
Grotesque hackery involved. Bring strong stomachs.
author | Bryan O'Sullivan <bos@serpentine.com> |
---|---|
date | Mon Jun 26 10:15:49 2006 -0700 (2006-06-26) |
parents | faa29ca23fc8 |
children | 339e75288632 |
files | en/examples/mq.qinit-help en/examples/run-example |
line diff
1.1 --- a/en/examples/mq.qinit-help Sun Jun 25 22:44:24 2006 -0700 1.2 +++ b/en/examples/mq.qinit-help Mon Jun 26 10:15:49 2006 -0700 1.3 @@ -1,2 +1,5 @@ 1.4 +echo '[extensions]' >> $HGRC 1.5 +echo 'hgext.mq =' >> $HGRC 1.6 + 1.7 #$ name: help 1.8 hg help qinit
2.1 --- a/en/examples/run-example Sun Jun 25 22:44:24 2006 -0700 2.2 +++ b/en/examples/run-example Mon Jun 26 10:15:49 2006 -0700 2.3 @@ -9,6 +9,7 @@ 2.4 import pty 2.5 import re 2.6 import shutil 2.7 +import signal 2.8 import sys 2.9 import tempfile 2.10 import time 2.11 @@ -24,6 +25,7 @@ 2.12 2.13 class example: 2.14 shell = '/bin/bash' 2.15 + prompt = '__run_example_prompt__\n' 2.16 pi_re = re.compile('#\$\s*(name):\s*(.*)$') 2.17 2.18 def __init__(self, name): 2.19 @@ -45,18 +47,50 @@ 2.20 if not s.endswith('\n'): 2.21 sys.stdout.flush() 2.22 2.23 - def drain(self, ifp, ofp): 2.24 + def send(self, s): 2.25 + self.cfp.write(s) 2.26 + self.cfp.flush() 2.27 + 2.28 + def receive(self): 2.29 + out = cStringIO.StringIO() 2.30 while True: 2.31 - s = ifp.read(4096) 2.32 - if not s: break 2.33 - if ofp: ofp.write(tex_escape(s)) 2.34 + s = self.cfp.readline().replace('\r\n', '\n') 2.35 + if not s or s == self.prompt: 2.36 + break 2.37 + out.write(s) 2.38 + return out.getvalue() 2.39 2.40 + def sendreceive(self, s): 2.41 + self.send(s) 2.42 + r = self.receive() 2.43 + if r.startswith(s): 2.44 + r = r[len(s):] 2.45 + return r 2.46 + 2.47 def run(self): 2.48 ofp = None 2.49 basename = os.path.basename(self.name) 2.50 self.status('running %s ' % basename) 2.51 tmpdir = tempfile.mkdtemp(prefix=basename) 2.52 + rcfile = os.path.join(tmpdir, '.bashrc') 2.53 + rcfp = open(rcfile, 'w') 2.54 + print >> rcfp, 'PS1="%s"' % self.prompt 2.55 + print >> rcfp, 'unset HISTFILE' 2.56 + print >> rcfp, 'export LANG=C' 2.57 + print >> rcfp, 'export LC_ALL=C' 2.58 + print >> rcfp, 'export TZ=GMT' 2.59 + print >> rcfp, 'export HGRC="%s/.hgrc"' % tmpdir 2.60 + print >> rcfp, 'export HGRCPATH=$HGRC' 2.61 + print >> rcfp, 'cd %s' % tmpdir 2.62 + rcfp.close() 2.63 + pid, fd = pty.fork() 2.64 + if pid == 0: 2.65 + #os.execl(self.shell, self.shell) 2.66 + os.system('/bin/bash --noediting --noprofile --rcfile %s' % rcfile) 2.67 + sys.exit(0) 2.68 + self.cfp = os.fdopen(fd, 'w+') 2.69 try: 2.70 + self.receive() 2.71 for hunk in self.parse(): 2.72 # is this line a processing instruction? 2.73 m = self.pi_re.match(hunk) 2.74 @@ -70,22 +104,30 @@ 2.75 ofp = open('%s.%s.out' % (self.name, out), 'w') 2.76 else: 2.77 ofp = None 2.78 - else: 2.79 + elif hunk.strip(): 2.80 # it's something we should execute 2.81 - cin, cout = os.popen4('cd %s; %s' % (tmpdir, hunk)) 2.82 - cin.close() 2.83 - if ofp: 2.84 - # first, print the command we ran 2.85 - if not hunk.startswith('#'): 2.86 - nl = hunk.endswith('\n') 2.87 - hunk = ('$ \\textbf{%s}' % 2.88 - tex_escape(hunk.rstrip('\n'))) 2.89 - if nl: hunk += '\n' 2.90 - ofp.write(hunk) 2.91 + output = self.sendreceive(hunk) 2.92 + if not ofp: 2.93 + continue 2.94 + # first, print the command we ran 2.95 + if not hunk.startswith('#'): 2.96 + nl = hunk.endswith('\n') 2.97 + hunk = ('$ \\textbf{%s}' % 2.98 + tex_escape(hunk.rstrip('\n'))) 2.99 + if nl: hunk += '\n' 2.100 + ofp.write(hunk) 2.101 # then its output 2.102 - self.drain(cout, ofp) 2.103 + ofp.write(output) 2.104 self.status('\n') 2.105 finally: 2.106 + try: 2.107 + output = self.sendreceive('exit\n') 2.108 + if ofp: 2.109 + ofp.write(output) 2.110 + self.cfp.close() 2.111 + except IOError: 2.112 + pass 2.113 + os.kill(pid, signal.SIGTERM) 2.114 os.wait() 2.115 shutil.rmtree(tmpdir) 2.116