diff options
Diffstat (limited to 'repo')
| -rwxr-xr-x | repo | 146 |
1 files changed, 126 insertions, 20 deletions
| @@ -2,7 +2,7 @@ | |||
| 2 | 2 | ||
| 3 | ## repo default configuration | 3 | ## repo default configuration |
| 4 | ## | 4 | ## |
| 5 | REPO_URL='git://android.git.kernel.org/tools/repo.git' | 5 | REPO_URL='https://gerrit.googlesource.com/git-repo' |
| 6 | REPO_REV='stable' | 6 | REPO_REV='stable' |
| 7 | 7 | ||
| 8 | # Copyright (C) 2008 Google Inc. | 8 | # Copyright (C) 2008 Google Inc. |
| @@ -28,7 +28,7 @@ if __name__ == '__main__': | |||
| 28 | del magic | 28 | del magic |
| 29 | 29 | ||
| 30 | # increment this whenever we make important changes to this script | 30 | # increment this whenever we make important changes to this script |
| 31 | VERSION = (1, 10) | 31 | VERSION = (1, 17) |
| 32 | 32 | ||
| 33 | # increment this if the MAINTAINER_KEYS block is modified | 33 | # increment this if the MAINTAINER_KEYS block is modified |
| 34 | KEYRING_VERSION = (1,0) | 34 | KEYRING_VERSION = (1,0) |
| @@ -91,6 +91,7 @@ import re | |||
| 91 | import readline | 91 | import readline |
| 92 | import subprocess | 92 | import subprocess |
| 93 | import sys | 93 | import sys |
| 94 | import urllib2 | ||
| 94 | 95 | ||
| 95 | home_dot_repo = os.path.expanduser('~/.repoconfig') | 96 | home_dot_repo = os.path.expanduser('~/.repoconfig') |
| 96 | gpg_dir = os.path.join(home_dot_repo, 'gnupg') | 97 | gpg_dir = os.path.join(home_dot_repo, 'gnupg') |
| @@ -109,23 +110,31 @@ group = init_optparse.add_option_group('Manifest options') | |||
| 109 | group.add_option('-u', '--manifest-url', | 110 | group.add_option('-u', '--manifest-url', |
| 110 | dest='manifest_url', | 111 | dest='manifest_url', |
| 111 | help='manifest repository location', metavar='URL') | 112 | help='manifest repository location', metavar='URL') |
| 112 | group.add_option('-o', '--origin', | ||
| 113 | dest='manifest_origin', | ||
| 114 | help="use REMOTE instead of 'origin' to track upstream", | ||
| 115 | metavar='REMOTE') | ||
| 116 | group.add_option('-b', '--manifest-branch', | 113 | group.add_option('-b', '--manifest-branch', |
| 117 | dest='manifest_branch', | 114 | dest='manifest_branch', |
| 118 | help='manifest branch or revision', metavar='REVISION') | 115 | help='manifest branch or revision', metavar='REVISION') |
| 119 | group.add_option('-m', '--manifest-name', | 116 | group.add_option('-m', '--manifest-name', |
| 120 | dest='manifest_name', | 117 | dest='manifest_name', |
| 121 | help='initial manifest file (deprecated)', | 118 | help='initial manifest file', metavar='NAME.xml') |
| 122 | metavar='NAME.xml') | ||
| 123 | group.add_option('--mirror', | 119 | group.add_option('--mirror', |
| 124 | dest='mirror', action='store_true', | 120 | dest='mirror', action='store_true', |
| 125 | help='mirror the forrest') | 121 | help='mirror the forrest') |
| 126 | group.add_option('--reference', | 122 | group.add_option('--reference', |
| 127 | dest='reference', | 123 | dest='reference', |
| 128 | help='location of mirror directory', metavar='DIR') | 124 | help='location of mirror directory', metavar='DIR') |
| 125 | group.add_option('--depth', type='int', default=None, | ||
| 126 | dest='depth', | ||
| 127 | help='create a shallow clone with given depth; see git clone') | ||
| 128 | group.add_option('-g', '--groups', | ||
| 129 | dest='groups', default='default', | ||
| 130 | help='restrict manifest projects to ones with a specified group', | ||
| 131 | metavar='GROUP') | ||
| 132 | group.add_option('-p', '--platform', | ||
| 133 | dest='platform', default="auto", | ||
| 134 | help='restrict manifest projects to ones with a specified' | ||
| 135 | 'platform group [auto|all|none|linux|darwin|...]', | ||
| 136 | metavar='PLATFORM') | ||
| 137 | |||
| 129 | 138 | ||
| 130 | # Tool | 139 | # Tool |
| 131 | group = init_optparse.add_option_group('repo Version options') | 140 | group = init_optparse.add_option_group('repo Version options') |
| @@ -139,6 +148,11 @@ group.add_option('--no-repo-verify', | |||
| 139 | dest='no_repo_verify', action='store_true', | 148 | dest='no_repo_verify', action='store_true', |
| 140 | help='do not verify repo source code') | 149 | help='do not verify repo source code') |
| 141 | 150 | ||
| 151 | # Other | ||
| 152 | group = init_optparse.add_option_group('Other options') | ||
| 153 | group.add_option('--config-name', | ||
| 154 | dest='config_name', action="store_true", default=False, | ||
| 155 | help='Always prompt for name/e-mail') | ||
| 142 | 156 | ||
| 143 | class CloneFailure(Exception): | 157 | class CloneFailure(Exception): |
| 144 | """Indicate the remote clone of repo itself failed. | 158 | """Indicate the remote clone of repo itself failed. |
| @@ -149,7 +163,7 @@ def _Init(args): | |||
| 149 | """Installs repo by cloning it over the network. | 163 | """Installs repo by cloning it over the network. |
| 150 | """ | 164 | """ |
| 151 | opt, args = init_optparse.parse_args(args) | 165 | opt, args = init_optparse.parse_args(args) |
| 152 | if args or not opt.manifest_url: | 166 | if args: |
| 153 | init_optparse.print_usage() | 167 | init_optparse.print_usage() |
| 154 | sys.exit(1) | 168 | sys.exit(1) |
| 155 | 169 | ||
| @@ -188,10 +202,6 @@ def _Init(args): | |||
| 188 | else: | 202 | else: |
| 189 | can_verify = True | 203 | can_verify = True |
| 190 | 204 | ||
| 191 | if not opt.quiet: | ||
| 192 | print >>sys.stderr, 'Getting repo ...' | ||
| 193 | print >>sys.stderr, ' from %s' % url | ||
| 194 | |||
| 195 | dst = os.path.abspath(os.path.join(repodir, S_repo)) | 205 | dst = os.path.abspath(os.path.join(repodir, S_repo)) |
| 196 | _Clone(url, dst, opt.quiet) | 206 | _Clone(url, dst, opt.quiet) |
| 197 | 207 | ||
| @@ -210,7 +220,17 @@ def _Init(args): | |||
| 210 | 220 | ||
| 211 | def _CheckGitVersion(): | 221 | def _CheckGitVersion(): |
| 212 | cmd = [GIT, '--version'] | 222 | cmd = [GIT, '--version'] |
| 213 | proc = subprocess.Popen(cmd, stdout=subprocess.PIPE) | 223 | try: |
| 224 | proc = subprocess.Popen(cmd, stdout=subprocess.PIPE) | ||
| 225 | except OSError, e: | ||
| 226 | print >>sys.stderr | ||
| 227 | print >>sys.stderr, "fatal: '%s' is not available" % GIT | ||
| 228 | print >>sys.stderr, 'fatal: %s' % e | ||
| 229 | print >>sys.stderr | ||
| 230 | print >>sys.stderr, 'Please make sure %s is installed'\ | ||
| 231 | ' and in your path.' % GIT | ||
| 232 | raise CloneFailure() | ||
| 233 | |||
| 214 | ver_str = proc.stdout.read().strip() | 234 | ver_str = proc.stdout.read().strip() |
| 215 | proc.stdout.close() | 235 | proc.stdout.close() |
| 216 | proc.wait() | 236 | proc.wait() |
| @@ -301,15 +321,43 @@ def _SetConfig(local, name, value): | |||
| 301 | raise CloneFailure() | 321 | raise CloneFailure() |
| 302 | 322 | ||
| 303 | 323 | ||
| 304 | def _Fetch(local, quiet, *args): | 324 | def _InitHttp(): |
| 325 | handlers = [] | ||
| 326 | |||
| 327 | mgr = urllib2.HTTPPasswordMgrWithDefaultRealm() | ||
| 328 | try: | ||
| 329 | import netrc | ||
| 330 | n = netrc.netrc() | ||
| 331 | for host in n.hosts: | ||
| 332 | p = n.hosts[host] | ||
| 333 | mgr.add_password(p[1], 'http://%s/' % host, p[0], p[2]) | ||
| 334 | mgr.add_password(p[1], 'https://%s/' % host, p[0], p[2]) | ||
| 335 | except: | ||
| 336 | pass | ||
| 337 | handlers.append(urllib2.HTTPBasicAuthHandler(mgr)) | ||
| 338 | handlers.append(urllib2.HTTPDigestAuthHandler(mgr)) | ||
| 339 | |||
| 340 | if 'http_proxy' in os.environ: | ||
| 341 | url = os.environ['http_proxy'] | ||
| 342 | handlers.append(urllib2.ProxyHandler({'http': url, 'https': url})) | ||
| 343 | if 'REPO_CURL_VERBOSE' in os.environ: | ||
| 344 | handlers.append(urllib2.HTTPHandler(debuglevel=1)) | ||
| 345 | handlers.append(urllib2.HTTPSHandler(debuglevel=1)) | ||
| 346 | urllib2.install_opener(urllib2.build_opener(*handlers)) | ||
| 347 | |||
| 348 | def _Fetch(url, local, src, quiet): | ||
| 349 | if not quiet: | ||
| 350 | print >>sys.stderr, 'Get %s' % url | ||
| 351 | |||
| 305 | cmd = [GIT, 'fetch'] | 352 | cmd = [GIT, 'fetch'] |
| 306 | if quiet: | 353 | if quiet: |
| 307 | cmd.append('--quiet') | 354 | cmd.append('--quiet') |
| 308 | err = subprocess.PIPE | 355 | err = subprocess.PIPE |
| 309 | else: | 356 | else: |
| 310 | err = None | 357 | err = None |
| 311 | cmd.extend(args) | 358 | cmd.append(src) |
| 312 | cmd.append('origin') | 359 | cmd.append('+refs/heads/*:refs/remotes/origin/*') |
| 360 | cmd.append('refs/tags/*:refs/tags/*') | ||
| 313 | 361 | ||
| 314 | proc = subprocess.Popen(cmd, cwd = local, stderr = err) | 362 | proc = subprocess.Popen(cmd, cwd = local, stderr = err) |
| 315 | if err: | 363 | if err: |
| @@ -318,6 +366,62 @@ def _Fetch(local, quiet, *args): | |||
| 318 | if proc.wait() != 0: | 366 | if proc.wait() != 0: |
| 319 | raise CloneFailure() | 367 | raise CloneFailure() |
| 320 | 368 | ||
| 369 | def _DownloadBundle(url, local, quiet): | ||
| 370 | if not url.endswith('/'): | ||
| 371 | url += '/' | ||
| 372 | url += 'clone.bundle' | ||
| 373 | |||
| 374 | proc = subprocess.Popen( | ||
| 375 | [GIT, 'config', '--get-regexp', 'url.*.insteadof'], | ||
| 376 | cwd = local, | ||
| 377 | stdout = subprocess.PIPE) | ||
| 378 | for line in proc.stdout: | ||
| 379 | m = re.compile(r'^url\.(.*)\.insteadof (.*)$').match(line) | ||
| 380 | if m: | ||
| 381 | new_url = m.group(1) | ||
| 382 | old_url = m.group(2) | ||
| 383 | if url.startswith(old_url): | ||
| 384 | url = new_url + url[len(old_url):] | ||
| 385 | break | ||
| 386 | proc.stdout.close() | ||
| 387 | proc.wait() | ||
| 388 | |||
| 389 | if not url.startswith('http:') and not url.startswith('https:'): | ||
| 390 | return False | ||
| 391 | |||
| 392 | dest = open(os.path.join(local, '.git', 'clone.bundle'), 'w+b') | ||
| 393 | try: | ||
| 394 | try: | ||
| 395 | r = urllib2.urlopen(url) | ||
| 396 | except urllib2.HTTPError, e: | ||
| 397 | if e.code == 404: | ||
| 398 | return False | ||
| 399 | print >>sys.stderr, 'fatal: Cannot get %s' % url | ||
| 400 | print >>sys.stderr, 'fatal: HTTP error %s' % e.code | ||
| 401 | raise CloneFailure() | ||
| 402 | except urllib2.URLError, e: | ||
| 403 | print >>sys.stderr, 'fatal: Cannot get %s' % url | ||
| 404 | print >>sys.stderr, 'fatal: error %s' % e.reason | ||
| 405 | raise CloneFailure() | ||
| 406 | try: | ||
| 407 | if not quiet: | ||
| 408 | print >>sys.stderr, 'Get %s' % url | ||
| 409 | while True: | ||
| 410 | buf = r.read(8192) | ||
| 411 | if buf == '': | ||
| 412 | return True | ||
| 413 | dest.write(buf) | ||
| 414 | finally: | ||
| 415 | r.close() | ||
| 416 | finally: | ||
| 417 | dest.close() | ||
| 418 | |||
| 419 | def _ImportBundle(local): | ||
| 420 | path = os.path.join(local, '.git', 'clone.bundle') | ||
| 421 | try: | ||
| 422 | _Fetch(local, local, path, True) | ||
| 423 | finally: | ||
| 424 | os.remove(path) | ||
| 321 | 425 | ||
| 322 | def _Clone(url, local, quiet): | 426 | def _Clone(url, local, quiet): |
| 323 | """Clones a git repository to a new subdirectory of repodir | 427 | """Clones a git repository to a new subdirectory of repodir |
| @@ -345,11 +449,14 @@ def _Clone(url, local, quiet): | |||
| 345 | print >>sys.stderr, 'fatal: could not create %s' % local | 449 | print >>sys.stderr, 'fatal: could not create %s' % local |
| 346 | raise CloneFailure() | 450 | raise CloneFailure() |
| 347 | 451 | ||
| 452 | _InitHttp() | ||
| 348 | _SetConfig(local, 'remote.origin.url', url) | 453 | _SetConfig(local, 'remote.origin.url', url) |
| 349 | _SetConfig(local, 'remote.origin.fetch', | 454 | _SetConfig(local, 'remote.origin.fetch', |
| 350 | '+refs/heads/*:refs/remotes/origin/*') | 455 | '+refs/heads/*:refs/remotes/origin/*') |
| 351 | _Fetch(local, quiet) | 456 | if _DownloadBundle(url, local, quiet): |
| 352 | _Fetch(local, quiet, '--tags') | 457 | _ImportBundle(local) |
| 458 | else: | ||
| 459 | _Fetch(url, local, 'origin', quiet) | ||
| 353 | 460 | ||
| 354 | 461 | ||
| 355 | def _Verify(cwd, branch, quiet): | 462 | def _Verify(cwd, branch, quiet): |
| @@ -601,4 +708,3 @@ def main(orig_args): | |||
| 601 | 708 | ||
| 602 | if __name__ == '__main__': | 709 | if __name__ == '__main__': |
| 603 | main(sys.argv[1:]) | 710 | main(sys.argv[1:]) |
| 604 | |||
