Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(614)

Side by Side Diff: isolate.py

Issue 22902007: Switch trace_inputs.py and isolate.py to subcommand.py. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/swarm_client
Patch Set: Now works Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | tests/isolate_smoke_test.py » ('j') | tests/isolate_smoke_test.py » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 """Front end tool to manage .isolate files and corresponding tests. 6 """Front end tool to operate on .isolate files.
7 7
8 Run ./isolate.py --help for more detailed information. 8 This includes creating, merging or compiling them to generate a .isolated file.
9 9
10 See more information at 10 See more information at
11 https://code.google.com/p/swarming/wiki/IsolateDesign 11 https://code.google.com/p/swarming/wiki/IsolateDesign
12 https://code.google.com/p/swarming/wiki/IsolateUserGuide 12 https://code.google.com/p/swarming/wiki/IsolateUserGuide
13 """ 13 """
14 # Run ./isolate.py --help for more detailed information.
14 15
15 import ast 16 import ast
16 import copy 17 import copy
17 import hashlib 18 import hashlib
18 import itertools 19 import itertools
19 import logging 20 import logging
20 import optparse 21 import optparse
21 import os 22 import os
22 import posixpath 23 import posixpath
23 import re 24 import re
24 import stat 25 import stat
25 import subprocess 26 import subprocess
26 import sys 27 import sys
27 28
28 import isolateserver_archive 29 import isolateserver_archive
29 import run_isolated 30 import run_isolated
30 import short_expression_finder 31 import short_expression_finder
31 import trace_inputs 32 import trace_inputs
32 33
33 # Import here directly so isolate is easier to use as a library. 34 # Import here directly so isolate is easier to use as a library.
34 from run_isolated import get_flavor 35 from run_isolated import get_flavor
35 36
37 from third_party import colorama
38 from third_party.depot_tools import fix_encoding
39 from third_party.depot_tools import subcommand
40
36 41
37 PATH_VARIABLES = ('DEPTH', 'PRODUCT_DIR') 42 PATH_VARIABLES = ('DEPTH', 'PRODUCT_DIR')
38 43
39 # Files that should be 0-length when mapped. 44 # Files that should be 0-length when mapped.
40 KEY_TOUCHED = 'isolate_dependency_touched' 45 KEY_TOUCHED = 'isolate_dependency_touched'
41 # Files that should be tracked by the build tool. 46 # Files that should be tracked by the build tool.
42 KEY_TRACKED = 'isolate_dependency_tracked' 47 KEY_TRACKED = 'isolate_dependency_tracked'
43 # Files that should not be tracked by the build tool. 48 # Files that should not be tracked by the build tool.
44 KEY_UNTRACKED = 'isolate_dependency_untracked' 49 KEY_UNTRACKED = 'isolate_dependency_untracked'
45 50
(...skipping 1859 matching lines...) Expand 10 before | Expand all | Expand 10 after
1905 with open(complete_state.saved_state.isolate_filepath, 'wb') as f: 1910 with open(complete_state.saved_state.isolate_filepath, 'wb') as f:
1906 print_all(config.file_comment, data, f) 1911 print_all(config.file_comment, data, f)
1907 if exceptions: 1912 if exceptions:
1908 # It got an exception, raise the first one. 1913 # It got an exception, raise the first one.
1909 raise \ 1914 raise \
1910 exceptions[0][0], \ 1915 exceptions[0][0], \
1911 exceptions[0][1], \ 1916 exceptions[0][1], \
1912 exceptions[0][2] 1917 exceptions[0][2]
1913 1918
1914 1919
1915 def CMDcheck(args): 1920 def CMDcheck(parser, args):
1916 """Checks that all the inputs are present and generates .isolated.""" 1921 """Checks that all the inputs are present and generates .isolated."""
1917 parser = OptionParserIsolate(command='check')
1918 parser.add_option('--subdir', help='Filters to a subdirectory') 1922 parser.add_option('--subdir', help='Filters to a subdirectory')
1919 options, args = parser.parse_args(args) 1923 options, args = parser.parse_args(args)
1920 if args: 1924 if args:
1921 parser.error('Unsupported argument: %s' % args) 1925 parser.error('Unsupported argument: %s' % args)
1922 complete_state = load_complete_state( 1926 complete_state = load_complete_state(
1923 options, os.getcwd(), options.subdir, False) 1927 options, os.getcwd(), options.subdir, False)
1924 1928
1925 # Nothing is done specifically. Just store the result and state. 1929 # Nothing is done specifically. Just store the result and state.
1926 complete_state.save_files() 1930 complete_state.save_files()
1927 return 0 1931 return 0
1928 1932
1929 1933
1930 def CMDhashtable(args): 1934 def CMDhashtable(parser, args):
1931 """Creates a hash table content addressed object store. 1935 """Creates a hash table content addressed object store.
1932 1936
1933 All the files listed in the .isolated file are put in the output directory 1937 All the files listed in the .isolated file are put in the output directory
1934 with the file name being the sha-1 of the file's content. 1938 with the file name being the sha-1 of the file's content.
1935 """ 1939 """
1936 parser = OptionParserIsolate(command='hashtable')
1937 parser.add_option('--subdir', help='Filters to a subdirectory') 1940 parser.add_option('--subdir', help='Filters to a subdirectory')
1938 options, args = parser.parse_args(args) 1941 options, args = parser.parse_args(args)
1939 if args: 1942 if args:
1940 parser.error('Unsupported argument: %s' % args) 1943 parser.error('Unsupported argument: %s' % args)
1941 1944
1942 with run_isolated.Profiler('GenerateHashtable'): 1945 with run_isolated.Profiler('GenerateHashtable'):
1943 success = False 1946 success = False
1944 try: 1947 try:
1945 complete_state = load_complete_state( 1948 complete_state = load_complete_state(
1946 options, os.getcwd(), options.subdir, False) 1949 options, os.getcwd(), options.subdir, False)
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1992 success = True 1995 success = True
1993 print('%s %s' % (isolated_hash[0], os.path.basename(options.isolated))) 1996 print('%s %s' % (isolated_hash[0], os.path.basename(options.isolated)))
1994 finally: 1997 finally:
1995 # If the command failed, delete the .isolated file if it exists. This is 1998 # If the command failed, delete the .isolated file if it exists. This is
1996 # important so no stale swarm job is executed. 1999 # important so no stale swarm job is executed.
1997 if not success and os.path.isfile(options.isolated): 2000 if not success and os.path.isfile(options.isolated):
1998 os.remove(options.isolated) 2001 os.remove(options.isolated)
1999 return not success 2002 return not success
2000 2003
2001 2004
2002 def CMDmerge(args): 2005 def CMDmerge(parser, args):
2003 """Reads and merges the data from the trace back into the original .isolate. 2006 """Reads and merges the data from the trace back into the original .isolate.
2004 2007
2005 Ignores --outdir. 2008 Ignores --outdir.
2006 """ 2009 """
2007 parser = OptionParserIsolate(command='merge', require_isolated=False) 2010 parser.require_isolated = False
2008 add_trace_option(parser) 2011 add_trace_option(parser)
2009 options, args = parser.parse_args(args) 2012 options, args = parser.parse_args(args)
2010 if args: 2013 if args:
2011 parser.error('Unsupported argument: %s' % args) 2014 parser.error('Unsupported argument: %s' % args)
2012 complete_state = load_complete_state(options, os.getcwd(), None, False) 2015 complete_state = load_complete_state(options, os.getcwd(), None, False)
2013 blacklist = trace_inputs.gen_blacklist(options.trace_blacklist) 2016 blacklist = trace_inputs.gen_blacklist(options.trace_blacklist)
2014 merge(complete_state, blacklist) 2017 merge(complete_state, blacklist)
2015 return 0 2018 return 0
2016 2019
2017 2020
2018 def CMDread(args): 2021 def CMDread(parser, args):
2019 """Reads the trace file generated with command 'trace'. 2022 """Reads the trace file generated with command 'trace'.
2020 2023
2021 Ignores --outdir. 2024 Ignores --outdir.
2022 """ 2025 """
2023 parser = OptionParserIsolate(command='read', require_isolated=False) 2026 parser.require_isolated = False
2024 add_trace_option(parser) 2027 add_trace_option(parser)
2025 parser.add_option( 2028 parser.add_option(
2026 '--skip-refresh', action='store_true', 2029 '--skip-refresh', action='store_true',
2027 help='Skip reading .isolate file and do not refresh the sha1 of ' 2030 help='Skip reading .isolate file and do not refresh the sha1 of '
2028 'dependencies') 2031 'dependencies')
2029 options, args = parser.parse_args(args) 2032 options, args = parser.parse_args(args)
2030 if args: 2033 if args:
2031 parser.error('Unsupported argument: %s' % args) 2034 parser.error('Unsupported argument: %s' % args)
2032 complete_state = load_complete_state( 2035 complete_state = load_complete_state(
2033 options, os.getcwd(), None, options.skip_refresh) 2036 options, os.getcwd(), None, options.skip_refresh)
2034 blacklist = trace_inputs.gen_blacklist(options.trace_blacklist) 2037 blacklist = trace_inputs.gen_blacklist(options.trace_blacklist)
2035 value, exceptions = read_trace_as_isolate_dict(complete_state, blacklist) 2038 value, exceptions = read_trace_as_isolate_dict(complete_state, blacklist)
2036 pretty_print(value, sys.stdout) 2039 pretty_print(value, sys.stdout)
2037 if exceptions: 2040 if exceptions:
2038 # It got an exception, raise the first one. 2041 # It got an exception, raise the first one.
2039 raise \ 2042 raise \
2040 exceptions[0][0], \ 2043 exceptions[0][0], \
2041 exceptions[0][1], \ 2044 exceptions[0][1], \
2042 exceptions[0][2] 2045 exceptions[0][2]
2043 return 0 2046 return 0
2044 2047
2045 2048
2046 def CMDremap(args): 2049 def CMDremap(parser, args):
2047 """Creates a directory with all the dependencies mapped into it. 2050 """Creates a directory with all the dependencies mapped into it.
2048 2051
2049 Useful to test manually why a test is failing. The target executable is not 2052 Useful to test manually why a test is failing. The target executable is not
2050 run. 2053 run.
2051 """ 2054 """
2052 parser = OptionParserIsolate(command='remap', require_isolated=False) 2055 parser.require_isolated = False
2053 options, args = parser.parse_args(args) 2056 options, args = parser.parse_args(args)
2054 if args: 2057 if args:
2055 parser.error('Unsupported argument: %s' % args) 2058 parser.error('Unsupported argument: %s' % args)
2056 complete_state = load_complete_state(options, os.getcwd(), None, False) 2059 complete_state = load_complete_state(options, os.getcwd(), None, False)
2057 2060
2058 if not options.outdir: 2061 if not options.outdir:
2059 options.outdir = run_isolated.make_temp_dir( 2062 options.outdir = run_isolated.make_temp_dir(
2060 'isolate', complete_state.root_dir) 2063 'isolate', complete_state.root_dir)
2061 else: 2064 else:
2062 if is_url(options.outdir): 2065 if is_url(options.outdir):
(...skipping 10 matching lines...) Expand all
2073 action=run_isolated.HARDLINK_WITH_FALLBACK, 2076 action=run_isolated.HARDLINK_WITH_FALLBACK,
2074 as_sha1=False) 2077 as_sha1=False)
2075 if complete_state.saved_state.read_only: 2078 if complete_state.saved_state.read_only:
2076 run_isolated.make_writable(options.outdir, True) 2079 run_isolated.make_writable(options.outdir, True)
2077 2080
2078 if complete_state.isolated_filepath: 2081 if complete_state.isolated_filepath:
2079 complete_state.save_files() 2082 complete_state.save_files()
2080 return 0 2083 return 0
2081 2084
2082 2085
2083 def CMDrewrite(args): 2086 def CMDrewrite(parser, args):
2084 """Rewrites a .isolate file into the canonical format.""" 2087 """Rewrites a .isolate file into the canonical format."""
2085 parser = OptionParserIsolate(command='rewrite', require_isolated=False) 2088 parser.require_isolated = False
2086 options, args = parser.parse_args(args) 2089 options, args = parser.parse_args(args)
2087 if args: 2090 if args:
2088 parser.error('Unsupported argument: %s' % args) 2091 parser.error('Unsupported argument: %s' % args)
2089 2092
2090 if options.isolated: 2093 if options.isolated:
2091 # Load the previous state if it was present. Namely, "foo.isolated.state". 2094 # Load the previous state if it was present. Namely, "foo.isolated.state".
2092 complete_state = CompleteState.load_files(options.isolated) 2095 complete_state = CompleteState.load_files(options.isolated)
2093 isolate = options.isolate or complete_state.saved_state.isolate_filepath 2096 isolate = options.isolate or complete_state.saved_state.isolate_filepath
2094 else: 2097 else:
2095 isolate = options.isolate 2098 isolate = options.isolate
2096 if not isolate: 2099 if not isolate:
2097 raise ExecutionError('A .isolate file is required.') 2100 raise ExecutionError('A .isolate file is required.')
2098 with open(isolate, 'r') as f: 2101 with open(isolate, 'r') as f:
2099 content = f.read() 2102 content = f.read()
2100 config = load_isolate_as_config( 2103 config = load_isolate_as_config(
2101 os.path.dirname(os.path.abspath(isolate)), 2104 os.path.dirname(os.path.abspath(isolate)),
2102 eval_content(content), 2105 eval_content(content),
2103 extract_comment(content)) 2106 extract_comment(content))
2104 data = config.make_isolate_file() 2107 data = config.make_isolate_file()
2105 print('Updating %s' % isolate) 2108 print('Updating %s' % isolate)
2106 with open(isolate, 'wb') as f: 2109 with open(isolate, 'wb') as f:
2107 print_all(config.file_comment, data, f) 2110 print_all(config.file_comment, data, f)
2108 return 0 2111 return 0
2109 2112
2110 2113
2111 def CMDrun(args): 2114 def CMDrun(parser, args):
2112 """Runs the test executable in an isolated (temporary) directory. 2115 """Runs the test executable in an isolated (temporary) directory.
2113 2116
2114 All the dependencies are mapped into the temporary directory and the 2117 All the dependencies are mapped into the temporary directory and the
2115 directory is cleaned up after the target exits. Warning: if --outdir is 2118 directory is cleaned up after the target exits. Warning: if --outdir is
2116 specified, it is deleted upon exit. 2119 specified, it is deleted upon exit.
2117 2120
2118 Argument processing stops at the first non-recognized argument and these 2121 Argument processing stops at the first non-recognized argument and these
2119 arguments are appended to the command line of the target to run. For example, 2122 arguments are appended to the command line of the target to run. For example,
2120 use: isolate.py --isolated foo.isolated -- --gtest_filter=Foo.Bar 2123 use: isolate.py --isolated foo.isolated -- --gtest_filter=Foo.Bar
2121 """ 2124 """
2122 parser = OptionParserIsolate(command='run', require_isolated=False) 2125 parser.require_isolated = False
2123 parser.add_option( 2126 parser.add_option(
2124 '--skip-refresh', action='store_true', 2127 '--skip-refresh', action='store_true',
2125 help='Skip reading .isolate file and do not refresh the sha1 of ' 2128 help='Skip reading .isolate file and do not refresh the sha1 of '
2126 'dependencies') 2129 'dependencies')
2127 parser.enable_interspersed_args() 2130 parser.enable_interspersed_args()
2128 options, args = parser.parse_args(args) 2131 options, args = parser.parse_args(args)
2129 complete_state = load_complete_state( 2132 complete_state = load_complete_state(
2130 options, os.getcwd(), None, options.skip_refresh) 2133 options, os.getcwd(), None, options.skip_refresh)
2131 cmd = complete_state.saved_state.command + args 2134 cmd = complete_state.saved_state.command + args
2132 if not cmd: 2135 if not cmd:
(...skipping 30 matching lines...) Expand all
2163 result = subprocess.call(cmd, cwd=cwd) 2166 result = subprocess.call(cmd, cwd=cwd)
2164 finally: 2167 finally:
2165 if options.outdir: 2168 if options.outdir:
2166 run_isolated.rmtree(options.outdir) 2169 run_isolated.rmtree(options.outdir)
2167 2170
2168 if complete_state.isolated_filepath: 2171 if complete_state.isolated_filepath:
2169 complete_state.save_files() 2172 complete_state.save_files()
2170 return result 2173 return result
2171 2174
2172 2175
2173 def CMDtrace(args): 2176 def CMDtrace(parser, args):
2174 """Traces the target using trace_inputs.py. 2177 """Traces the target using trace_inputs.py.
2175 2178
2176 It runs the executable without remapping it, and traces all the files it and 2179 It runs the executable without remapping it, and traces all the files it and
2177 its child processes access. Then the 'merge' command can be used to generate 2180 its child processes access. Then the 'merge' command can be used to generate
2178 an updated .isolate file out of it or the 'read' command to print it out to 2181 an updated .isolate file out of it or the 'read' command to print it out to
2179 stdout. 2182 stdout.
2180 2183
2181 Argument processing stops at the first non-recognized argument and these 2184 Argument processing stops at the first non-recognized argument and these
2182 arguments are appended to the command line of the target to run. For example, 2185 arguments are appended to the command line of the target to run. For example,
2183 use: isolate.py --isolated foo.isolated -- --gtest_filter=Foo.Bar 2186 use: isolate.py --isolated foo.isolated -- --gtest_filter=Foo.Bar
2184 """ 2187 """
2185 parser = OptionParserIsolate(command='trace')
2186 add_trace_option(parser) 2188 add_trace_option(parser)
2187 parser.enable_interspersed_args() 2189 parser.enable_interspersed_args()
2188 parser.add_option( 2190 parser.add_option(
2189 '-m', '--merge', action='store_true', 2191 '-m', '--merge', action='store_true',
2190 help='After tracing, merge the results back in the .isolate file') 2192 help='After tracing, merge the results back in the .isolate file')
2191 parser.add_option( 2193 parser.add_option(
2192 '--skip-refresh', action='store_true', 2194 '--skip-refresh', action='store_true',
2193 help='Skip reading .isolate file and do not refresh the sha1 of ' 2195 help='Skip reading .isolate file and do not refresh the sha1 of '
2194 'dependencies') 2196 'dependencies')
2195 options, args = parser.parse_args(args) 2197 options, args = parser.parse_args(args)
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
2306 # but it wouldn't be backward compatible. 2308 # but it wouldn't be backward compatible.
2307 def try_make_int(s): 2309 def try_make_int(s):
2308 """Converts a value to int if possible, converts to unicode otherwise.""" 2310 """Converts a value to int if possible, converts to unicode otherwise."""
2309 try: 2311 try:
2310 return int(s) 2312 return int(s)
2311 except ValueError: 2313 except ValueError:
2312 return s.decode('utf-8') 2314 return s.decode('utf-8')
2313 options.variables = dict((k, try_make_int(v)) for k, v in options.variables) 2315 options.variables = dict((k, try_make_int(v)) for k, v in options.variables)
2314 2316
2315 2317
2316 class OptionParserIsolate(trace_inputs.OptionParserWithNiceDescription): 2318 class OptionParserIsolate(trace_inputs.OptionParserWithLogging):
2317 """Adds automatic --isolate, --isolated, --out and --variable handling.""" 2319 """Adds automatic --isolate, --isolated, --out and --variable handling."""
2318 def __init__(self, require_isolated=True, **kwargs): 2320 # Set it to False if it is not required, e.g. it can be passed on but do not
2319 trace_inputs.OptionParserWithNiceDescription.__init__( 2321 # fail if not given.
2322 require_isolated = True
2323
2324 def __init__(self, **kwargs):
2325 trace_inputs.OptionParserWithLogging.__init__(
2320 self, 2326 self,
2321 verbose=int(os.environ.get('ISOLATE_DEBUG', 0)), 2327 verbose=int(os.environ.get('ISOLATE_DEBUG', 0)),
2322 **kwargs) 2328 **kwargs)
2323 group = optparse.OptionGroup(self, "Common options") 2329 group = optparse.OptionGroup(self, "Common options")
2324 group.add_option( 2330 group.add_option(
2325 '-i', '--isolate', 2331 '-i', '--isolate',
2326 metavar='FILE', 2332 metavar='FILE',
2327 help='.isolate file to load the dependency data from') 2333 help='.isolate file to load the dependency data from')
2328 add_variable_option(group) 2334 add_variable_option(group)
2329 group.add_option( 2335 group.add_option(
2330 '-o', '--outdir', metavar='DIR', 2336 '-o', '--outdir', metavar='DIR',
2331 help='Directory used to recreate the tree or store the hash table. ' 2337 help='Directory used to recreate the tree or store the hash table. '
2332 'Defaults: run|remap: a /tmp subdirectory, others: ' 2338 'Defaults: run|remap: a /tmp subdirectory, others: '
2333 'defaults to the directory containing --isolated') 2339 'defaults to the directory containing --isolated')
2334 group.add_option( 2340 group.add_option(
2335 '--ignore_broken_items', action='store_true', 2341 '--ignore_broken_items', action='store_true',
2336 default=bool(os.environ.get('ISOLATE_IGNORE_BROKEN_ITEMS')), 2342 default=bool(os.environ.get('ISOLATE_IGNORE_BROKEN_ITEMS')),
2337 help='Indicates that invalid entries in the isolated file to be ' 2343 help='Indicates that invalid entries in the isolated file to be '
2338 'only be logged and not stop processing. Defaults to True if ' 2344 'only be logged and not stop processing. Defaults to True if '
2339 'env var ISOLATE_IGNORE_BROKEN_ITEMS is set') 2345 'env var ISOLATE_IGNORE_BROKEN_ITEMS is set')
2340 self.add_option_group(group) 2346 self.add_option_group(group)
2341 self.require_isolated = require_isolated
2342 2347
2343 def parse_args(self, *args, **kwargs): 2348 def parse_args(self, *args, **kwargs):
2344 """Makes sure the paths make sense. 2349 """Makes sure the paths make sense.
2345 2350
2346 On Windows, / and \ are often mixed together in a path. 2351 On Windows, / and \ are often mixed together in a path.
2347 """ 2352 """
2348 options, args = trace_inputs.OptionParserWithNiceDescription.parse_args( 2353 options, args = trace_inputs.OptionParserWithLogging.parse_args(
2349 self, *args, **kwargs) 2354 self, *args, **kwargs)
2350 if not self.allow_interspersed_args and args: 2355 if not self.allow_interspersed_args and args:
2351 self.error('Unsupported argument: %s' % args) 2356 self.error('Unsupported argument: %s' % args)
2352 2357
2353 cwd = trace_inputs.get_native_path_case(unicode(os.getcwd())) 2358 cwd = trace_inputs.get_native_path_case(unicode(os.getcwd()))
2354 parse_isolated_option(self, options, cwd, self.require_isolated) 2359 parse_isolated_option(self, options, cwd, self.require_isolated)
2355 parse_variable_option(options) 2360 parse_variable_option(options)
2356 2361
2357 if options.isolate: 2362 if options.isolate:
2358 # TODO(maruel): Work with non-ASCII. 2363 # TODO(maruel): Work with non-ASCII.
2359 # The path must be in native path case for tracing purposes. 2364 # The path must be in native path case for tracing purposes.
2360 options.isolate = unicode(options.isolate).replace('/', os.path.sep) 2365 options.isolate = unicode(options.isolate).replace('/', os.path.sep)
2361 options.isolate = os.path.normpath(os.path.join(cwd, options.isolate)) 2366 options.isolate = os.path.normpath(os.path.join(cwd, options.isolate))
2362 options.isolate = trace_inputs.get_native_path_case(options.isolate) 2367 options.isolate = trace_inputs.get_native_path_case(options.isolate)
2363 2368
2364 if options.outdir and not is_url(options.outdir): 2369 if options.outdir and not is_url(options.outdir):
2365 options.outdir = unicode(options.outdir).replace('/', os.path.sep) 2370 options.outdir = unicode(options.outdir).replace('/', os.path.sep)
2366 # outdir doesn't need native path case since tracing is never done from 2371 # outdir doesn't need native path case since tracing is never done from
2367 # there. 2372 # there.
2368 options.outdir = os.path.normpath(os.path.join(cwd, options.outdir)) 2373 options.outdir = os.path.normpath(os.path.join(cwd, options.outdir))
2369 2374
2370 return options, args 2375 return options, args
2371 2376
2372 2377
2373 ### Glue code to make all the commands works magically.
2374
2375
2376 CMDhelp = trace_inputs.CMDhelp
2377
2378
2379 def main(argv): 2378 def main(argv):
2379 dispatcher = subcommand.CommandDispatcher(__name__)
2380 try: 2380 try:
2381 return trace_inputs.main_impl(argv) 2381 return dispatcher.execute(OptionParserIsolate(), argv)
2382 except ( 2382 except (
2383 ExecutionError, 2383 ExecutionError,
2384 run_isolated.MappingError, 2384 run_isolated.MappingError,
2385 run_isolated.ConfigError) as e: 2385 run_isolated.ConfigError) as e:
2386 sys.stderr.write('\nError: ') 2386 sys.stderr.write('\nError: ')
2387 sys.stderr.write(str(e)) 2387 sys.stderr.write(str(e))
2388 sys.stderr.write('\n') 2388 sys.stderr.write('\n')
2389 return 1 2389 return 1
2390 2390
2391 2391
2392 if __name__ == '__main__': 2392 if __name__ == '__main__':
2393 fix_encoding.fix_encoding()
2394 trace_inputs.disable_buffering()
2395 colorama.init()
2393 sys.exit(main(sys.argv[1:])) 2396 sys.exit(main(sys.argv[1:]))
OLDNEW
« no previous file with comments | « no previous file | tests/isolate_smoke_test.py » ('j') | tests/isolate_smoke_test.py » ('J')

Powered by Google App Engine
This is Rietveld 408576698