| #!/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:])) |