summaryrefslogtreecommitdiffstats
path: root/subcmds/abandon.py
diff options
context:
space:
mode:
Diffstat (limited to 'subcmds/abandon.py')
-rw-r--r--subcmds/abandon.py75
1 files changed, 45 insertions, 30 deletions
diff --git a/subcmds/abandon.py b/subcmds/abandon.py
index cd1d0c40..85d85f5a 100644
--- a/subcmds/abandon.py
+++ b/subcmds/abandon.py
@@ -1,5 +1,3 @@
1# -*- coding:utf-8 -*-
2#
3# Copyright (C) 2008 The Android Open Source Project 1# Copyright (C) 2008 The Android Open Source Project
4# 2#
5# Licensed under the Apache License, Version 2.0 (the "License"); 3# Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,15 +12,18 @@
14# See the License for the specific language governing permissions and 12# See the License for the specific language governing permissions and
15# limitations under the License. 13# limitations under the License.
16 14
17from __future__ import print_function
18import sys
19from command import Command
20from collections import defaultdict 15from collections import defaultdict
16import functools
17import itertools
18import sys
19
20from command import Command, DEFAULT_LOCAL_JOBS
21from git_command import git 21from git_command import git
22from progress import Progress 22from progress import Progress
23 23
24
24class Abandon(Command): 25class Abandon(Command):
25 common = True 26 COMMON = True
26 helpSummary = "Permanently abandon a development branch" 27 helpSummary = "Permanently abandon a development branch"
27 helpUsage = """ 28 helpUsage = """
28%prog [--all | <branchname>] [<project>...] 29%prog [--all | <branchname>] [<project>...]
@@ -32,6 +33,8 @@ deleting it (and all its history) from your local repository.
32 33
33It is equivalent to "git branch -D <branchname>". 34It is equivalent to "git branch -D <branchname>".
34""" 35"""
36 PARALLEL_JOBS = DEFAULT_LOCAL_JOBS
37
35 def _Options(self, p): 38 def _Options(self, p):
36 p.add_option('--all', 39 p.add_option('--all',
37 dest='all', action='store_true', 40 dest='all', action='store_true',
@@ -48,52 +51,64 @@ It is equivalent to "git branch -D <branchname>".
48 else: 51 else:
49 args.insert(0, "'All local branches'") 52 args.insert(0, "'All local branches'")
50 53
54 def _ExecuteOne(self, all_branches, nb, project):
55 """Abandon one project."""
56 if all_branches:
57 branches = project.GetBranches()
58 else:
59 branches = [nb]
60
61 ret = {}
62 for name in branches:
63 status = project.AbandonBranch(name)
64 if status is not None:
65 ret[name] = status
66 return (ret, project)
67
51 def Execute(self, opt, args): 68 def Execute(self, opt, args):
52 nb = args[0] 69 nb = args[0]
53 err = defaultdict(list) 70 err = defaultdict(list)
54 success = defaultdict(list) 71 success = defaultdict(list)
55 all_projects = self.GetProjects(args[1:]) 72 all_projects = self.GetProjects(args[1:])
56 73
57 pm = Progress('Abandon %s' % nb, len(all_projects)) 74 def _ProcessResults(_pool, pm, states):
58 for project in all_projects: 75 for (results, project) in states:
59 pm.update() 76 for branch, status in results.items():
60
61 if opt.all:
62 branches = list(project.GetBranches().keys())
63 else:
64 branches = [nb]
65
66 for name in branches:
67 status = project.AbandonBranch(name)
68 if status is not None:
69 if status: 77 if status:
70 success[name].append(project) 78 success[branch].append(project)
71 else: 79 else:
72 err[name].append(project) 80 err[branch].append(project)
73 pm.end() 81 pm.update()
74 82
75 width = 25 83 self.ExecuteInParallel(
76 for name in branches: 84 opt.jobs,
77 if width < len(name): 85 functools.partial(self._ExecuteOne, opt.all, nb),
78 width = len(name) 86 all_projects,
87 callback=_ProcessResults,
88 output=Progress('Abandon %s' % (nb,), len(all_projects), quiet=opt.quiet))
79 89
90 width = max(itertools.chain(
91 [25], (len(x) for x in itertools.chain(success, err))))
80 if err: 92 if err:
81 for br in err.keys(): 93 for br in err.keys():
82 err_msg = "error: cannot abandon %s" %br 94 err_msg = "error: cannot abandon %s" % br
83 print(err_msg, file=sys.stderr) 95 print(err_msg, file=sys.stderr)
84 for proj in err[br]: 96 for proj in err[br]:
85 print(' '*len(err_msg) + " | %s" % proj.relpath, file=sys.stderr) 97 print(' ' * len(err_msg) + " | %s" % proj.relpath, file=sys.stderr)
86 sys.exit(1) 98 sys.exit(1)
87 elif not success: 99 elif not success:
88 print('error: no project has local branch(es) : %s' % nb, 100 print('error: no project has local branch(es) : %s' % nb,
89 file=sys.stderr) 101 file=sys.stderr)
90 sys.exit(1) 102 sys.exit(1)
91 else: 103 else:
92 print('Abandoned branches:', file=sys.stderr) 104 # Everything below here is displaying status.
105 if opt.quiet:
106 return
107 print('Abandoned branches:')
93 for br in success.keys(): 108 for br in success.keys():
94 if len(all_projects) > 1 and len(all_projects) == len(success[br]): 109 if len(all_projects) > 1 and len(all_projects) == len(success[br]):
95 result = "all project" 110 result = "all project"
96 else: 111 else:
97 result = "%s" % ( 112 result = "%s" % (
98 ('\n'+' '*width + '| ').join(p.relpath for p in success[br])) 113 ('\n' + ' ' * width + '| ').join(p.relpath for p in success[br]))
99 print("%s%s| %s\n" % (br,' '*(width-len(br)), result),file=sys.stderr) 114 print("%s%s| %s\n" % (br, ' ' * (width - len(br)), result))