diff options
Diffstat (limited to 'subcmds/abandon.py')
-rw-r--r-- | subcmds/abandon.py | 75 |
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 | ||
17 | from __future__ import print_function | ||
18 | import sys | ||
19 | from command import Command | ||
20 | from collections import defaultdict | 15 | from collections import defaultdict |
16 | import functools | ||
17 | import itertools | ||
18 | import sys | ||
19 | |||
20 | from command import Command, DEFAULT_LOCAL_JOBS | ||
21 | from git_command import git | 21 | from git_command import git |
22 | from progress import Progress | 22 | from progress import Progress |
23 | 23 | ||
24 | |||
24 | class Abandon(Command): | 25 | class 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 | ||
33 | It is equivalent to "git branch -D <branchname>". | 34 | It 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)) |