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

Side by Side Diff: tools/isolate/isolate.py

Issue 9513003: Add target base_unittests_run and tools/isolate/isolate.py. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Remove directory from 'inputs' Created 8 years, 9 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 | « tools/isolate/PRESUBMIT.py ('k') | tools/isolate/isolate_test.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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 """Does one of the following depending on the --mode argument:
7 check verify all the inputs exist, touches the file specified with
8 --result and exits.
9 run recreates a tree with all the inputs files and run the executable
10 in it.
11 remap stores all the inputs files in a directory without running the
12 executable.
13 """
14
15 import logging
16 import optparse
17 import os
18 import re
19 import shutil
20 import subprocess
21 import sys
22 import tempfile
23 import time
24
25 import tree_creator
26
27
28 def touch(filename):
29 """Implements the equivalent of the 'touch' command."""
30 if not os.path.exists(filename):
31 open(filename, 'a').close()
32 os.utime(filename, None)
33
34
35 def rmtree(root):
36 """Wrapper around shutil.rmtree() to retry automatically on Windows."""
37 if sys.platform == 'win32':
38 for i in range(3):
39 try:
40 shutil.rmtree(root)
41 break
42 except WindowsError: # pylint: disable=E0602
43 delay = (i+1)*2
44 print >> sys.stderr, (
45 'The test has subprocess outliving it. Sleep %d seconds.' % delay)
46 time.sleep(delay)
47 else:
48 shutil.rmtree(root)
49
50
51 def isolate(outdir, root, resultfile, mode, read_only, args):
52 """Main function to isolate a target with its dependencies."""
53 cmd = []
54 if '--' in args:
55 # Strip off the command line from the inputs.
56 i = args.index('--')
57 cmd = args[i+1:]
58 args = args[:i]
59
60 # gyp provides paths relative to cwd. Convert them to be relative to
61 # root.
62 cwd = os.getcwd()
63
64 def make_relpath(i):
65 """Makes an input file a relative path but keeps any trailing slash."""
66 out = os.path.relpath(os.path.join(cwd, i), root)
67 if i.endswith('/'):
68 out += '/'
69 return out
70
71 infiles = [make_relpath(i) for i in args]
72
73 if not infiles:
74 raise ValueError('Need at least one input file to map')
75
76 # Other modes ignore the command.
77 if mode == 'run' and not cmd:
78 print >> sys.stderr, 'Using first input %s as executable' % infiles[0]
79 cmd = [infiles[0]]
80
81 tempdir = None
82 try:
83 if not outdir and mode != 'check':
84 tempdir = tempfile.mkdtemp(prefix='isolate')
85 outdir = tempdir
86 elif outdir:
87 outdir = os.path.abspath(outdir)
88
89 tree_creator.recreate_tree(
90 outdir,
91 os.path.abspath(root),
92 infiles,
93 tree_creator.DRY_RUN if mode == 'check' else tree_creator.HARDLINK,
94 lambda x: re.match(r'.*\.(svn|pyc)$', x))
95
96 if mode != 'check' and read_only:
97 tree_creator.make_writable(outdir, True)
98
99 if mode in ('check', 'remap'):
100 result = 0
101 else:
102 # TODO(maruel): Remove me. Layering violation. Used by
103 # base/base_paths_linux.cc
104 env = os.environ.copy()
105 env['CR_SOURCE_ROOT'] = outdir.encode()
106 # Rebase the command to the right path.
107 cmd[0] = os.path.join(outdir, cmd[0])
108 logging.info('Running %s' % cmd)
109 result = subprocess.call(cmd, cwd=outdir, env=env)
110
111 if not result and resultfile:
112 # Signal the build tool that the test succeeded.
113 touch(resultfile)
114 return result
115 finally:
116 if tempdir and mode == 'isolate':
117 if read_only:
118 tree_creator.make_writable(tempdir, False)
119 rmtree(tempdir)
120
121
122 def main():
123 parser = optparse.OptionParser(
124 usage='%prog [options] [inputs] -- [command line]',
125 description=sys.modules[__name__].__doc__)
126 parser.allow_interspersed_args = False
127 parser.format_description = lambda *_: parser.description
128 parser.add_option(
129 '-v', '--verbose', action='count', default=0, help='Use multiple times')
130 parser.add_option(
131 '--mode', choices=['remap', 'check', 'run'],
132 help='Determines the action to be taken')
133 parser.add_option(
134 '--result', metavar='X',
135 help='File to be touched when the command succeeds')
136 parser.add_option('--root', help='Base directory to fetch files, required')
137 parser.add_option(
138 '--outdir', metavar='X',
139 help='Directory used to recreate the tree. Defaults to a /tmp '
140 'subdirectory')
141 parser.add_option(
142 '--read-only', action='store_true',
143 help='Make the temporary tree read-only')
144
145 options, args = parser.parse_args()
146 level = [logging.ERROR, logging.INFO, logging.DEBUG][min(2, options.verbose)]
147 logging.basicConfig(
148 level=level,
149 format='%(levelname)5s %(module)15s(%(lineno)3d): %(message)s')
150
151 if not options.root:
152 parser.error('--root is required.')
153
154 try:
155 return isolate(
156 options.outdir,
157 options.root,
158 options.result,
159 options.mode,
160 options.read_only,
161 args)
162 except ValueError, e:
163 parser.error(str(e))
164
165
166 if __name__ == '__main__':
167 sys.exit(main())
OLDNEW
« no previous file with comments | « tools/isolate/PRESUBMIT.py ('k') | tools/isolate/isolate_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698