summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xrepo96
1 files changed, 54 insertions, 42 deletions
diff --git a/repo b/repo
index 6ebfcd92..47211742 100755
--- a/repo
+++ b/repo
@@ -1,7 +1,7 @@
1#!/usr/bin/env python 1#!/usr/bin/env python
2 2
3## repo default configuration 3# repo default configuration
4## 4#
5import os 5import os
6REPO_URL = os.environ.get('REPO_URL', None) 6REPO_URL = os.environ.get('REPO_URL', None)
7if not REPO_URL: 7if not REPO_URL:
@@ -104,13 +104,13 @@ JuinEP+AwLAUZ1Bsx9ISC0Agpk2VeHXPL3FGhroEmoMvBzO0kTFGyoeT7PR/BfKv
104-----END PGP PUBLIC KEY BLOCK----- 104-----END PGP PUBLIC KEY BLOCK-----
105""" 105"""
106 106
107GIT = 'git' # our git command 107GIT = 'git' # our git command
108MIN_GIT_VERSION = (1, 7, 2) # minimum supported git version 108MIN_GIT_VERSION = (1, 7, 2) # minimum supported git version
109repodir = '.repo' # name of repo's private directory 109repodir = '.repo' # name of repo's private directory
110S_repo = 'repo' # special repo repository 110S_repo = 'repo' # special repo repository
111S_manifests = 'manifests' # special manifest repository 111S_manifests = 'manifests' # special manifest repository
112REPO_MAIN = S_repo + '/main.py' # main script 112REPO_MAIN = S_repo + '/main.py' # main script
113MIN_PYTHON_VERSION = (2, 6) # minimum supported python version 113MIN_PYTHON_VERSION = (2, 6) # minimum supported python version
114GITC_CONFIG_FILE = '/gitc/.config' 114GITC_CONFIG_FILE = '/gitc/.config'
115GITC_FS_ROOT_DIR = '/gitc/manifest-rw/' 115GITC_FS_ROOT_DIR = '/gitc/manifest-rw/'
116 116
@@ -216,9 +216,10 @@ group.add_option('--config-name',
216 dest='config_name', action="store_true", default=False, 216 dest='config_name', action="store_true", default=False,
217 help='Always prompt for name/e-mail') 217 help='Always prompt for name/e-mail')
218 218
219def _GitcInitOptions(init_optparse): 219
220 init_optparse.set_usage("repo gitc-init -u url -c client [options]") 220def _GitcInitOptions(init_optparse_arg):
221 g = init_optparse.add_option_group('GITC options') 221 init_optparse_arg.set_usage("repo gitc-init -u url -c client [options]")
222 g = init_optparse_arg.add_option_group('GITC options')
222 g.add_option('-f', '--manifest-file', 223 g.add_option('-f', '--manifest-file',
223 dest='manifest_file', 224 dest='manifest_file',
224 help='Optional manifest file to use for this GITC client.') 225 help='Optional manifest file to use for this GITC client.')
@@ -227,6 +228,8 @@ def _GitcInitOptions(init_optparse):
227 help='The name of the gitc_client instance to create or modify.') 228 help='The name of the gitc_client instance to create or modify.')
228 229
229_gitc_manifest_dir = None 230_gitc_manifest_dir = None
231
232
230def get_gitc_manifest_dir(): 233def get_gitc_manifest_dir():
231 global _gitc_manifest_dir 234 global _gitc_manifest_dir
232 if _gitc_manifest_dir is None: 235 if _gitc_manifest_dir is None:
@@ -241,6 +244,7 @@ def get_gitc_manifest_dir():
241 pass 244 pass
242 return _gitc_manifest_dir 245 return _gitc_manifest_dir
243 246
247
244def gitc_parse_clientdir(gitc_fs_path): 248def gitc_parse_clientdir(gitc_fs_path):
245 """Parse a path in the GITC FS and return its client name. 249 """Parse a path in the GITC FS and return its client name.
246 250
@@ -263,7 +267,9 @@ def gitc_parse_clientdir(gitc_fs_path):
263 return gitc_fs_path.split(manifest_dir)[1].split('/')[0] 267 return gitc_fs_path.split(manifest_dir)[1].split('/')[0]
264 return gitc_fs_path.split(GITC_FS_ROOT_DIR)[1].split('/')[0] 268 return gitc_fs_path.split(GITC_FS_ROOT_DIR)[1].split('/')[0]
265 269
270
266class CloneFailure(Exception): 271class CloneFailure(Exception):
272
267 """Indicate the remote clone of repo itself failed. 273 """Indicate the remote clone of repo itself failed.
268 """ 274 """
269 275
@@ -431,8 +437,8 @@ def SetupGnuPG(quiet):
431 cmd = ['gpg', '--import'] 437 cmd = ['gpg', '--import']
432 try: 438 try:
433 proc = subprocess.Popen(cmd, 439 proc = subprocess.Popen(cmd,
434 env = env, 440 env=env,
435 stdin = subprocess.PIPE) 441 stdin=subprocess.PIPE)
436 except OSError as e: 442 except OSError as e:
437 if not quiet: 443 if not quiet:
438 _print('warning: gpg (GnuPG) is not available.', file=sys.stderr) 444 _print('warning: gpg (GnuPG) is not available.', file=sys.stderr)
@@ -458,7 +464,7 @@ def _SetConfig(local, name, value):
458 """Set a git configuration option to the specified value. 464 """Set a git configuration option to the specified value.
459 """ 465 """
460 cmd = [GIT, 'config', name, value] 466 cmd = [GIT, 'config', name, value]
461 if subprocess.Popen(cmd, cwd = local).wait() != 0: 467 if subprocess.Popen(cmd, cwd=local).wait() != 0:
462 raise CloneFailure() 468 raise CloneFailure()
463 469
464 470
@@ -471,9 +477,9 @@ def _InitHttp():
471 n = netrc.netrc() 477 n = netrc.netrc()
472 for host in n.hosts: 478 for host in n.hosts:
473 p = n.hosts[host] 479 p = n.hosts[host]
474 mgr.add_password(p[1], 'http://%s/' % host, p[0], p[2]) 480 mgr.add_password(p[1], 'http://%s/' % host, p[0], p[2])
475 mgr.add_password(p[1], 'https://%s/' % host, p[0], p[2]) 481 mgr.add_password(p[1], 'https://%s/' % host, p[0], p[2])
476 except: 482 except: # pylint: disable=bare-except
477 pass 483 pass
478 handlers.append(urllib.request.HTTPBasicAuthHandler(mgr)) 484 handlers.append(urllib.request.HTTPBasicAuthHandler(mgr))
479 handlers.append(urllib.request.HTTPDigestAuthHandler(mgr)) 485 handlers.append(urllib.request.HTTPDigestAuthHandler(mgr))
@@ -486,6 +492,7 @@ def _InitHttp():
486 handlers.append(urllib.request.HTTPSHandler(debuglevel=1)) 492 handlers.append(urllib.request.HTTPSHandler(debuglevel=1))
487 urllib.request.install_opener(urllib.request.build_opener(*handlers)) 493 urllib.request.install_opener(urllib.request.build_opener(*handlers))
488 494
495
489def _Fetch(url, local, src, quiet): 496def _Fetch(url, local, src, quiet):
490 if not quiet: 497 if not quiet:
491 _print('Get %s' % url, file=sys.stderr) 498 _print('Get %s' % url, file=sys.stderr)
@@ -500,22 +507,23 @@ def _Fetch(url, local, src, quiet):
500 cmd.append('+refs/heads/*:refs/remotes/origin/*') 507 cmd.append('+refs/heads/*:refs/remotes/origin/*')
501 cmd.append('refs/tags/*:refs/tags/*') 508 cmd.append('refs/tags/*:refs/tags/*')
502 509
503 proc = subprocess.Popen(cmd, cwd = local, stderr = err) 510 proc = subprocess.Popen(cmd, cwd=local, stderr=err)
504 if err: 511 if err:
505 proc.stderr.read() 512 proc.stderr.read()
506 proc.stderr.close() 513 proc.stderr.close()
507 if proc.wait() != 0: 514 if proc.wait() != 0:
508 raise CloneFailure() 515 raise CloneFailure()
509 516
517
510def _DownloadBundle(url, local, quiet): 518def _DownloadBundle(url, local, quiet):
511 if not url.endswith('/'): 519 if not url.endswith('/'):
512 url += '/' 520 url += '/'
513 url += 'clone.bundle' 521 url += 'clone.bundle'
514 522
515 proc = subprocess.Popen( 523 proc = subprocess.Popen(
516 [GIT, 'config', '--get-regexp', 'url.*.insteadof'], 524 [GIT, 'config', '--get-regexp', 'url.*.insteadof'],
517 cwd = local, 525 cwd=local,
518 stdout = subprocess.PIPE) 526 stdout=subprocess.PIPE)
519 for line in proc.stdout: 527 for line in proc.stdout:
520 m = re.compile(r'^url\.(.*)\.insteadof (.*)$').match(line) 528 m = re.compile(r'^url\.(.*)\.insteadof (.*)$').match(line)
521 if m: 529 if m:
@@ -557,6 +565,7 @@ def _DownloadBundle(url, local, quiet):
557 finally: 565 finally:
558 dest.close() 566 dest.close()
559 567
568
560def _ImportBundle(local): 569def _ImportBundle(local):
561 path = os.path.join(local, '.git', 'clone.bundle') 570 path = os.path.join(local, '.git', 'clone.bundle')
562 try: 571 try:
@@ -564,6 +573,7 @@ def _ImportBundle(local):
564 finally: 573 finally:
565 os.remove(path) 574 os.remove(path)
566 575
576
567def _Clone(url, local, quiet): 577def _Clone(url, local, quiet):
568 """Clones a git repository to a new subdirectory of repodir 578 """Clones a git repository to a new subdirectory of repodir
569 """ 579 """
@@ -576,14 +586,14 @@ def _Clone(url, local, quiet):
576 586
577 cmd = [GIT, 'init', '--quiet'] 587 cmd = [GIT, 'init', '--quiet']
578 try: 588 try:
579 proc = subprocess.Popen(cmd, cwd = local) 589 proc = subprocess.Popen(cmd, cwd=local)
580 except OSError as e: 590 except OSError as e:
581 _print(file=sys.stderr) 591 _print(file=sys.stderr)
582 _print("fatal: '%s' is not available" % GIT, file=sys.stderr) 592 _print("fatal: '%s' is not available" % GIT, file=sys.stderr)
583 _print('fatal: %s' % e, file=sys.stderr) 593 _print('fatal: %s' % e, file=sys.stderr)
584 _print(file=sys.stderr) 594 _print(file=sys.stderr)
585 _print('Please make sure %s is installed and in your path.' % GIT, 595 _print('Please make sure %s is installed and in your path.' % GIT,
586 file=sys.stderr) 596 file=sys.stderr)
587 raise CloneFailure() 597 raise CloneFailure()
588 if proc.wait() != 0: 598 if proc.wait() != 0:
589 _print('fatal: could not create %s' % local, file=sys.stderr) 599 _print('fatal: could not create %s' % local, file=sys.stderr)
@@ -591,8 +601,9 @@ def _Clone(url, local, quiet):
591 601
592 _InitHttp() 602 _InitHttp()
593 _SetConfig(local, 'remote.origin.url', url) 603 _SetConfig(local, 'remote.origin.url', url)
594 _SetConfig(local, 'remote.origin.fetch', 604 _SetConfig(local,
595 '+refs/heads/*:refs/remotes/origin/*') 605 'remote.origin.fetch',
606 '+refs/heads/*:refs/remotes/origin/*')
596 if _DownloadBundle(url, local, quiet): 607 if _DownloadBundle(url, local, quiet):
597 _ImportBundle(local) 608 _ImportBundle(local)
598 _Fetch(url, local, 'origin', quiet) 609 _Fetch(url, local, 'origin', quiet)
@@ -605,7 +616,7 @@ def _Verify(cwd, branch, quiet):
605 proc = subprocess.Popen(cmd, 616 proc = subprocess.Popen(cmd,
606 stdout=subprocess.PIPE, 617 stdout=subprocess.PIPE,
607 stderr=subprocess.PIPE, 618 stderr=subprocess.PIPE,
608 cwd = cwd) 619 cwd=cwd)
609 cur = proc.stdout.read().strip() 620 cur = proc.stdout.read().strip()
610 proc.stdout.close() 621 proc.stdout.close()
611 622
@@ -623,7 +634,7 @@ def _Verify(cwd, branch, quiet):
623 if not quiet: 634 if not quiet:
624 _print(file=sys.stderr) 635 _print(file=sys.stderr)
625 _print("info: Ignoring branch '%s'; using tagged release '%s'" 636 _print("info: Ignoring branch '%s'; using tagged release '%s'"
626 % (branch, cur), file=sys.stderr) 637 % (branch, cur), file=sys.stderr)
627 _print(file=sys.stderr) 638 _print(file=sys.stderr)
628 639
629 env = os.environ.copy() 640 env = os.environ.copy()
@@ -631,10 +642,10 @@ def _Verify(cwd, branch, quiet):
631 642
632 cmd = [GIT, 'tag', '-v', cur] 643 cmd = [GIT, 'tag', '-v', cur]
633 proc = subprocess.Popen(cmd, 644 proc = subprocess.Popen(cmd,
634 stdout = subprocess.PIPE, 645 stdout=subprocess.PIPE,
635 stderr = subprocess.PIPE, 646 stderr=subprocess.PIPE,
636 cwd = cwd, 647 cwd=cwd,
637 env = env) 648 env=env)
638 out = proc.stdout.read() 649 out = proc.stdout.read()
639 proc.stdout.close() 650 proc.stdout.close()
640 651
@@ -654,21 +665,21 @@ def _Checkout(cwd, branch, rev, quiet):
654 """Checkout an upstream branch into the repository and track it. 665 """Checkout an upstream branch into the repository and track it.
655 """ 666 """
656 cmd = [GIT, 'update-ref', 'refs/heads/default', rev] 667 cmd = [GIT, 'update-ref', 'refs/heads/default', rev]
657 if subprocess.Popen(cmd, cwd = cwd).wait() != 0: 668 if subprocess.Popen(cmd, cwd=cwd).wait() != 0:
658 raise CloneFailure() 669 raise CloneFailure()
659 670
660 _SetConfig(cwd, 'branch.default.remote', 'origin') 671 _SetConfig(cwd, 'branch.default.remote', 'origin')
661 _SetConfig(cwd, 'branch.default.merge', 'refs/heads/%s' % branch) 672 _SetConfig(cwd, 'branch.default.merge', 'refs/heads/%s' % branch)
662 673
663 cmd = [GIT, 'symbolic-ref', 'HEAD', 'refs/heads/default'] 674 cmd = [GIT, 'symbolic-ref', 'HEAD', 'refs/heads/default']
664 if subprocess.Popen(cmd, cwd = cwd).wait() != 0: 675 if subprocess.Popen(cmd, cwd=cwd).wait() != 0:
665 raise CloneFailure() 676 raise CloneFailure()
666 677
667 cmd = [GIT, 'read-tree', '--reset', '-u'] 678 cmd = [GIT, 'read-tree', '--reset', '-u']
668 if not quiet: 679 if not quiet:
669 cmd.append('-v') 680 cmd.append('-v')
670 cmd.append('HEAD') 681 cmd.append('HEAD')
671 if subprocess.Popen(cmd, cwd = cwd).wait() != 0: 682 if subprocess.Popen(cmd, cwd=cwd).wait() != 0:
672 raise CloneFailure() 683 raise CloneFailure()
673 684
674 685
@@ -680,8 +691,8 @@ def _FindRepo():
680 691
681 olddir = None 692 olddir = None
682 while curdir != '/' \ 693 while curdir != '/' \
683 and curdir != olddir \ 694 and curdir != olddir \
684 and not repo: 695 and not repo:
685 repo = os.path.join(curdir, repodir, REPO_MAIN) 696 repo = os.path.join(curdir, repodir, REPO_MAIN)
686 if not os.path.isfile(repo): 697 if not os.path.isfile(repo):
687 repo = None 698 repo = None
@@ -690,7 +701,7 @@ def _FindRepo():
690 return (repo, os.path.join(curdir, repodir)) 701 return (repo, os.path.join(curdir, repodir))
691 702
692 703
693class _Options: 704class _Options(object):
694 help = False 705 help = False
695 706
696 707
@@ -717,7 +728,7 @@ def _Usage():
717 gitc_usage = " gitc-init Initialize a GITC Client.\n" 728 gitc_usage = " gitc-init Initialize a GITC Client.\n"
718 729
719 _print( 730 _print(
720"""usage: repo COMMAND [ARGS] 731 """usage: repo COMMAND [ARGS]
721 732
722repo is not yet installed. Use "repo init" to install it here. 733repo is not yet installed. Use "repo init" to install it here.
723 734
@@ -725,7 +736,7 @@ The most commonly used repo commands are:
725 736
726 init Install repo in the current working directory 737 init Install repo in the current working directory
727""" + gitc_usage + 738""" + gitc_usage +
728""" help Display detailed help on a command 739 """ help Display detailed help on a command
729 740
730For access to the full online help, install repo ("repo init"). 741For access to the full online help, install repo ("repo init").
731""", file=sys.stderr) 742""", file=sys.stderr)
@@ -786,8 +797,8 @@ def _SetDefaultsTo(gitdir):
786 '--git-dir=%s' % gitdir, 797 '--git-dir=%s' % gitdir,
787 'symbolic-ref', 798 'symbolic-ref',
788 'HEAD'], 799 'HEAD'],
789 stdout = subprocess.PIPE, 800 stdout=subprocess.PIPE,
790 stderr = subprocess.PIPE) 801 stderr=subprocess.PIPE)
791 REPO_REV = proc.stdout.read().strip() 802 REPO_REV = proc.stdout.read().strip()
792 proc.stdout.close() 803 proc.stdout.close()
793 804
@@ -814,7 +825,8 @@ def main(orig_args):
814 if get_gitc_manifest_dir() and cwd.startswith(get_gitc_manifest_dir()): 825 if get_gitc_manifest_dir() and cwd.startswith(get_gitc_manifest_dir()):
815 _print('error: repo cannot be used in the GITC local manifest directory.' 826 _print('error: repo cannot be used in the GITC local manifest directory.'
816 '\nIf you want to work on this GITC client please rerun this ' 827 '\nIf you want to work on this GITC client please rerun this '
817 'command from the corresponding client under /gitc/', file=sys.stderr) 828 'command from the corresponding client under /gitc/',
829 file=sys.stderr)
818 sys.exit(1) 830 sys.exit(1)
819 if not repo_main: 831 if not repo_main:
820 if opt.help: 832 if opt.help: