1#!/usr/bin/env python
2# Copyright (c) 2012 The Chromium Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6"""Launch a local server on an ephemeral port, then launch a executable that
7points to that server.
8"""
9
10import copy
11import getos
12import optparse
13import os
14import subprocess
15import sys
16import httpd
17
18
19if sys.version_info < (2, 6, 0):
20  sys.stderr.write("python 2.6 or later is required run this script\n")
21  sys.exit(1)
22
23
24def main(args):
25  usage = """usage: %prog [options] -- executable args...
26
27  This command creates a local server on an ephemeral port, then runs:
28    <executable> <args..> http://localhost:<port>/<page>.
29
30  Where <page> can be set by -P, or uses index.html by default."""
31  parser = optparse.OptionParser(usage)
32  parser.add_option('-C', '--serve-dir',
33      help='Serve files out of this directory.',
34      dest='serve_dir', default=os.path.abspath('.'))
35  parser.add_option('-P', '--path', help='Path to load from local server.',
36      dest='path', default='index.html')
37  parser.add_option('-D',
38      help='Add debug command-line when launching the chrome debug.',
39      dest='debug', action='append', default=[])
40  parser.add_option('-E',
41      help='Add environment variables when launching the executable.',
42      dest='environ', action='append', default=[])
43  parser.add_option('-p', '--port',
44      help='Port to run server on. Default is 5103, ephemeral is 0.',
45      type='int', default=5103)
46  options, args = parser.parse_args(args)
47  if not args:
48    parser.error('No executable given.')
49
50  # 0 means use an ephemeral port.
51  server = httpd.LocalHTTPServer(options.serve_dir, options.port)
52  print 'Serving %s on %s...' % (options.serve_dir, server.GetURL(''))
53
54  env = copy.copy(os.environ)
55  for e in options.environ:
56    key, value = map(str.strip, e.split('='))
57    env[key] = value
58
59  cmd = args + [server.GetURL(options.path)]
60  print 'Running: %s...' % (' '.join(cmd),)
61  process = subprocess.Popen(cmd, env=env)
62
63  # If any debug args are passed in, assume we want to debug
64  if options.debug:
65    if getos.GetPlatform() == 'linux':
66      cmd = ['xterm', '-title', 'NaCl Debugger', '-e']
67      cmd += options.debug
68    elif getos.GetPlatform() == 'mac':
69      cmd = ['osascript', '-e',
70             'tell application "Terminal" to do script "%s"' %
71                 ' '.join(r'\"%s\"' % x for x in options.debug)]
72    elif getos.GetPlatform() == 'win':
73      cmd = ['cmd.exe', '/c', 'start', 'cmd.exe', '/c']
74      cmd += options.debug
75    print 'Starting debugger: ' + ' '.join(cmd)
76    debug_process = subprocess.Popen(cmd, env=env)
77  else:
78    debug_process = False
79
80  try:
81    return server.ServeUntilSubprocessDies(process)
82  finally:
83    if process.returncode is None:
84      process.kill()
85    if debug_process and debug_process.returncode is None:
86      debug_process.kill()
87
88if __name__ == '__main__':
89  sys.exit(main(sys.argv[1:]))
90