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

Side by Side Diff: bootstrap/run_helper.py

Issue 1200843003: Added virtualenv for depot_tools (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/depot_tools
Patch Set: Fix on Windows Created 5 years, 6 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
OLDNEW
(Empty)
1 #!/usr/bin/env python
2 # Copyright 2014 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 """Code supporting run.py implementation.
7
8 Reused across infra/run.py and infra_internal/run.py.
9 """
10
11 import os
12 import sys
13
14
15 def is_in_venv(env_path):
16 """True if already running in virtual env."""
17 abs_prefix = os.path.abspath(sys.prefix)
18 abs_env_path = os.path.abspath(env_path)
19 if abs_prefix == abs_env_path:
20 return True
21 # Ordinarily os.path.abspath(sys.prefix) == env_path is enough. But it doesn't
22 # work when virtual env is deployed as CIPD package. CIPD uses symlinks to
23 # stage files into installation root. When booting venv, something (python
24 # binary itself?) resolves the symlink ENV/bin/python to the target, making
25 # sys.prefix look like "<root>/.cipd/.../ENV". Note that "<root>/ENV" is not
26 # a symlink itself, but "<root>/ENV/bin/python" is.
27 if sys.platform == 'win32':
28 # TODO(vadimsh): Make it work for Win32 too.
29 return False
30 try:
31 return os.path.samefile(
32 os.path.join(abs_prefix, 'bin', 'python'),
33 os.path.join(abs_env_path, 'bin', 'python'))
34 except OSError:
35 return False
36
37
38 def boot_venv(script, env_path):
39 """Reexecs the top-level script in a virtualenv (if necessary)."""
40 RUN_PY_RECURSION_BLOCKER = 'RUN_PY_RECURSION'
41
42 if not is_in_venv(env_path):
43 if RUN_PY_RECURSION_BLOCKER in os.environ:
44 print >> sys.stderr, 'TOO MUCH RECURSION IN RUN.PY'
45 sys.exit(-1)
46
47 # not in the venv
48 if sys.platform.startswith('win'):
49 python = os.path.join(env_path, 'Scripts', 'python.exe')
50 else:
51 python = os.path.join(env_path, 'bin', 'python')
52 if os.path.exists(python):
53 os.environ[RUN_PY_RECURSION_BLOCKER] = "1"
54 os.environ.pop('PYTHONPATH', None)
55 os.execv(python, [python, script] + sys.argv[1:])
56 print >> sys.stderr, "Exec is busted :("
57 sys.exit(-1) # should never reach
58
59 print 'You must use the virtualenv in ENV for scripts in the infra repo.'
60 print 'Running `gclient runhooks` will create this environment for you.'
61 sys.exit(1)
62
63 # In case some poor script ends up calling run.py, don't explode them.
64 os.environ.pop(RUN_PY_RECURSION_BLOCKER, None)
65
66
67 def run_py_main(args, runpy_path, env_path, package):
68 boot_venv(runpy_path, env_path)
69
70 import argparse
71 import runpy
72 import shlex
73 import textwrap
74
75 import argcomplete
76
77 os.chdir(os.path.dirname(runpy_path))
78
79 # Impersonate the argcomplete 'protocol'
80 completing = os.getenv('_ARGCOMPLETE') == '1'
81 if completing:
82 assert not args
83 line = os.getenv('COMP_LINE')
84 args = shlex.split(line)[1:]
85 if len(args) == 1 and not line.endswith(' '):
86 args = []
87
88 if not args or not args[0].startswith('%s.' % package):
89 commands = []
90 for root, _, files in os.walk(package):
91 if '__main__.py' in files:
92 commands.append(root.replace(os.path.sep, '.'))
93
94 if completing:
95 # Argcomplete is listening for strings on fd 8
96 with os.fdopen(8, 'wb') as f:
97 print >> f, '\n'.join(commands)
98 return
99
100 print textwrap.dedent("""\
101 usage: run.py %s.<module.path.to.tool> [args for tool]
102
103 %s
104
105 Available tools are:""") % (
106 package, sys.modules['__main__'].__doc__.strip())
107 for command in commands:
108 print ' *', command
109 return 1
110
111 if completing:
112 to_nuke = ' ' + args[0]
113 os.environ['COMP_LINE'] = os.environ['COMP_LINE'].replace(to_nuke, '', 1)
114 os.environ['COMP_POINT'] = str(int(os.environ['COMP_POINT']) - len(to_nuke))
115 orig_parse_args = argparse.ArgumentParser.parse_args
116 def new_parse_args(self, *args, **kwargs):
117 argcomplete.autocomplete(self)
118 return orig_parse_args(*args, **kwargs)
119 argparse.ArgumentParser.parse_args = new_parse_args
120 else:
121 # remove the module from sys.argv
122 del sys.argv[1]
123
124 runpy.run_module(args[0], run_name='__main__', alter_sys=True)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698