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

Side by Side Diff: isolate.py

Issue 24813003: Move file path functions into utils/file_path.py. (Closed) Base URL: https://chromium.googlesource.com/a/chromium/tools/swarm_client@master
Patch Set: Created 7 years, 2 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
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 operate on .isolate files. 6 """Front end tool to operate on .isolate files.
7 7
8 This includes creating, merging or compiling them to generate a .isolated file. 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
(...skipping 18 matching lines...) Expand all
29 import run_isolated 29 import run_isolated
30 import trace_inputs 30 import trace_inputs
31 31
32 # Import here directly so isolate is easier to use as a library. 32 # Import here directly so isolate is easier to use as a library.
33 from run_isolated import get_flavor 33 from run_isolated import get_flavor
34 34
35 from third_party import colorama 35 from third_party import colorama
36 from third_party.depot_tools import fix_encoding 36 from third_party.depot_tools import fix_encoding
37 from third_party.depot_tools import subcommand 37 from third_party.depot_tools import subcommand
38 38
39 from utils import file_path
39 from utils import tools 40 from utils import tools
40 from utils import short_expression_finder 41 from utils import short_expression_finder
41 42
42 43
43 __version__ = '0.1.1' 44 __version__ = '0.1.1'
44 45
45 46
46 PATH_VARIABLES = ('DEPTH', 'PRODUCT_DIR') 47 PATH_VARIABLES = ('DEPTH', 'PRODUCT_DIR')
47 48
48 # Files that should be 0-length when mapped. 49 # Files that should be 0-length when mapped.
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
131 132
132 133
133 def path_starts_with(prefix, path): 134 def path_starts_with(prefix, path):
134 """Returns true if the components of the path |prefix| are the same as the 135 """Returns true if the components of the path |prefix| are the same as the
135 initial components of |path| (or all of the components of |path|). The paths 136 initial components of |path| (or all of the components of |path|). The paths
136 must be absolute. 137 must be absolute.
137 """ 138 """
138 assert os.path.isabs(prefix) and os.path.isabs(path) 139 assert os.path.isabs(prefix) and os.path.isabs(path)
139 prefix = os.path.normpath(prefix) 140 prefix = os.path.normpath(prefix)
140 path = os.path.normpath(path) 141 path = os.path.normpath(path)
141 assert prefix == trace_inputs.get_native_path_case(prefix), prefix 142 assert prefix == file_path.get_native_path_case(prefix), prefix
142 assert path == trace_inputs.get_native_path_case(path), path 143 assert path == file_path.get_native_path_case(path), path
143 prefix = prefix.rstrip(os.path.sep) + os.path.sep 144 prefix = prefix.rstrip(os.path.sep) + os.path.sep
144 path = path.rstrip(os.path.sep) + os.path.sep 145 path = path.rstrip(os.path.sep) + os.path.sep
145 return path.startswith(prefix) 146 return path.startswith(prefix)
146 147
147 148
148 def fix_native_path_case(root, path): 149 def fix_native_path_case(root, path):
149 """Ensures that each component of |path| has the proper native case by 150 """Ensures that each component of |path| has the proper native case by
150 iterating slowly over the directory elements of |path|.""" 151 iterating slowly over the directory elements of |path|."""
151 native_case_path = root 152 native_case_path = root
152 for raw_part in path.split(os.sep): 153 for raw_part in path.split(os.sep):
153 if not raw_part or raw_part == '.': 154 if not raw_part or raw_part == '.':
154 break 155 break
155 156
156 part = trace_inputs.find_item_native_case(native_case_path, raw_part) 157 part = file_path.find_item_native_case(native_case_path, raw_part)
157 if not part: 158 if not part:
158 raise isolateserver.MappingError( 159 raise isolateserver.MappingError(
159 'Input file %s doesn\'t exist' % 160 'Input file %s doesn\'t exist' %
160 os.path.join(native_case_path, raw_part)) 161 os.path.join(native_case_path, raw_part))
161 native_case_path = os.path.join(native_case_path, part) 162 native_case_path = os.path.join(native_case_path, part)
162 163
163 return os.path.normpath(native_case_path) 164 return os.path.normpath(native_case_path)
164 165
165 166
166 def expand_symlinks(indir, relfile): 167 def expand_symlinks(indir, relfile):
167 """Follows symlinks in |relfile|, but treating symlinks that point outside the 168 """Follows symlinks in |relfile|, but treating symlinks that point outside the
168 build tree as if they were ordinary directories/files. Returns the final 169 build tree as if they were ordinary directories/files. Returns the final
169 symlink-free target and a list of paths to symlinks encountered in the 170 symlink-free target and a list of paths to symlinks encountered in the
170 process. 171 process.
171 172
172 The rule about symlinks outside the build tree is for the benefit of the 173 The rule about symlinks outside the build tree is for the benefit of the
173 Chromium OS ebuild, which symlinks the output directory to an unrelated path 174 Chromium OS ebuild, which symlinks the output directory to an unrelated path
174 in the chroot. 175 in the chroot.
175 176
176 Fails when a directory loop is detected, although in theory we could support 177 Fails when a directory loop is detected, although in theory we could support
177 that case. 178 that case.
178 """ 179 """
179 is_directory = relfile.endswith(os.path.sep) 180 is_directory = relfile.endswith(os.path.sep)
180 done = indir 181 done = indir
181 todo = relfile.strip(os.path.sep) 182 todo = relfile.strip(os.path.sep)
182 symlinks = [] 183 symlinks = []
183 184
184 while todo: 185 while todo:
185 pre_symlink, symlink, post_symlink = trace_inputs.split_at_symlink( 186 pre_symlink, symlink, post_symlink = file_path.split_at_symlink(
186 done, todo) 187 done, todo)
187 if not symlink: 188 if not symlink:
188 todo = fix_native_path_case(done, todo) 189 todo = fix_native_path_case(done, todo)
189 done = os.path.join(done, todo) 190 done = os.path.join(done, todo)
190 break 191 break
191 symlink_path = os.path.join(done, pre_symlink, symlink) 192 symlink_path = os.path.join(done, pre_symlink, symlink)
192 post_symlink = post_symlink.lstrip(os.path.sep) 193 post_symlink = post_symlink.lstrip(os.path.sep)
193 # readlink doesn't exist on Windows. 194 # readlink doesn't exist on Windows.
194 # pylint: disable=E1101 195 # pylint: disable=E1101
195 target = os.path.normpath(os.path.join(done, pre_symlink)) 196 target = os.path.normpath(os.path.join(done, pre_symlink))
196 symlink_target = os.readlink(symlink_path) 197 symlink_target = os.readlink(symlink_path)
197 if os.path.isabs(symlink_target): 198 if os.path.isabs(symlink_target):
198 # Absolute path are considered a normal directories. The use case is 199 # Absolute path are considered a normal directories. The use case is
199 # generally someone who puts the output directory on a separate drive. 200 # generally someone who puts the output directory on a separate drive.
200 target = symlink_target 201 target = symlink_target
201 else: 202 else:
202 # The symlink itself could be using the wrong path case. 203 # The symlink itself could be using the wrong path case.
203 target = fix_native_path_case(target, symlink_target) 204 target = fix_native_path_case(target, symlink_target)
204 205
205 if not os.path.exists(target): 206 if not os.path.exists(target):
206 raise isolateserver.MappingError( 207 raise isolateserver.MappingError(
207 'Symlink target doesn\'t exist: %s -> %s' % (symlink_path, target)) 208 'Symlink target doesn\'t exist: %s -> %s' % (symlink_path, target))
208 target = trace_inputs.get_native_path_case(target) 209 target = file_path.get_native_path_case(target)
209 if not path_starts_with(indir, target): 210 if not path_starts_with(indir, target):
210 done = symlink_path 211 done = symlink_path
211 todo = post_symlink 212 todo = post_symlink
212 continue 213 continue
213 if path_starts_with(target, symlink_path): 214 if path_starts_with(target, symlink_path):
214 raise isolateserver.MappingError( 215 raise isolateserver.MappingError(
215 'Can\'t map recursive symlink reference %s -> %s' % 216 'Can\'t map recursive symlink reference %s -> %s' %
216 (symlink_path, target)) 217 (symlink_path, target))
217 logging.info('Found symlink: %s -> %s', symlink_path, target) 218 logging.info('Found symlink: %s -> %s', symlink_path, target)
218 symlinks.append(os.path.relpath(symlink_path, indir)) 219 symlinks.append(os.path.relpath(symlink_path, indir))
(...skipping 28 matching lines...) Expand all
247 if os.path.isabs(relfile): 248 if os.path.isabs(relfile):
248 raise isolateserver.MappingError( 249 raise isolateserver.MappingError(
249 'Can\'t map absolute path %s' % relfile) 250 'Can\'t map absolute path %s' % relfile)
250 251
251 infile = normpath(os.path.join(indir, relfile)) 252 infile = normpath(os.path.join(indir, relfile))
252 if not infile.startswith(indir): 253 if not infile.startswith(indir):
253 raise isolateserver.MappingError( 254 raise isolateserver.MappingError(
254 'Can\'t map file %s outside %s' % (infile, indir)) 255 'Can\'t map file %s outside %s' % (infile, indir))
255 256
256 filepath = os.path.join(indir, relfile) 257 filepath = os.path.join(indir, relfile)
257 native_filepath = trace_inputs.get_native_path_case(filepath) 258 native_filepath = file_path.get_native_path_case(filepath)
258 if filepath != native_filepath: 259 if filepath != native_filepath:
259 # Special case './'. 260 # Special case './'.
260 if filepath != native_filepath + '.' + os.path.sep: 261 if filepath != native_filepath + '.' + os.path.sep:
261 # Give up enforcing strict path case on OSX. Really, it's that sad. The 262 # Give up enforcing strict path case on OSX. Really, it's that sad. The
262 # case where it happens is very specific and hard to reproduce: 263 # case where it happens is very specific and hard to reproduce:
263 # get_native_path_case( 264 # get_native_path_case(
264 # u'Foo.framework/Versions/A/Resources/Something.nib') will return 265 # u'Foo.framework/Versions/A/Resources/Something.nib') will return
265 # u'Foo.framework/Versions/A/resources/Something.nib', e.g. lowercase 'r'. 266 # u'Foo.framework/Versions/A/resources/Something.nib', e.g. lowercase 'r'.
266 # 267 #
267 # Note that this is really something deep in OSX because running 268 # Note that this is really something deep in OSX because running
268 # ls Foo.framework/Versions/A 269 # ls Foo.framework/Versions/A
269 # will print out 'Resources', while trace_inputs.get_native_path_case() 270 # will print out 'Resources', while file_path.get_native_path_case()
270 # returns a lower case 'r'. 271 # returns a lower case 'r'.
271 # 272 #
272 # So *something* is happening under the hood resulting in the command 'ls' 273 # So *something* is happening under the hood resulting in the command 'ls'
273 # and Carbon.File.FSPathMakeRef('path').FSRefMakePath() to disagree. We 274 # and Carbon.File.FSPathMakeRef('path').FSRefMakePath() to disagree. We
274 # have no idea why. 275 # have no idea why.
275 if sys.platform != 'darwin': 276 if sys.platform != 'darwin':
276 raise isolateserver.MappingError( 277 raise isolateserver.MappingError(
277 'File path doesn\'t equal native file path\n%s != %s' % 278 'File path doesn\'t equal native file path\n%s != %s' %
278 (filepath, native_filepath)) 279 (filepath, native_filepath))
279 280
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
469 if prevdict.get('t') == out['t']: 470 if prevdict.get('t') == out['t']:
470 # Reuse the previous link destination if available. 471 # Reuse the previous link destination if available.
471 out['l'] = prevdict.get('l') 472 out['l'] = prevdict.get('l')
472 if out.get('l') is None: 473 if out.get('l') is None:
473 # The link could be in an incorrect path case. In practice, this only 474 # The link could be in an incorrect path case. In practice, this only
474 # happen on OSX on case insensitive HFS. 475 # happen on OSX on case insensitive HFS.
475 # TODO(maruel): It'd be better if it was only done once, in 476 # TODO(maruel): It'd be better if it was only done once, in
476 # expand_directory_and_symlink(), so it would not be necessary to do again 477 # expand_directory_and_symlink(), so it would not be necessary to do again
477 # here. 478 # here.
478 symlink_value = os.readlink(filepath) # pylint: disable=E1101 479 symlink_value = os.readlink(filepath) # pylint: disable=E1101
479 filedir = trace_inputs.get_native_path_case(os.path.dirname(filepath)) 480 filedir = file_path.get_native_path_case(os.path.dirname(filepath))
480 native_dest = fix_native_path_case(filedir, symlink_value) 481 native_dest = fix_native_path_case(filedir, symlink_value)
481 out['l'] = os.path.relpath(native_dest, filedir) 482 out['l'] = os.path.relpath(native_dest, filedir)
482 return out 483 return out
483 484
484 485
485 ### Variable stuff. 486 ### Variable stuff.
486 487
487 488
488 def isolatedfile_to_state(filename): 489 def isolatedfile_to_state(filename):
489 """Replaces the file's extension.""" 490 """Replaces the file's extension."""
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
523 return variables[m.group(1)] 524 return variables[m.group(1)]
524 return part 525 return part
525 526
526 527
527 def process_variables(cwd, variables, relative_base_dir): 528 def process_variables(cwd, variables, relative_base_dir):
528 """Processes path variables as a special case and returns a copy of the dict. 529 """Processes path variables as a special case and returns a copy of the dict.
529 530
530 For each 'path' variable: first normalizes it based on |cwd|, verifies it 531 For each 'path' variable: first normalizes it based on |cwd|, verifies it
531 exists then sets it as relative to relative_base_dir. 532 exists then sets it as relative to relative_base_dir.
532 """ 533 """
533 relative_base_dir = trace_inputs.get_native_path_case(relative_base_dir) 534 relative_base_dir = file_path.get_native_path_case(relative_base_dir)
534 variables = variables.copy() 535 variables = variables.copy()
535 for i in PATH_VARIABLES: 536 for i in PATH_VARIABLES:
536 if i not in variables: 537 if i not in variables:
537 continue 538 continue
538 variable = variables[i].strip() 539 variable = variables[i].strip()
539 # Variables could contain / or \ on windows. Always normalize to 540 # Variables could contain / or \ on windows. Always normalize to
540 # os.path.sep. 541 # os.path.sep.
541 variable = variable.replace('/', os.path.sep) 542 variable = variable.replace('/', os.path.sep)
542 variable = os.path.join(cwd, variable) 543 variable = os.path.join(cwd, variable)
543 variable = os.path.normpath(variable) 544 variable = os.path.normpath(variable)
544 variable = trace_inputs.get_native_path_case(variable) 545 variable = file_path.get_native_path_case(variable)
545 if not os.path.isdir(variable): 546 if not os.path.isdir(variable):
546 raise ExecutionError('%s=%s is not a directory' % (i, variable)) 547 raise ExecutionError('%s=%s is not a directory' % (i, variable))
547 548
548 # All variables are relative to the .isolate file. 549 # All variables are relative to the .isolate file.
549 variable = os.path.relpath(variable, relative_base_dir) 550 variable = os.path.relpath(variable, relative_base_dir)
550 logging.debug( 551 logging.debug(
551 'Translated variable %s from %s to %s', i, variables[i], variable) 552 'Translated variable %s from %s to %s', i, variables[i], variable)
552 variables[i] = variable 553 variables[i] = variable
553 return variables 554 return variables
554 555
(...skipping 1120 matching lines...) Expand 10 before | Expand all | Expand 10 after
1675 isolatedfile_to_state(isolated_filepath), isolated_basedir)) 1676 isolatedfile_to_state(isolated_filepath), isolated_basedir))
1676 1677
1677 def load_isolate(self, cwd, isolate_file, variables, ignore_broken_items): 1678 def load_isolate(self, cwd, isolate_file, variables, ignore_broken_items):
1678 """Updates self.isolated and self.saved_state with information loaded from a 1679 """Updates self.isolated and self.saved_state with information loaded from a
1679 .isolate file. 1680 .isolate file.
1680 1681
1681 Processes the loaded data, deduce root_dir, relative_cwd. 1682 Processes the loaded data, deduce root_dir, relative_cwd.
1682 """ 1683 """
1683 # Make sure to not depend on os.getcwd(). 1684 # Make sure to not depend on os.getcwd().
1684 assert os.path.isabs(isolate_file), isolate_file 1685 assert os.path.isabs(isolate_file), isolate_file
1685 isolate_file = trace_inputs.get_native_path_case(isolate_file) 1686 isolate_file = file_path.get_native_path_case(isolate_file)
1686 logging.info( 1687 logging.info(
1687 'CompleteState.load_isolate(%s, %s, %s, %s)', 1688 'CompleteState.load_isolate(%s, %s, %s, %s)',
1688 cwd, isolate_file, variables, ignore_broken_items) 1689 cwd, isolate_file, variables, ignore_broken_items)
1689 relative_base_dir = os.path.dirname(isolate_file) 1690 relative_base_dir = os.path.dirname(isolate_file)
1690 1691
1691 # Processes the variables and update the saved state. 1692 # Processes the variables and update the saved state.
1692 variables = process_variables(cwd, variables, relative_base_dir) 1693 variables = process_variables(cwd, variables, relative_base_dir)
1693 self.saved_state.update(isolate_file, variables) 1694 self.saved_state.update(isolate_file, variables)
1694 variables = self.saved_state.variables 1695 variables = self.saved_state.variables
1695 1696
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
1804 raise ExecutionError('Please specify --isolate') 1805 raise ExecutionError('Please specify --isolate')
1805 isolate_dir = os.path.dirname(self.saved_state.isolate_filepath) 1806 isolate_dir = os.path.dirname(self.saved_state.isolate_filepath)
1806 # Special case '.'. 1807 # Special case '.'.
1807 if self.saved_state.relative_cwd == '.': 1808 if self.saved_state.relative_cwd == '.':
1808 root_dir = isolate_dir 1809 root_dir = isolate_dir
1809 else: 1810 else:
1810 assert isolate_dir.endswith(self.saved_state.relative_cwd), ( 1811 assert isolate_dir.endswith(self.saved_state.relative_cwd), (
1811 isolate_dir, self.saved_state.relative_cwd) 1812 isolate_dir, self.saved_state.relative_cwd)
1812 # Walk back back to the root directory. 1813 # Walk back back to the root directory.
1813 root_dir = isolate_dir[:-(len(self.saved_state.relative_cwd) + 1)] 1814 root_dir = isolate_dir[:-(len(self.saved_state.relative_cwd) + 1)]
1814 return trace_inputs.get_native_path_case(root_dir) 1815 return file_path.get_native_path_case(root_dir)
1815 1816
1816 @property 1817 @property
1817 def resultdir(self): 1818 def resultdir(self):
1818 """Returns the absolute path containing the .isolated file. 1819 """Returns the absolute path containing the .isolated file.
1819 1820
1820 It is usually equivalent to the variable PRODUCT_DIR. Uses the .isolated 1821 It is usually equivalent to the variable PRODUCT_DIR. Uses the .isolated
1821 path as the value. 1822 path as the value.
1822 """ 1823 """
1823 return os.path.dirname(self.isolated_filepath) 1824 return os.path.dirname(self.isolated_filepath)
1824 1825
(...skipping 20 matching lines...) Expand all
1845 options.isolate and options.isolated, if the value is set, it is an 1846 options.isolate and options.isolated, if the value is set, it is an
1846 absolute path. 1847 absolute path.
1847 cwd: base directory to be used when loading the .isolate file. 1848 cwd: base directory to be used when loading the .isolate file.
1848 subdir: optional argument to only process file in the subdirectory, relative 1849 subdir: optional argument to only process file in the subdirectory, relative
1849 to CompleteState.root_dir. 1850 to CompleteState.root_dir.
1850 skip_update: Skip trying to load the .isolate file and processing the 1851 skip_update: Skip trying to load the .isolate file and processing the
1851 dependencies. It is useful when not needed, like when tracing. 1852 dependencies. It is useful when not needed, like when tracing.
1852 """ 1853 """
1853 assert not options.isolate or os.path.isabs(options.isolate) 1854 assert not options.isolate or os.path.isabs(options.isolate)
1854 assert not options.isolated or os.path.isabs(options.isolated) 1855 assert not options.isolated or os.path.isabs(options.isolated)
1855 cwd = trace_inputs.get_native_path_case(unicode(cwd)) 1856 cwd = file_path.get_native_path_case(unicode(cwd))
1856 if options.isolated: 1857 if options.isolated:
1857 # Load the previous state if it was present. Namely, "foo.isolated.state". 1858 # Load the previous state if it was present. Namely, "foo.isolated.state".
1858 # Note: this call doesn't load the .isolate file. 1859 # Note: this call doesn't load the .isolate file.
1859 complete_state = CompleteState.load_files(options.isolated) 1860 complete_state = CompleteState.load_files(options.isolated)
1860 else: 1861 else:
1861 # Constructs a dummy object that cannot be saved. Useful for temporary 1862 # Constructs a dummy object that cannot be saved. Useful for temporary
1862 # commands like 'run'. 1863 # commands like 'run'.
1863 complete_state = CompleteState(None, SavedState()) 1864 complete_state = CompleteState(None, SavedState())
1864 1865
1865 if not options.isolate: 1866 if not options.isolate:
(...skipping 548 matching lines...) Expand 10 before | Expand all | Expand 10 after
2414 def parse_args(self, *args, **kwargs): 2415 def parse_args(self, *args, **kwargs):
2415 """Makes sure the paths make sense. 2416 """Makes sure the paths make sense.
2416 2417
2417 On Windows, / and \ are often mixed together in a path. 2418 On Windows, / and \ are often mixed together in a path.
2418 """ 2419 """
2419 options, args = tools.OptionParserWithLogging.parse_args( 2420 options, args = tools.OptionParserWithLogging.parse_args(
2420 self, *args, **kwargs) 2421 self, *args, **kwargs)
2421 if not self.allow_interspersed_args and args: 2422 if not self.allow_interspersed_args and args:
2422 self.error('Unsupported argument: %s' % args) 2423 self.error('Unsupported argument: %s' % args)
2423 2424
2424 cwd = trace_inputs.get_native_path_case(unicode(os.getcwd())) 2425 cwd = file_path.get_native_path_case(unicode(os.getcwd()))
2425 parse_isolated_option(self, options, cwd, self.require_isolated) 2426 parse_isolated_option(self, options, cwd, self.require_isolated)
2426 parse_variable_option(options) 2427 parse_variable_option(options)
2427 2428
2428 if options.isolate: 2429 if options.isolate:
2429 # TODO(maruel): Work with non-ASCII. 2430 # TODO(maruel): Work with non-ASCII.
2430 # The path must be in native path case for tracing purposes. 2431 # The path must be in native path case for tracing purposes.
2431 options.isolate = unicode(options.isolate).replace('/', os.path.sep) 2432 options.isolate = unicode(options.isolate).replace('/', os.path.sep)
2432 options.isolate = os.path.normpath(os.path.join(cwd, options.isolate)) 2433 options.isolate = os.path.normpath(os.path.join(cwd, options.isolate))
2433 options.isolate = trace_inputs.get_native_path_case(options.isolate) 2434 options.isolate = file_path.get_native_path_case(options.isolate)
2434 2435
2435 if options.outdir and not is_url(options.outdir): 2436 if options.outdir and not is_url(options.outdir):
2436 options.outdir = unicode(options.outdir).replace('/', os.path.sep) 2437 options.outdir = unicode(options.outdir).replace('/', os.path.sep)
2437 # outdir doesn't need native path case since tracing is never done from 2438 # outdir doesn't need native path case since tracing is never done from
2438 # there. 2439 # there.
2439 options.outdir = os.path.normpath(os.path.join(cwd, options.outdir)) 2440 options.outdir = os.path.normpath(os.path.join(cwd, options.outdir))
2440 2441
2441 return options, args 2442 return options, args
2442 2443
2443 2444
2444 def main(argv): 2445 def main(argv):
2445 dispatcher = subcommand.CommandDispatcher(__name__) 2446 dispatcher = subcommand.CommandDispatcher(__name__)
2446 try: 2447 try:
2447 return dispatcher.execute(OptionParserIsolate(version=__version__), argv) 2448 return dispatcher.execute(OptionParserIsolate(version=__version__), argv)
2448 except ( 2449 except (
2449 ExecutionError, 2450 ExecutionError,
2450 isolateserver.ConfigError, 2451 isolateserver.ConfigError,
2451 isolateserver.MappingError) as e: 2452 isolateserver.MappingError) as e:
2452 sys.stderr.write('\nError: ') 2453 sys.stderr.write('\nError: ')
2453 sys.stderr.write(str(e)) 2454 sys.stderr.write(str(e))
2454 sys.stderr.write('\n') 2455 sys.stderr.write('\n')
2455 return 1 2456 return 1
2456 2457
2457 2458
2458 if __name__ == '__main__': 2459 if __name__ == '__main__':
2459 fix_encoding.fix_encoding() 2460 fix_encoding.fix_encoding()
2460 tools.disable_buffering() 2461 tools.disable_buffering()
2461 colorama.init() 2462 colorama.init()
2462 sys.exit(main(sys.argv[1:])) 2463 sys.exit(main(sys.argv[1:]))
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698