forked from swiftlang/swift
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdemo-tool
executable file
·136 lines (106 loc) · 3.71 KB
/
demo-tool
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#!/usr/bin/env python
import json
import optparse
import subprocess
import time
def send_to_screen(screen_name, arg0=None, command='stuff'):
args = ['screen', '-S', screen_name, '-p', '0',
'-X', command]
if arg0 is not None:
args.append(arg0)
p = subprocess.Popen(args)
p.communicate()
def load_as_transcript(f):
def add_block():
# If so, add the current block after trimming leading and trailing blank
# lines.
while current_block and current_block[0].isspace():
current_block.pop(0)
while current_block and current_block[-1].isspace():
current_block.pop()
# Add the block if it is non-empty.
if current_block:
# Form the joined script..
script = ''.join(current_block)
# Strip off any trailing newline.
if script.endswith('\n'):
script = script[:-1]
demo_script.append({ 'command' : script})
# Clear the block.
del current_block[:]
f.seek(0)
demo_script = []
current_block = []
for ln in f:
# Check if this is a block delimiter.
if ln.strip() == '>>>':
add_block()
continue
# Otherwise, add the line to the current block.
current_block.append(ln)
return demo_script
def main():
parser = optparse.OptionParser("""\
usage: %%prog [options] <demo script>
Run a command line demo script using 'screen'. The script file should be either
a JSON document listing the commands to run, as in::
[
{ "command" : "ls" },
{ "command" : "echo Hello" }
]
or, alternately, it should be a text filed delimited by '>>>', as in::
>>>
ls
>>>
echo Hello
where leading and trailing blank lines around each block will be discarded.
The script requires the 'screen' session to have been started in another window,
for example::
$ screen -S demo
""")
def send(*args, **kwargs):
return send_to_screen(opts.screen_name, *args, **kwargs)
parser.add_option("-S", "--screen-name", dest="screen_name", metavar="NAME",
help="name of the screen sesison to use [%default]",
action="store", default="demo")
opts, args = parser.parse_args()
if len(args) == 1:
path, = args
else:
parser.error("invalid number of arguments")
# Read in the demo script.
with open(path) as f:
try:
demo_script = json.load(f)
except ValueError:
demo_script = load_as_transcript(f)
# Validate the entries.
for item in demo_script:
command = str(item.get('command'))
if not isinstance(command, str):
raise SystemError("error: invalid item in script: %r" % (
item,))
# Notify screen that we are starting the demo.
raw_input('press enter to begin demo...')
# Iterate over each command, sending it and waiting for user direction to
# continue.
for item in demo_script:
command = str(item['command'])
# Send the command slowly, as if it was typed.
print "sending command: %r" % (command.replace('\n', '<cr>'),)
for c in command:
send(c)
if c == "\n":
time.sleep(0.75)
else:
time.sleep(0.005)
# Wait for user input, then send a return.
raw_input('press enter to send return...')
send('\n')
if item is not demo_script[-1]:
raw_input('press enter to continue to next command...')
# Notify screen that the demo is over, after a small wait period.
time.sleep(0.1)
send('Demo session is over.', command='wall')
if __name__ == '__main__':
main()