summaryrefslogtreecommitdiffstats
path: root/main.py
diff options
context:
space:
mode:
Diffstat (limited to 'main.py')
-rwxr-xr-xmain.py169
1 files changed, 160 insertions, 9 deletions
diff --git a/main.py b/main.py
index 07b26ef7..ea29851e 100755
--- a/main.py
+++ b/main.py
@@ -22,19 +22,27 @@ if __name__ == '__main__':
22 del sys.argv[-1] 22 del sys.argv[-1]
23del magic 23del magic
24 24
25import netrc
25import optparse 26import optparse
26import os 27import os
27import re 28import re
28import sys 29import sys
30import time
31import urllib2
29 32
30from trace import SetTrace 33from trace import SetTrace
34from git_command import git, GitCommand
31from git_config import init_ssh, close_ssh 35from git_config import init_ssh, close_ssh
32from command import InteractiveCommand 36from command import InteractiveCommand
33from command import MirrorSafeCommand 37from command import MirrorSafeCommand
34from command import PagedCommand 38from command import PagedCommand
39from subcmds.version import Version
40from editor import Editor
41from error import DownloadError
35from error import ManifestInvalidRevisionError 42from error import ManifestInvalidRevisionError
36from error import NoSuchProjectError 43from error import NoSuchProjectError
37from error import RepoChangedException 44from error import RepoChangedException
45from manifest_xml import XmlManifest
38from pager import RunPager 46from pager import RunPager
39 47
40from subcmds import all as all_commands 48from subcmds import all as all_commands
@@ -51,6 +59,9 @@ global_options.add_option('--no-pager',
51global_options.add_option('--trace', 59global_options.add_option('--trace',
52 dest='trace', action='store_true', 60 dest='trace', action='store_true',
53 help='trace git command execution') 61 help='trace git command execution')
62global_options.add_option('--time',
63 dest='time', action='store_true',
64 help='time repo command execution')
54global_options.add_option('--version', 65global_options.add_option('--version',
55 dest='show_version', action='store_true', 66 dest='show_version', action='store_true',
56 help='display this version of repo') 67 help='display this version of repo')
@@ -63,6 +74,7 @@ class _Repo(object):
63 all_commands['branch'] = all_commands['branches'] 74 all_commands['branch'] = all_commands['branches']
64 75
65 def _Run(self, argv): 76 def _Run(self, argv):
77 result = 0
66 name = None 78 name = None
67 glob = [] 79 glob = []
68 80
@@ -86,7 +98,7 @@ class _Repo(object):
86 name = 'version' 98 name = 'version'
87 else: 99 else:
88 print >>sys.stderr, 'fatal: invalid usage of --version' 100 print >>sys.stderr, 'fatal: invalid usage of --version'
89 sys.exit(1) 101 return 1
90 102
91 try: 103 try:
92 cmd = self.commands[name] 104 cmd = self.commands[name]
@@ -94,15 +106,17 @@ class _Repo(object):
94 print >>sys.stderr,\ 106 print >>sys.stderr,\
95 "repo: '%s' is not a repo command. See 'repo help'."\ 107 "repo: '%s' is not a repo command. See 'repo help'."\
96 % name 108 % name
97 sys.exit(1) 109 return 1
98 110
99 cmd.repodir = self.repodir 111 cmd.repodir = self.repodir
112 cmd.manifest = XmlManifest(cmd.repodir)
113 Editor.globalConfig = cmd.manifest.globalConfig
100 114
101 if not isinstance(cmd, MirrorSafeCommand) and cmd.manifest.IsMirror: 115 if not isinstance(cmd, MirrorSafeCommand) and cmd.manifest.IsMirror:
102 print >>sys.stderr, \ 116 print >>sys.stderr, \
103 "fatal: '%s' requires a working directory"\ 117 "fatal: '%s' requires a working directory"\
104 % name 118 % name
105 sys.exit(1) 119 return 1
106 120
107 copts, cargs = cmd.OptionParser.parse_args(argv) 121 copts, cargs = cmd.OptionParser.parse_args(argv)
108 122
@@ -118,16 +132,37 @@ class _Repo(object):
118 RunPager(config) 132 RunPager(config)
119 133
120 try: 134 try:
121 cmd.Execute(copts, cargs) 135 start = time.time()
136 try:
137 result = cmd.Execute(copts, cargs)
138 finally:
139 elapsed = time.time() - start
140 hours, remainder = divmod(elapsed, 3600)
141 minutes, seconds = divmod(remainder, 60)
142 if gopts.time:
143 if hours == 0:
144 print >>sys.stderr, 'real\t%dm%.3fs' \
145 % (minutes, seconds)
146 else:
147 print >>sys.stderr, 'real\t%dh%dm%.3fs' \
148 % (hours, minutes, seconds)
149 except DownloadError, e:
150 print >>sys.stderr, 'error: %s' % str(e)
151 return 1
122 except ManifestInvalidRevisionError, e: 152 except ManifestInvalidRevisionError, e:
123 print >>sys.stderr, 'error: %s' % str(e) 153 print >>sys.stderr, 'error: %s' % str(e)
124 sys.exit(1) 154 return 1
125 except NoSuchProjectError, e: 155 except NoSuchProjectError, e:
126 if e.name: 156 if e.name:
127 print >>sys.stderr, 'error: project %s not found' % e.name 157 print >>sys.stderr, 'error: project %s not found' % e.name
128 else: 158 else:
129 print >>sys.stderr, 'error: no project in current directory' 159 print >>sys.stderr, 'error: no project in current directory'
130 sys.exit(1) 160 return 1
161
162 return result
163
164def _MyRepoPath():
165 return os.path.dirname(__file__)
131 166
132def _MyWrapperPath(): 167def _MyWrapperPath():
133 return os.path.join(os.path.dirname(__file__), 'repo') 168 return os.path.join(os.path.dirname(__file__), 'repo')
@@ -195,7 +230,117 @@ def _PruneOptions(argv, opt):
195 continue 230 continue
196 i += 1 231 i += 1
197 232
233_user_agent = None
234
235def _UserAgent():
236 global _user_agent
237
238 if _user_agent is None:
239 py_version = sys.version_info
240
241 os_name = sys.platform
242 if os_name == 'linux2':
243 os_name = 'Linux'
244 elif os_name == 'win32':
245 os_name = 'Win32'
246 elif os_name == 'cygwin':
247 os_name = 'Cygwin'
248 elif os_name == 'darwin':
249 os_name = 'Darwin'
250
251 p = GitCommand(
252 None, ['describe', 'HEAD'],
253 cwd = _MyRepoPath(),
254 capture_stdout = True)
255 if p.Wait() == 0:
256 repo_version = p.stdout
257 if len(repo_version) > 0 and repo_version[-1] == '\n':
258 repo_version = repo_version[0:-1]
259 if len(repo_version) > 0 and repo_version[0] == 'v':
260 repo_version = repo_version[1:]
261 else:
262 repo_version = 'unknown'
263
264 _user_agent = 'git-repo/%s (%s) git/%s Python/%d.%d.%d' % (
265 repo_version,
266 os_name,
267 '.'.join(map(lambda d: str(d), git.version_tuple())),
268 py_version[0], py_version[1], py_version[2])
269 return _user_agent
270
271class _UserAgentHandler(urllib2.BaseHandler):
272 def http_request(self, req):
273 req.add_header('User-Agent', _UserAgent())
274 return req
275
276 def https_request(self, req):
277 req.add_header('User-Agent', _UserAgent())
278 return req
279
280class _BasicAuthHandler(urllib2.HTTPBasicAuthHandler):
281 def http_error_auth_reqed(self, authreq, host, req, headers):
282 try:
283 old_add_header = req.add_header
284 def _add_header(name, val):
285 val = val.replace('\n', '')
286 old_add_header(name, val)
287 req.add_header = _add_header
288 return urllib2.AbstractBasicAuthHandler.http_error_auth_reqed(
289 self, authreq, host, req, headers)
290 except:
291 reset = getattr(self, 'reset_retry_count', None)
292 if reset is not None:
293 reset()
294 elif getattr(self, 'retried', None):
295 self.retried = 0
296 raise
297
298class _DigestAuthHandler(urllib2.HTTPDigestAuthHandler):
299 def http_error_auth_reqed(self, auth_header, host, req, headers):
300 try:
301 old_add_header = req.add_header
302 def _add_header(name, val):
303 val = val.replace('\n', '')
304 old_add_header(name, val)
305 req.add_header = _add_header
306 return urllib2.AbstractDigestAuthHandler.http_error_auth_reqed(
307 self, auth_header, host, req, headers)
308 except:
309 reset = getattr(self, 'reset_retry_count', None)
310 if reset is not None:
311 reset()
312 elif getattr(self, 'retried', None):
313 self.retried = 0
314 raise
315
316def init_http():
317 handlers = [_UserAgentHandler()]
318
319 mgr = urllib2.HTTPPasswordMgrWithDefaultRealm()
320 try:
321 n = netrc.netrc()
322 for host in n.hosts:
323 p = n.hosts[host]
324 mgr.add_password(p[1], 'http://%s/' % host, p[0], p[2])
325 mgr.add_password(p[1], 'https://%s/' % host, p[0], p[2])
326 except netrc.NetrcParseError:
327 pass
328 except IOError:
329 pass
330 handlers.append(_BasicAuthHandler(mgr))
331 handlers.append(_DigestAuthHandler(mgr))
332
333 if 'http_proxy' in os.environ:
334 url = os.environ['http_proxy']
335 handlers.append(urllib2.ProxyHandler({'http': url, 'https': url}))
336 if 'REPO_CURL_VERBOSE' in os.environ:
337 handlers.append(urllib2.HTTPHandler(debuglevel=1))
338 handlers.append(urllib2.HTTPSHandler(debuglevel=1))
339 urllib2.install_opener(urllib2.build_opener(*handlers))
340
198def _Main(argv): 341def _Main(argv):
342 result = 0
343
199 opt = optparse.OptionParser(usage="repo wrapperinfo -- ...") 344 opt = optparse.OptionParser(usage="repo wrapperinfo -- ...")
200 opt.add_option("--repo-dir", dest="repodir", 345 opt.add_option("--repo-dir", dest="repodir",
201 help="path to .repo/") 346 help="path to .repo/")
@@ -209,15 +354,19 @@ def _Main(argv):
209 _CheckWrapperVersion(opt.wrapper_version, opt.wrapper_path) 354 _CheckWrapperVersion(opt.wrapper_version, opt.wrapper_path)
210 _CheckRepoDir(opt.repodir) 355 _CheckRepoDir(opt.repodir)
211 356
357 Version.wrapper_version = opt.wrapper_version
358 Version.wrapper_path = opt.wrapper_path
359
212 repo = _Repo(opt.repodir) 360 repo = _Repo(opt.repodir)
213 try: 361 try:
214 try: 362 try:
215 init_ssh() 363 init_ssh()
216 repo._Run(argv) 364 init_http()
365 result = repo._Run(argv) or 0
217 finally: 366 finally:
218 close_ssh() 367 close_ssh()
219 except KeyboardInterrupt: 368 except KeyboardInterrupt:
220 sys.exit(1) 369 result = 1
221 except RepoChangedException, rce: 370 except RepoChangedException, rce:
222 # If repo changed, re-exec ourselves. 371 # If repo changed, re-exec ourselves.
223 # 372 #
@@ -228,7 +377,9 @@ def _Main(argv):
228 except OSError, e: 377 except OSError, e:
229 print >>sys.stderr, 'fatal: cannot restart repo after upgrade' 378 print >>sys.stderr, 'fatal: cannot restart repo after upgrade'
230 print >>sys.stderr, 'fatal: %s' % e 379 print >>sys.stderr, 'fatal: %s' % e
231 sys.exit(128) 380 result = 128
381
382 sys.exit(result)
232 383
233if __name__ == '__main__': 384if __name__ == '__main__':
234 _Main(sys.argv[1:]) 385 _Main(sys.argv[1:])