blob: 72e39df1bba21ca0a5164329e3649935d215e03b [file] [log] [blame]
#!/usr/bin/env python
# Copyright (c) 2012 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Generates a wrapper script to invoke a test binary on a desktop.
We want every test step to be invoked in a uniform way so that developers
can trivially reproduce how tests are invoked on the bots, and so that
tests are configured the same way regardless of platform or type of test.
This script is responsible for generating wrapper scripts that will
provided the needed arguments for test() targets in the build to run
on Mac, Win, and Linux. The test() template invokes different scripts
to generate wrappers for Android, CrOS, and Fuchsia.
"""
import argparse
import os
import pipes
import re
import stat
import sys
def main(argv):
parser = argparse.ArgumentParser()
parser.add_argument('output',
help='path to write the file to')
args, remaining_args = parser.parse_known_args(argv)
bin_dir = os.path.dirname(args.output)
if args.output.endswith('.bat'):
contents = (
'@echo off\n' +
'rem Generated by //testing/gen_desktop_runner_script.py\n' +
'cd /d %dp0\\..\n' +
' '.join(QuoteForCmd(arg) for arg in remaining_args) + ' %*\n')
else:
contents = (
'#!/bin/bash\n' +
'# Generated by //testing/gen_desktop_runner_script.py' +
'set -x\n' +
'cd "$(dirname "$0" )/.."\n' +
' '.join(pipes.quote(arg) for arg in remaining_args) + ' "$@"\n')
if not os.path.exists(bin_dir):
os.mkdir(bin_dir)
with open(args.output, 'w') as fp:
fp.write(contents)
os.chmod(args.output,
stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR |
stat.S_IRGRP | stat.S_IWGRP | stat.S_IXGRP |
stat.S_IROTH | stat.S_IWOTH | stat.S_IXOTH)
return 0
def QuoteForCmd(arg):
"""Returns an arg quoted for passing to cmd.exe or using in a batch file."""
# See http://goo.gl/l5NPDW and http://goo.gl/4Diozm for the painful
# details of this next section, which handles escaping command lines
# so that they can be copied and pasted into a cmd window.
UNSAFE_FOR_CMD = set('^<>&|()%')
ALL_META_CHARS = UNSAFE_FOR_CMD.union(set('"'))
# First, escape the arg so that CommandLineToArgvW will parse it properly.
if arg == '' or ' ' in arg or '"' in arg:
quote_re = re.compile(r'(\\*)"')
arg = '"%s"' % (quote_re.sub(lambda mo: 2 * mo.group(1) + '\\"', arg))
# Then check to see if the arg contains any metacharacters other than
# double quotes; if it does, quote everything (including the double
# quotes) for safety.
if any(a in UNSAFE_FOR_CMD for a in arg):
arg = ''.join('^' + a if a in ALL_META_CHARS else a for a in arg)
return arg
if __name__ == '__main__':
sys.exit(main(sys.argv[1:]))