summaryrefslogtreecommitdiffstats
path: root/main.py
diff options
context:
space:
mode:
Diffstat (limited to 'main.py')
-rwxr-xr-xmain.py158
1 files changed, 82 insertions, 76 deletions
diff --git a/main.py b/main.py
index ba40d56b..9cc2639a 100755
--- a/main.py
+++ b/main.py
@@ -1,4 +1,4 @@
1#!/bin/sh 1#!/usr/bin/env python
2# 2#
3# Copyright (C) 2008 The Android Open Source Project 3# Copyright (C) 2008 The Android Open Source Project
4# 4#
@@ -14,23 +14,23 @@
14# See the License for the specific language governing permissions and 14# See the License for the specific language governing permissions and
15# limitations under the License. 15# limitations under the License.
16 16
17magic='--calling-python-from-/bin/sh--' 17from __future__ import print_function
18"""exec" python -E "$0" "$@" """#$magic"
19if __name__ == '__main__':
20 import sys
21 if sys.argv[-1] == '#%s' % magic:
22 del sys.argv[-1]
23del magic
24
25import getpass 18import getpass
26import imp 19import imp
27import netrc 20import netrc
28import optparse 21import optparse
29import os 22import os
30import re
31import sys 23import sys
32import time 24import time
33import urllib2 25try:
26 import urllib2
27except ImportError:
28 # For python3
29 import urllib.request
30else:
31 # For python2
32 urllib = imp.new_module('urllib')
33 urllib.request = urllib2
34 34
35from trace import SetTrace 35from trace import SetTrace
36from git_command import git, GitCommand 36from git_command import git, GitCommand
@@ -41,6 +41,8 @@ from subcmds.version import Version
41from editor import Editor 41from editor import Editor
42from error import DownloadError 42from error import DownloadError
43from error import ManifestInvalidRevisionError 43from error import ManifestInvalidRevisionError
44from error import ManifestParseError
45from error import NoManifestException
44from error import NoSuchProjectError 46from error import NoSuchProjectError
45from error import RepoChangedException 47from error import RepoChangedException
46from manifest_xml import XmlManifest 48from manifest_xml import XmlManifest
@@ -79,7 +81,7 @@ class _Repo(object):
79 name = None 81 name = None
80 glob = [] 82 glob = []
81 83
82 for i in xrange(0, len(argv)): 84 for i in range(len(argv)):
83 if not argv[i].startswith('-'): 85 if not argv[i].startswith('-'):
84 name = argv[i] 86 name = argv[i]
85 if i > 0: 87 if i > 0:
@@ -98,15 +100,14 @@ class _Repo(object):
98 if name == 'help': 100 if name == 'help':
99 name = 'version' 101 name = 'version'
100 else: 102 else:
101 print >>sys.stderr, 'fatal: invalid usage of --version' 103 print('fatal: invalid usage of --version', file=sys.stderr)
102 return 1 104 return 1
103 105
104 try: 106 try:
105 cmd = self.commands[name] 107 cmd = self.commands[name]
106 except KeyError: 108 except KeyError:
107 print >>sys.stderr,\ 109 print("repo: '%s' is not a repo command. See 'repo help'." % name,
108 "repo: '%s' is not a repo command. See 'repo help'."\ 110 file=sys.stderr)
109 % name
110 return 1 111 return 1
111 112
112 cmd.repodir = self.repodir 113 cmd.repodir = self.repodir
@@ -114,12 +115,12 @@ class _Repo(object):
114 Editor.globalConfig = cmd.manifest.globalConfig 115 Editor.globalConfig = cmd.manifest.globalConfig
115 116
116 if not isinstance(cmd, MirrorSafeCommand) and cmd.manifest.IsMirror: 117 if not isinstance(cmd, MirrorSafeCommand) and cmd.manifest.IsMirror:
117 print >>sys.stderr, \ 118 print("fatal: '%s' requires a working directory" % name,
118 "fatal: '%s' requires a working directory"\ 119 file=sys.stderr)
119 % name
120 return 1 120 return 1
121 121
122 copts, cargs = cmd.OptionParser.parse_args(argv) 122 copts, cargs = cmd.OptionParser.parse_args(argv)
123 copts = cmd.ReadEnvironmentOptions(copts)
123 124
124 if not gopts.no_pager and not isinstance(cmd, InteractiveCommand): 125 if not gopts.no_pager and not isinstance(cmd, InteractiveCommand):
125 config = cmd.manifest.globalConfig 126 config = cmd.manifest.globalConfig
@@ -132,33 +133,35 @@ class _Repo(object):
132 if use_pager: 133 if use_pager:
133 RunPager(config) 134 RunPager(config)
134 135
136 start = time.time()
135 try: 137 try:
136 start = time.time() 138 result = cmd.Execute(copts, cargs)
137 try:
138 result = cmd.Execute(copts, cargs)
139 finally:
140 elapsed = time.time() - start
141 hours, remainder = divmod(elapsed, 3600)
142 minutes, seconds = divmod(remainder, 60)
143 if gopts.time:
144 if hours == 0:
145 print >>sys.stderr, 'real\t%dm%.3fs' \
146 % (minutes, seconds)
147 else:
148 print >>sys.stderr, 'real\t%dh%dm%.3fs' \
149 % (hours, minutes, seconds)
150 except DownloadError as e: 139 except DownloadError as e:
151 print >>sys.stderr, 'error: %s' % str(e) 140 print('error: %s' % str(e), file=sys.stderr)
152 return 1 141 result = 1
153 except ManifestInvalidRevisionError as e: 142 except ManifestInvalidRevisionError as e:
154 print >>sys.stderr, 'error: %s' % str(e) 143 print('error: %s' % str(e), file=sys.stderr)
155 return 1 144 result = 1
145 except NoManifestException as e:
146 print('error: manifest required for this command -- please run init',
147 file=sys.stderr)
148 result = 1
156 except NoSuchProjectError as e: 149 except NoSuchProjectError as e:
157 if e.name: 150 if e.name:
158 print >>sys.stderr, 'error: project %s not found' % e.name 151 print('error: project %s not found' % e.name, file=sys.stderr)
159 else: 152 else:
160 print >>sys.stderr, 'error: no project in current directory' 153 print('error: no project in current directory', file=sys.stderr)
161 return 1 154 result = 1
155 finally:
156 elapsed = time.time() - start
157 hours, remainder = divmod(elapsed, 3600)
158 minutes, seconds = divmod(remainder, 60)
159 if gopts.time:
160 if hours == 0:
161 print('real\t%dm%.3fs' % (minutes, seconds), file=sys.stderr)
162 else:
163 print('real\t%dh%dm%.3fs' % (hours, minutes, seconds),
164 file=sys.stderr)
162 165
163 return result 166 return result
164 167
@@ -183,36 +186,35 @@ def _CheckWrapperVersion(ver, repo_path):
183 repo_path = '~/bin/repo' 186 repo_path = '~/bin/repo'
184 187
185 if not ver: 188 if not ver:
186 print >>sys.stderr, 'no --wrapper-version argument' 189 print('no --wrapper-version argument', file=sys.stderr)
187 sys.exit(1) 190 sys.exit(1)
188 191
189 exp = _CurrentWrapperVersion() 192 exp = _CurrentWrapperVersion()
190 ver = tuple(map(lambda x: int(x), ver.split('.'))) 193 ver = tuple(map(int, ver.split('.')))
191 if len(ver) == 1: 194 if len(ver) == 1:
192 ver = (0, ver[0]) 195 ver = (0, ver[0])
193 196
197 exp_str = '.'.join(map(str, exp))
194 if exp[0] > ver[0] or ver < (0, 4): 198 if exp[0] > ver[0] or ver < (0, 4):
195 exp_str = '.'.join(map(lambda x: str(x), exp)) 199 print("""
196 print >>sys.stderr, """
197!!! A new repo command (%5s) is available. !!! 200!!! A new repo command (%5s) is available. !!!
198!!! You must upgrade before you can continue: !!! 201!!! You must upgrade before you can continue: !!!
199 202
200 cp %s %s 203 cp %s %s
201""" % (exp_str, _MyWrapperPath(), repo_path) 204""" % (exp_str, _MyWrapperPath(), repo_path), file=sys.stderr)
202 sys.exit(1) 205 sys.exit(1)
203 206
204 if exp > ver: 207 if exp > ver:
205 exp_str = '.'.join(map(lambda x: str(x), exp)) 208 print("""
206 print >>sys.stderr, """
207... A new repo command (%5s) is available. 209... A new repo command (%5s) is available.
208... You should upgrade soon: 210... You should upgrade soon:
209 211
210 cp %s %s 212 cp %s %s
211""" % (exp_str, _MyWrapperPath(), repo_path) 213""" % (exp_str, _MyWrapperPath(), repo_path), file=sys.stderr)
212 214
213def _CheckRepoDir(repo_dir): 215def _CheckRepoDir(repo_dir):
214 if not repo_dir: 216 if not repo_dir:
215 print >>sys.stderr, 'no --repo-dir argument' 217 print('no --repo-dir argument', file=sys.stderr)
216 sys.exit(1) 218 sys.exit(1)
217 219
218def _PruneOptions(argv, opt): 220def _PruneOptions(argv, opt):
@@ -264,11 +266,11 @@ def _UserAgent():
264 _user_agent = 'git-repo/%s (%s) git/%s Python/%d.%d.%d' % ( 266 _user_agent = 'git-repo/%s (%s) git/%s Python/%d.%d.%d' % (
265 repo_version, 267 repo_version,
266 os_name, 268 os_name,
267 '.'.join(map(lambda d: str(d), git.version_tuple())), 269 '.'.join(map(str, git.version_tuple())),
268 py_version[0], py_version[1], py_version[2]) 270 py_version[0], py_version[1], py_version[2])
269 return _user_agent 271 return _user_agent
270 272
271class _UserAgentHandler(urllib2.BaseHandler): 273class _UserAgentHandler(urllib.request.BaseHandler):
272 def http_request(self, req): 274 def http_request(self, req):
273 req.add_header('User-Agent', _UserAgent()) 275 req.add_header('User-Agent', _UserAgent())
274 return req 276 return req
@@ -278,22 +280,22 @@ class _UserAgentHandler(urllib2.BaseHandler):
278 return req 280 return req
279 281
280def _AddPasswordFromUserInput(handler, msg, req): 282def _AddPasswordFromUserInput(handler, msg, req):
281 # If repo could not find auth info from netrc, try to get it from user input 283 # If repo could not find auth info from netrc, try to get it from user input
282 url = req.get_full_url() 284 url = req.get_full_url()
283 user, password = handler.passwd.find_user_password(None, url) 285 user, password = handler.passwd.find_user_password(None, url)
284 if user is None: 286 if user is None:
285 print msg 287 print(msg)
286 try: 288 try:
287 user = raw_input('User: ') 289 user = raw_input('User: ')
288 password = getpass.getpass() 290 password = getpass.getpass()
289 except KeyboardInterrupt: 291 except KeyboardInterrupt:
290 return 292 return
291 handler.passwd.add_password(None, url, user, password) 293 handler.passwd.add_password(None, url, user, password)
292 294
293class _BasicAuthHandler(urllib2.HTTPBasicAuthHandler): 295class _BasicAuthHandler(urllib.request.HTTPBasicAuthHandler):
294 def http_error_401(self, req, fp, code, msg, headers): 296 def http_error_401(self, req, fp, code, msg, headers):
295 _AddPasswordFromUserInput(self, msg, req) 297 _AddPasswordFromUserInput(self, msg, req)
296 return urllib2.HTTPBasicAuthHandler.http_error_401( 298 return urllib.request.HTTPBasicAuthHandler.http_error_401(
297 self, req, fp, code, msg, headers) 299 self, req, fp, code, msg, headers)
298 300
299 def http_error_auth_reqed(self, authreq, host, req, headers): 301 def http_error_auth_reqed(self, authreq, host, req, headers):
@@ -303,7 +305,7 @@ class _BasicAuthHandler(urllib2.HTTPBasicAuthHandler):
303 val = val.replace('\n', '') 305 val = val.replace('\n', '')
304 old_add_header(name, val) 306 old_add_header(name, val)
305 req.add_header = _add_header 307 req.add_header = _add_header
306 return urllib2.AbstractBasicAuthHandler.http_error_auth_reqed( 308 return urllib.request.AbstractBasicAuthHandler.http_error_auth_reqed(
307 self, authreq, host, req, headers) 309 self, authreq, host, req, headers)
308 except: 310 except:
309 reset = getattr(self, 'reset_retry_count', None) 311 reset = getattr(self, 'reset_retry_count', None)
@@ -313,10 +315,10 @@ class _BasicAuthHandler(urllib2.HTTPBasicAuthHandler):
313 self.retried = 0 315 self.retried = 0
314 raise 316 raise
315 317
316class _DigestAuthHandler(urllib2.HTTPDigestAuthHandler): 318class _DigestAuthHandler(urllib.request.HTTPDigestAuthHandler):
317 def http_error_401(self, req, fp, code, msg, headers): 319 def http_error_401(self, req, fp, code, msg, headers):
318 _AddPasswordFromUserInput(self, msg, req) 320 _AddPasswordFromUserInput(self, msg, req)
319 return urllib2.HTTPDigestAuthHandler.http_error_401( 321 return urllib.request.HTTPDigestAuthHandler.http_error_401(
320 self, req, fp, code, msg, headers) 322 self, req, fp, code, msg, headers)
321 323
322 def http_error_auth_reqed(self, auth_header, host, req, headers): 324 def http_error_auth_reqed(self, auth_header, host, req, headers):
@@ -326,7 +328,7 @@ class _DigestAuthHandler(urllib2.HTTPDigestAuthHandler):
326 val = val.replace('\n', '') 328 val = val.replace('\n', '')
327 old_add_header(name, val) 329 old_add_header(name, val)
328 req.add_header = _add_header 330 req.add_header = _add_header
329 return urllib2.AbstractDigestAuthHandler.http_error_auth_reqed( 331 return urllib.request.AbstractDigestAuthHandler.http_error_auth_reqed(
330 self, auth_header, host, req, headers) 332 self, auth_header, host, req, headers)
331 except: 333 except:
332 reset = getattr(self, 'reset_retry_count', None) 334 reset = getattr(self, 'reset_retry_count', None)
@@ -339,7 +341,7 @@ class _DigestAuthHandler(urllib2.HTTPDigestAuthHandler):
339def init_http(): 341def init_http():
340 handlers = [_UserAgentHandler()] 342 handlers = [_UserAgentHandler()]
341 343
342 mgr = urllib2.HTTPPasswordMgrWithDefaultRealm() 344 mgr = urllib.request.HTTPPasswordMgrWithDefaultRealm()
343 try: 345 try:
344 n = netrc.netrc() 346 n = netrc.netrc()
345 for host in n.hosts: 347 for host in n.hosts:
@@ -355,11 +357,11 @@ def init_http():
355 357
356 if 'http_proxy' in os.environ: 358 if 'http_proxy' in os.environ:
357 url = os.environ['http_proxy'] 359 url = os.environ['http_proxy']
358 handlers.append(urllib2.ProxyHandler({'http': url, 'https': url})) 360 handlers.append(urllib.request.ProxyHandler({'http': url, 'https': url}))
359 if 'REPO_CURL_VERBOSE' in os.environ: 361 if 'REPO_CURL_VERBOSE' in os.environ:
360 handlers.append(urllib2.HTTPHandler(debuglevel=1)) 362 handlers.append(urllib.request.HTTPHandler(debuglevel=1))
361 handlers.append(urllib2.HTTPSHandler(debuglevel=1)) 363 handlers.append(urllib.request.HTTPSHandler(debuglevel=1))
362 urllib2.install_opener(urllib2.build_opener(*handlers)) 364 urllib.request.install_opener(urllib.request.build_opener(*handlers))
363 365
364def _Main(argv): 366def _Main(argv):
365 result = 0 367 result = 0
@@ -389,6 +391,10 @@ def _Main(argv):
389 finally: 391 finally:
390 close_ssh() 392 close_ssh()
391 except KeyboardInterrupt: 393 except KeyboardInterrupt:
394 print('aborted by user', file=sys.stderr)
395 result = 1
396 except ManifestParseError as mpe:
397 print('fatal: %s' % mpe, file=sys.stderr)
392 result = 1 398 result = 1
393 except RepoChangedException as rce: 399 except RepoChangedException as rce:
394 # If repo changed, re-exec ourselves. 400 # If repo changed, re-exec ourselves.
@@ -398,8 +404,8 @@ def _Main(argv):
398 try: 404 try:
399 os.execv(__file__, argv) 405 os.execv(__file__, argv)
400 except OSError as e: 406 except OSError as e:
401 print >>sys.stderr, 'fatal: cannot restart repo after upgrade' 407 print('fatal: cannot restart repo after upgrade', file=sys.stderr)
402 print >>sys.stderr, 'fatal: %s' % e 408 print('fatal: %s' % e, file=sys.stderr)
403 result = 128 409 result = 128
404 410
405 sys.exit(result) 411 sys.exit(result)