summaryrefslogtreecommitdiffstats
path: root/subcmds
diff options
context:
space:
mode:
Diffstat (limited to 'subcmds')
-rw-r--r--subcmds/abandon.py59
-rw-r--r--subcmds/start.py62
2 files changed, 83 insertions, 38 deletions
diff --git a/subcmds/abandon.py b/subcmds/abandon.py
index 359c431b..b82a2dbf 100644
--- a/subcmds/abandon.py
+++ b/subcmds/abandon.py
@@ -13,9 +13,12 @@
13# limitations under the License. 13# limitations under the License.
14 14
15from collections import defaultdict 15from collections import defaultdict
16import functools
17import itertools
18import multiprocessing
16import sys 19import sys
17 20
18from command import Command 21from command import Command, DEFAULT_LOCAL_JOBS, WORKER_BATCH_SIZE
19from git_command import git 22from git_command import git
20from progress import Progress 23from progress import Progress
21 24
@@ -31,8 +34,10 @@ deleting it (and all its history) from your local repository.
31 34
32It is equivalent to "git branch -D <branchname>". 35It is equivalent to "git branch -D <branchname>".
33""" 36"""
37 PARALLEL_JOBS = DEFAULT_LOCAL_JOBS
34 38
35 def _Options(self, p): 39 def _Options(self, p):
40 super()._Options(p)
36 p.add_option('-q', '--quiet', 41 p.add_option('-q', '--quiet',
37 action='store_true', default=False, 42 action='store_true', default=False,
38 help='be quiet') 43 help='be quiet')
@@ -51,35 +56,49 @@ It is equivalent to "git branch -D <branchname>".
51 else: 56 else:
52 args.insert(0, "'All local branches'") 57 args.insert(0, "'All local branches'")
53 58
59 def _ExecuteOne(self, opt, nb, project):
60 """Abandon one project."""
61 if opt.all:
62 branches = project.GetBranches()
63 else:
64 branches = [nb]
65
66 ret = {}
67 for name in branches:
68 status = project.AbandonBranch(name)
69 if status is not None:
70 ret[name] = status
71 return (ret, project)
72
54 def Execute(self, opt, args): 73 def Execute(self, opt, args):
55 nb = args[0] 74 nb = args[0]
56 err = defaultdict(list) 75 err = defaultdict(list)
57 success = defaultdict(list) 76 success = defaultdict(list)
58 all_projects = self.GetProjects(args[1:]) 77 all_projects = self.GetProjects(args[1:])
59 78
60 pm = Progress('Abandon %s' % nb, len(all_projects)) 79 def _ProcessResults(states):
61 for project in all_projects: 80 for (results, project) in states:
62 pm.update() 81 for branch, status in results.items():
63
64 if opt.all:
65 branches = list(project.GetBranches().keys())
66 else:
67 branches = [nb]
68
69 for name in branches:
70 status = project.AbandonBranch(name)
71 if status is not None:
72 if status: 82 if status:
73 success[name].append(project) 83 success[branch].append(project)
74 else: 84 else:
75 err[name].append(project) 85 err[branch].append(project)
76 pm.end() 86 pm.update()
77 87
78 width = 25 88 pm = Progress('Abandon %s' % nb, len(all_projects))
79 for name in branches: 89 # NB: Multiprocessing is heavy, so don't spin it up for one job.
80 if width < len(name): 90 if len(all_projects) == 1 or opt.jobs == 1:
81 width = len(name) 91 _ProcessResults(self._ExecuteOne(opt, nb, x) for x in all_projects)
92 else:
93 with multiprocessing.Pool(opt.jobs) as pool:
94 states = pool.imap_unordered(
95 functools.partial(self._ExecuteOne, opt, nb), all_projects,
96 chunksize=WORKER_BATCH_SIZE)
97 _ProcessResults(states)
98 pm.end()
82 99
100 width = max(itertools.chain(
101 [25], (len(x) for x in itertools.chain(success, err))))
83 if err: 102 if err:
84 for br in err.keys(): 103 for br in err.keys():
85 err_msg = "error: cannot abandon %s" % br 104 err_msg = "error: cannot abandon %s" % br
diff --git a/subcmds/start.py b/subcmds/start.py
index 7684b6d7..25b229f1 100644
--- a/subcmds/start.py
+++ b/subcmds/start.py
@@ -12,10 +12,12 @@
12# See the License for the specific language governing permissions and 12# See the License for the specific language governing permissions and
13# limitations under the License. 13# limitations under the License.
14 14
15import functools
16import multiprocessing
15import os 17import os
16import sys 18import sys
17 19
18from command import Command 20from command import Command, DEFAULT_LOCAL_JOBS, WORKER_BATCH_SIZE
19from git_config import IsImmutable 21from git_config import IsImmutable
20from git_command import git 22from git_command import git
21import gitc_utils 23import gitc_utils
@@ -33,8 +35,10 @@ class Start(Command):
33'%prog' begins a new branch of development, starting from the 35'%prog' begins a new branch of development, starting from the
34revision specified in the manifest. 36revision specified in the manifest.
35""" 37"""
38 PARALLEL_JOBS = DEFAULT_LOCAL_JOBS
36 39
37 def _Options(self, p): 40 def _Options(self, p):
41 super()._Options(p)
38 p.add_option('--all', 42 p.add_option('--all',
39 dest='all', action='store_true', 43 dest='all', action='store_true',
40 help='begin branch in all projects') 44 help='begin branch in all projects')
@@ -51,6 +55,26 @@ revision specified in the manifest.
51 if not git.check_ref_format('heads/%s' % nb): 55 if not git.check_ref_format('heads/%s' % nb):
52 self.OptionParser.error("'%s' is not a valid name" % nb) 56 self.OptionParser.error("'%s' is not a valid name" % nb)
53 57
58 def _ExecuteOne(self, opt, nb, project):
59 """Start one project."""
60 # If the current revision is immutable, such as a SHA1, a tag or
61 # a change, then we can't push back to it. Substitute with
62 # dest_branch, if defined; or with manifest default revision instead.
63 branch_merge = ''
64 if IsImmutable(project.revisionExpr):
65 if project.dest_branch:
66 branch_merge = project.dest_branch
67 else:
68 branch_merge = self.manifest.default.revisionExpr
69
70 try:
71 ret = project.StartBranch(
72 nb, branch_merge=branch_merge, revision=opt.revision)
73 except Exception as e:
74 print('error: unable to checkout %s: %s' % (project.name, e), file=sys.stderr)
75 ret = False
76 return (ret, project)
77
54 def Execute(self, opt, args): 78 def Execute(self, opt, args):
55 nb = args[0] 79 nb = args[0]
56 err = [] 80 err = []
@@ -82,11 +106,8 @@ revision specified in the manifest.
82 if not os.path.exists(os.getcwd()): 106 if not os.path.exists(os.getcwd()):
83 os.chdir(self.manifest.topdir) 107 os.chdir(self.manifest.topdir)
84 108
85 pm = Progress('Starting %s' % nb, len(all_projects)) 109 pm = Progress('Syncing %s' % nb, len(all_projects))
86 for project in all_projects: 110 for project in all_projects:
87 pm.update()
88
89 if self.gitc_manifest:
90 gitc_project = self.gitc_manifest.paths[project.relpath] 111 gitc_project = self.gitc_manifest.paths[project.relpath]
91 # Sync projects that have not been opened. 112 # Sync projects that have not been opened.
92 if not gitc_project.already_synced: 113 if not gitc_project.already_synced:
@@ -99,20 +120,25 @@ revision specified in the manifest.
99 sync_buf = SyncBuffer(self.manifest.manifestProject.config) 120 sync_buf = SyncBuffer(self.manifest.manifestProject.config)
100 project.Sync_LocalHalf(sync_buf) 121 project.Sync_LocalHalf(sync_buf)
101 project.revisionId = gitc_project.old_revision 122 project.revisionId = gitc_project.old_revision
123 pm.update()
124 pm.end()
102 125
103 # If the current revision is immutable, such as a SHA1, a tag or 126 def _ProcessResults(results):
104 # a change, then we can't push back to it. Substitute with 127 for (result, project) in results:
105 # dest_branch, if defined; or with manifest default revision instead. 128 if not result:
106 branch_merge = '' 129 err.append(project)
107 if IsImmutable(project.revisionExpr): 130 pm.update()
108 if project.dest_branch:
109 branch_merge = project.dest_branch
110 else:
111 branch_merge = self.manifest.default.revisionExpr
112 131
113 if not project.StartBranch( 132 pm = Progress('Starting %s' % nb, len(all_projects))
114 nb, branch_merge=branch_merge, revision=opt.revision): 133 # NB: Multiprocessing is heavy, so don't spin it up for one job.
115 err.append(project) 134 if len(all_projects) == 1 or opt.jobs == 1:
135 _ProcessResults(self._ExecuteOne(opt, nb, x) for x in all_projects)
136 else:
137 with multiprocessing.Pool(opt.jobs) as pool:
138 results = pool.imap_unordered(
139 functools.partial(self._ExecuteOne, opt, nb), all_projects,
140 chunksize=WORKER_BATCH_SIZE)
141 _ProcessResults(results)
116 pm.end() 142 pm.end()
117 143
118 if err: 144 if err: