summaryrefslogtreecommitdiffstats
path: root/subcmds
diff options
context:
space:
mode:
Diffstat (limited to 'subcmds')
-rw-r--r--subcmds/__init__.py4
-rw-r--r--subcmds/branches.py5
-rw-r--r--subcmds/forall.py14
-rw-r--r--subcmds/help.py10
-rw-r--r--subcmds/info.py2
-rw-r--r--subcmds/init.py7
-rw-r--r--subcmds/list.py31
-rw-r--r--subcmds/overview.py2
-rw-r--r--subcmds/stage.py8
-rw-r--r--subcmds/status.py11
-rw-r--r--subcmds/sync.py47
-rw-r--r--subcmds/upload.py7
12 files changed, 100 insertions, 48 deletions
diff --git a/subcmds/__init__.py b/subcmds/__init__.py
index 1fac802e..84efb4de 100644
--- a/subcmds/__init__.py
+++ b/subcmds/__init__.py
@@ -38,8 +38,8 @@ for py in os.listdir(my_dir):
38 try: 38 try:
39 cmd = getattr(mod, clsn)() 39 cmd = getattr(mod, clsn)()
40 except AttributeError: 40 except AttributeError:
41 raise SyntaxError, '%s/%s does not define class %s' % ( 41 raise SyntaxError('%s/%s does not define class %s' % (
42 __name__, py, clsn) 42 __name__, py, clsn))
43 43
44 name = name.replace('_', '-') 44 name = name.replace('_', '-')
45 cmd.NAME = name 45 cmd.NAME = name
diff --git a/subcmds/branches.py b/subcmds/branches.py
index 06d45abe..c2e7c4b9 100644
--- a/subcmds/branches.py
+++ b/subcmds/branches.py
@@ -98,14 +98,13 @@ is shown, then the branch appears in all projects.
98 project_cnt = len(projects) 98 project_cnt = len(projects)
99 99
100 for project in projects: 100 for project in projects:
101 for name, b in project.GetBranches().iteritems(): 101 for name, b in project.GetBranches().items():
102 b.project = project 102 b.project = project
103 if name not in all_branches: 103 if name not in all_branches:
104 all_branches[name] = BranchInfo(name) 104 all_branches[name] = BranchInfo(name)
105 all_branches[name].add(b) 105 all_branches[name].add(b)
106 106
107 names = all_branches.keys() 107 names = list(sorted(all_branches))
108 names.sort()
109 108
110 if not names: 109 if not names:
111 print(' (no branches)', file=sys.stderr) 110 print(' (no branches)', file=sys.stderr)
diff --git a/subcmds/forall.py b/subcmds/forall.py
index 4c1c9ff8..7d5f7794 100644
--- a/subcmds/forall.py
+++ b/subcmds/forall.py
@@ -42,10 +42,14 @@ class Forall(Command, MirrorSafeCommand):
42 helpSummary = "Run a shell command in each project" 42 helpSummary = "Run a shell command in each project"
43 helpUsage = """ 43 helpUsage = """
44%prog [<project>...] -c <command> [<arg>...] 44%prog [<project>...] -c <command> [<arg>...]
45%prog -r str1 [str2] ... -c <command> [<arg>...]"
45""" 46"""
46 helpDescription = """ 47 helpDescription = """
47Executes the same shell command in each project. 48Executes the same shell command in each project.
48 49
50The -r option allows running the command only on projects matching
51regex or wildcard expression.
52
49Output Formatting 53Output Formatting
50----------------- 54-----------------
51 55
@@ -103,6 +107,9 @@ without iterating through the remaining projects.
103 setattr(parser.values, option.dest, list(parser.rargs)) 107 setattr(parser.values, option.dest, list(parser.rargs))
104 while parser.rargs: 108 while parser.rargs:
105 del parser.rargs[0] 109 del parser.rargs[0]
110 p.add_option('-r', '--regex',
111 dest='regex', action='store_true',
112 help="Execute the command only on projects matching regex or wildcard expression")
106 p.add_option('-c', '--command', 113 p.add_option('-c', '--command',
107 help='Command (and arguments) to execute', 114 help='Command (and arguments) to execute',
108 dest='command', 115 dest='command',
@@ -166,7 +173,12 @@ without iterating through the remaining projects.
166 rc = 0 173 rc = 0
167 first = True 174 first = True
168 175
169 for project in self.GetProjects(args): 176 if not opt.regex:
177 projects = self.GetProjects(args)
178 else:
179 projects = self.FindProjects(args)
180
181 for project in projects:
170 env = os.environ.copy() 182 env = os.environ.copy()
171 def setenv(name, val): 183 def setenv(name, val):
172 if val is None: 184 if val is None:
diff --git a/subcmds/help.py b/subcmds/help.py
index 78428825..4aa3f863 100644
--- a/subcmds/help.py
+++ b/subcmds/help.py
@@ -34,8 +34,7 @@ Displays detailed usage information about a command.
34 def _PrintAllCommands(self): 34 def _PrintAllCommands(self):
35 print('usage: repo COMMAND [ARGS]') 35 print('usage: repo COMMAND [ARGS]')
36 print('The complete list of recognized repo commands are:') 36 print('The complete list of recognized repo commands are:')
37 commandNames = self.commands.keys() 37 commandNames = list(sorted(self.commands))
38 commandNames.sort()
39 38
40 maxlen = 0 39 maxlen = 0
41 for name in commandNames: 40 for name in commandNames:
@@ -55,10 +54,9 @@ Displays detailed usage information about a command.
55 def _PrintCommonCommands(self): 54 def _PrintCommonCommands(self):
56 print('usage: repo COMMAND [ARGS]') 55 print('usage: repo COMMAND [ARGS]')
57 print('The most commonly used repo commands are:') 56 print('The most commonly used repo commands are:')
58 commandNames = [name 57 commandNames = list(sorted([name
59 for name in self.commands.keys() 58 for name, command in self.commands.items()
60 if self.commands[name].common] 59 if command.common]))
61 commandNames.sort()
62 60
63 maxlen = 0 61 maxlen = 0
64 for name in commandNames: 62 for name in commandNames:
diff --git a/subcmds/info.py b/subcmds/info.py
index 325874b5..c10e56cd 100644
--- a/subcmds/info.py
+++ b/subcmds/info.py
@@ -163,7 +163,7 @@ class Info(PagedCommand):
163 all_branches = [] 163 all_branches = []
164 for project in self.GetProjects(args): 164 for project in self.GetProjects(args):
165 br = [project.GetUploadableBranch(x) 165 br = [project.GetUploadableBranch(x)
166 for x in project.GetBranches().keys()] 166 for x in project.GetBranches()]
167 br = [x for x in br if x] 167 br = [x for x in br if x]
168 if self.opt.current_branch: 168 if self.opt.current_branch:
169 br = [x for x in br if x.name == project.CurrentBranch] 169 br = [x for x in br if x.name == project.CurrentBranch]
diff --git a/subcmds/init.py b/subcmds/init.py
index 11312601..29730cc4 100644
--- a/subcmds/init.py
+++ b/subcmds/init.py
@@ -91,8 +91,9 @@ to update the working directory files.
91 dest='depth', 91 dest='depth',
92 help='create a shallow clone with given depth; see git clone') 92 help='create a shallow clone with given depth; see git clone')
93 g.add_option('-g', '--groups', 93 g.add_option('-g', '--groups',
94 dest='groups', default='all,-notdefault', 94 dest='groups', default='default',
95 help='restrict manifest projects to ones with a specified group', 95 help='restrict manifest projects to ones with specified '
96 'group(s) [default|all|G1,G2,G3|G4,-G5,-G6]',
96 metavar='GROUP') 97 metavar='GROUP')
97 g.add_option('-p', '--platform', 98 g.add_option('-p', '--platform',
98 dest='platform', default='auto', 99 dest='platform', default='auto',
@@ -169,7 +170,7 @@ to update the working directory files.
169 170
170 groups = [x for x in groups if x] 171 groups = [x for x in groups if x]
171 groupstr = ','.join(groups) 172 groupstr = ','.join(groups)
172 if opt.platform == 'auto' and groupstr == 'all,-notdefault,platform-' + platform.system().lower(): 173 if opt.platform == 'auto' and groupstr == 'default,platform-' + platform.system().lower():
173 groupstr = None 174 groupstr = None
174 m.config.SetString('manifest.groups', groupstr) 175 m.config.SetString('manifest.groups', groupstr)
175 176
diff --git a/subcmds/list.py b/subcmds/list.py
index 0d5c27f7..a3358245 100644
--- a/subcmds/list.py
+++ b/subcmds/list.py
@@ -14,7 +14,7 @@
14# limitations under the License. 14# limitations under the License.
15 15
16from __future__ import print_function 16from __future__ import print_function
17import re 17import sys
18 18
19from command import Command, MirrorSafeCommand 19from command import Command, MirrorSafeCommand
20 20
@@ -38,6 +38,12 @@ This is similar to running: repo forall -c 'echo "$REPO_PATH : $REPO_PROJECT"'.
38 p.add_option('-f', '--fullpath', 38 p.add_option('-f', '--fullpath',
39 dest='fullpath', action='store_true', 39 dest='fullpath', action='store_true',
40 help="Display the full work tree path instead of the relative path") 40 help="Display the full work tree path instead of the relative path")
41 p.add_option('-n', '--name-only',
42 dest='name_only', action='store_true',
43 help="Display only the name of the repository")
44 p.add_option('-p', '--path-only',
45 dest='path_only', action='store_true',
46 help="Display only the path of the repository")
41 47
42 def Execute(self, opt, args): 48 def Execute(self, opt, args):
43 """List all projects and the associated directories. 49 """List all projects and the associated directories.
@@ -50,6 +56,11 @@ This is similar to running: repo forall -c 'echo "$REPO_PATH : $REPO_PROJECT"'.
50 opt: The options. 56 opt: The options.
51 args: Positional args. Can be a list of projects to list, or empty. 57 args: Positional args. Can be a list of projects to list, or empty.
52 """ 58 """
59
60 if opt.fullpath and opt.name_only:
61 print('error: cannot combine -f and -n', file=sys.stderr)
62 sys.exit(1)
63
53 if not opt.regex: 64 if not opt.regex:
54 projects = self.GetProjects(args) 65 projects = self.GetProjects(args)
55 else: 66 else:
@@ -62,18 +73,12 @@ This is similar to running: repo forall -c 'echo "$REPO_PATH : $REPO_PROJECT"'.
62 73
63 lines = [] 74 lines = []
64 for project in projects: 75 for project in projects:
65 lines.append("%s : %s" % (_getpath(project), project.name)) 76 if opt.name_only and not opt.path_only:
77 lines.append("%s" % ( project.name))
78 elif opt.path_only and not opt.name_only:
79 lines.append("%s" % (_getpath(project)))
80 else:
81 lines.append("%s : %s" % (_getpath(project), project.name))
66 82
67 lines.sort() 83 lines.sort()
68 print('\n'.join(lines)) 84 print('\n'.join(lines))
69
70 def FindProjects(self, args):
71 result = []
72 for project in self.GetProjects(''):
73 for arg in args:
74 pattern = re.compile(r'%s' % arg, re.IGNORECASE)
75 if pattern.search(project.name) or pattern.search(project.relpath):
76 result.append(project)
77 break
78 result.sort(key=lambda project: project.relpath)
79 return result
diff --git a/subcmds/overview.py b/subcmds/overview.py
index 418459ae..eed8cf20 100644
--- a/subcmds/overview.py
+++ b/subcmds/overview.py
@@ -42,7 +42,7 @@ are displayed.
42 all_branches = [] 42 all_branches = []
43 for project in self.GetProjects(args): 43 for project in self.GetProjects(args):
44 br = [project.GetUploadableBranch(x) 44 br = [project.GetUploadableBranch(x)
45 for x in project.GetBranches().keys()] 45 for x in project.GetBranches()]
46 br = [x for x in br if x] 46 br = [x for x in br if x]
47 if opt.current_branch: 47 if opt.current_branch:
48 br = [x for x in br if x.name == project.CurrentBranch] 48 br = [x for x in br if x.name == project.CurrentBranch]
diff --git a/subcmds/stage.py b/subcmds/stage.py
index ff15ee0c..28849764 100644
--- a/subcmds/stage.py
+++ b/subcmds/stage.py
@@ -49,7 +49,7 @@ The '%prog' command stages files to prepare the next commit.
49 self.Usage() 49 self.Usage()
50 50
51 def _Interactive(self, opt, args): 51 def _Interactive(self, opt, args):
52 all_projects = filter(lambda x: x.IsDirty(), self.GetProjects(args)) 52 all_projects = [p for p in self.GetProjects(args) if p.IsDirty()]
53 if not all_projects: 53 if not all_projects:
54 print('no projects have uncommitted modifications', file=sys.stderr) 54 print('no projects have uncommitted modifications', file=sys.stderr)
55 return 55 return
@@ -98,9 +98,9 @@ The '%prog' command stages files to prepare the next commit.
98 _AddI(all_projects[a_index - 1]) 98 _AddI(all_projects[a_index - 1])
99 continue 99 continue
100 100
101 p = filter(lambda x: x.name == a or x.relpath == a, all_projects) 101 projects = [p for p in all_projects if a in [p.name, p.relpath]]
102 if len(p) == 1: 102 if len(projects) == 1:
103 _AddI(p[0]) 103 _AddI(projects[0])
104 continue 104 continue
105 print('Bye.') 105 print('Bye.')
106 106
diff --git a/subcmds/status.py b/subcmds/status.py
index cce00c81..9810337f 100644
--- a/subcmds/status.py
+++ b/subcmds/status.py
@@ -21,10 +21,15 @@ except ImportError:
21 import dummy_threading as _threading 21 import dummy_threading as _threading
22 22
23import glob 23import glob
24try:
25 # For python2
26 import StringIO as io
27except ImportError:
28 # For python3
29 import io
24import itertools 30import itertools
25import os 31import os
26import sys 32import sys
27import StringIO
28 33
29from color import Coloring 34from color import Coloring
30 35
@@ -142,7 +147,7 @@ the following meanings:
142 for project in all_projects: 147 for project in all_projects:
143 sem.acquire() 148 sem.acquire()
144 149
145 class BufList(StringIO.StringIO): 150 class BufList(io.StringIO):
146 def dump(self, ostream): 151 def dump(self, ostream):
147 for entry in self.buflist: 152 for entry in self.buflist:
148 ostream.write(entry) 153 ostream.write(entry)
@@ -182,7 +187,7 @@ the following meanings:
182 try: 187 try:
183 os.chdir(self.manifest.topdir) 188 os.chdir(self.manifest.topdir)
184 189
185 outstring = StringIO.StringIO() 190 outstring = io.StringIO()
186 self._FindOrphans(glob.glob('.*') + \ 191 self._FindOrphans(glob.glob('.*') + \
187 glob.glob('*'), \ 192 glob.glob('*'), \
188 proj_dirs, proj_dirs_parents, outstring) 193 proj_dirs, proj_dirs_parents, outstring)
diff --git a/subcmds/sync.py b/subcmds/sync.py
index 6c903ff4..8fb94885 100644
--- a/subcmds/sync.py
+++ b/subcmds/sync.py
@@ -24,8 +24,24 @@ import socket
24import subprocess 24import subprocess
25import sys 25import sys
26import time 26import time
27import urlparse 27try:
28import xmlrpclib 28 # For python3
29 import urllib.parse
30except ImportError:
31 # For python2
32 import imp
33 import urlparse
34 urllib = imp.new_module('urllib')
35 urllib.parse = urlparse
36try:
37 # For python3
38 import xmlrpc.client
39except ImportError:
40 # For python2
41 import imp
42 import xmlrpclib
43 xmlrpc = imp.new_module('xmlrpc')
44 xmlrpc.client = xmlrpclib
29 45
30try: 46try:
31 import threading as _threading 47 import threading as _threading
@@ -228,6 +244,9 @@ later is required to fix a server side protocol bug.
228 # We'll set to true once we've locked the lock. 244 # We'll set to true once we've locked the lock.
229 did_lock = False 245 did_lock = False
230 246
247 if not opt.quiet:
248 print('Fetching project %s' % project.name)
249
231 # Encapsulate everything in a try/except/finally so that: 250 # Encapsulate everything in a try/except/finally so that:
232 # - We always set err_event in the case of an exception. 251 # - We always set err_event in the case of an exception.
233 # - We always make sure we call sem.release(). 252 # - We always make sure we call sem.release().
@@ -274,6 +293,8 @@ later is required to fix a server side protocol bug.
274 if self.jobs == 1: 293 if self.jobs == 1:
275 for project in projects: 294 for project in projects:
276 pm.update() 295 pm.update()
296 if not opt.quiet:
297 print('Fetching project %s' % project.name)
277 if project.Sync_NetworkHalf( 298 if project.Sync_NetworkHalf(
278 quiet=opt.quiet, 299 quiet=opt.quiet,
279 current_branch_only=opt.current_branch_only, 300 current_branch_only=opt.current_branch_only,
@@ -372,6 +393,13 @@ later is required to fix a server side protocol bug.
372 print('\nerror: Exited sync due to gc errors', file=sys.stderr) 393 print('\nerror: Exited sync due to gc errors', file=sys.stderr)
373 sys.exit(1) 394 sys.exit(1)
374 395
396 def _ReloadManifest(self, manifest_name=None):
397 if manifest_name:
398 # Override calls _Unload already
399 self.manifest.Override(manifest_name)
400 else:
401 self.manifest._Unload()
402
375 def UpdateProjectList(self): 403 def UpdateProjectList(self):
376 new_project_paths = [] 404 new_project_paths = []
377 for project in self.GetProjects(None, missing_ok=True): 405 for project in self.GetProjects(None, missing_ok=True):
@@ -486,7 +514,7 @@ later is required to fix a server side protocol bug.
486 file=sys.stderr) 514 file=sys.stderr)
487 else: 515 else:
488 try: 516 try:
489 parse_result = urlparse.urlparse(manifest_server) 517 parse_result = urllib.parse(manifest_server)
490 if parse_result.hostname: 518 if parse_result.hostname:
491 username, _account, password = \ 519 username, _account, password = \
492 info.authenticators(parse_result.hostname) 520 info.authenticators(parse_result.hostname)
@@ -504,7 +532,7 @@ later is required to fix a server side protocol bug.
504 1) 532 1)
505 533
506 try: 534 try:
507 server = xmlrpclib.Server(manifest_server) 535 server = xmlrpc.client.Server(manifest_server)
508 if opt.smart_sync: 536 if opt.smart_sync:
509 p = self.manifest.manifestProject 537 p = self.manifest.manifestProject
510 b = p.GetBranch(p.CurrentBranch) 538 b = p.GetBranch(p.CurrentBranch)
@@ -513,8 +541,7 @@ later is required to fix a server side protocol bug.
513 branch = branch[len(R_HEADS):] 541 branch = branch[len(R_HEADS):]
514 542
515 env = os.environ.copy() 543 env = os.environ.copy()
516 if (env.has_key('TARGET_PRODUCT') and 544 if 'TARGET_PRODUCT' in env and 'TARGET_BUILD_VARIANT' in env:
517 env.has_key('TARGET_BUILD_VARIANT')):
518 target = '%s-%s' % (env['TARGET_PRODUCT'], 545 target = '%s-%s' % (env['TARGET_PRODUCT'],
519 env['TARGET_BUILD_VARIANT']) 546 env['TARGET_BUILD_VARIANT'])
520 [success, manifest_str] = server.GetApprovedManifest(branch, target) 547 [success, manifest_str] = server.GetApprovedManifest(branch, target)
@@ -542,11 +569,11 @@ later is required to fix a server side protocol bug.
542 else: 569 else:
543 print('error: %s' % manifest_str, file=sys.stderr) 570 print('error: %s' % manifest_str, file=sys.stderr)
544 sys.exit(1) 571 sys.exit(1)
545 except (socket.error, IOError, xmlrpclib.Fault) as e: 572 except (socket.error, IOError, xmlrpc.client.Fault) as e:
546 print('error: cannot connect to manifest server %s:\n%s' 573 print('error: cannot connect to manifest server %s:\n%s'
547 % (self.manifest.manifest_server, e), file=sys.stderr) 574 % (self.manifest.manifest_server, e), file=sys.stderr)
548 sys.exit(1) 575 sys.exit(1)
549 except xmlrpclib.ProtocolError as e: 576 except xmlrpc.client.ProtocolError as e:
550 print('error: cannot connect to manifest server %s:\n%d %s' 577 print('error: cannot connect to manifest server %s:\n%d %s'
551 % (self.manifest.manifest_server, e.errcode, e.errmsg), 578 % (self.manifest.manifest_server, e.errcode, e.errmsg),
552 file=sys.stderr) 579 file=sys.stderr)
@@ -571,7 +598,7 @@ later is required to fix a server side protocol bug.
571 mp.Sync_LocalHalf(syncbuf) 598 mp.Sync_LocalHalf(syncbuf)
572 if not syncbuf.Finish(): 599 if not syncbuf.Finish():
573 sys.exit(1) 600 sys.exit(1)
574 self.manifest._Unload() 601 self._ReloadManifest(opt.manifest_name)
575 if opt.jobs is None: 602 if opt.jobs is None:
576 self.jobs = self.manifest.default.sync_j 603 self.jobs = self.manifest.default.sync_j
577 all_projects = self.GetProjects(args, 604 all_projects = self.GetProjects(args,
@@ -596,7 +623,7 @@ later is required to fix a server side protocol bug.
596 # Iteratively fetch missing and/or nested unregistered submodules 623 # Iteratively fetch missing and/or nested unregistered submodules
597 previously_missing_set = set() 624 previously_missing_set = set()
598 while True: 625 while True:
599 self.manifest._Unload() 626 self._ReloadManifest(opt.manifest_name)
600 all_projects = self.GetProjects(args, 627 all_projects = self.GetProjects(args,
601 missing_ok=True, 628 missing_ok=True,
602 submodules_ok=opt.fetch_submodules) 629 submodules_ok=opt.fetch_submodules)
diff --git a/subcmds/upload.py b/subcmds/upload.py
index 48ee685c..a34938e5 100644
--- a/subcmds/upload.py
+++ b/subcmds/upload.py
@@ -23,6 +23,11 @@ from editor import Editor
23from error import HookError, UploadError 23from error import HookError, UploadError
24from project import RepoHook 24from project import RepoHook
25 25
26try:
27 input = raw_input
28except NameError:
29 pass
30
26UNUSUAL_COMMIT_THRESHOLD = 5 31UNUSUAL_COMMIT_THRESHOLD = 5
27 32
28def _ConfirmManyUploads(multiple_branches=False): 33def _ConfirmManyUploads(multiple_branches=False):
@@ -33,7 +38,7 @@ def _ConfirmManyUploads(multiple_branches=False):
33 print('ATTENTION: You are uploading an unusually high number of commits.') 38 print('ATTENTION: You are uploading an unusually high number of commits.')
34 print('YOU PROBABLY DO NOT MEAN TO DO THIS. (Did you rebase across ' 39 print('YOU PROBABLY DO NOT MEAN TO DO THIS. (Did you rebase across '
35 'branches?)') 40 'branches?)')
36 answer = raw_input("If you are sure you intend to do this, type 'yes': ").strip() 41 answer = input("If you are sure you intend to do this, type 'yes': ").strip()
37 return answer == "yes" 42 return answer == "yes"
38 43
39def _die(fmt, *args): 44def _die(fmt, *args):