summaryrefslogtreecommitdiffstats
path: root/subcmds/abandon.py
diff options
context:
space:
mode:
Diffstat (limited to 'subcmds/abandon.py')
-rw-r--r--subcmds/abandon.py167
1 files changed, 94 insertions, 73 deletions
diff --git a/subcmds/abandon.py b/subcmds/abandon.py
index c3d2d5b7..1f687f53 100644
--- a/subcmds/abandon.py
+++ b/subcmds/abandon.py
@@ -23,9 +23,9 @@ from progress import Progress
23 23
24 24
25class Abandon(Command): 25class Abandon(Command):
26 COMMON = True 26 COMMON = True
27 helpSummary = "Permanently abandon a development branch" 27 helpSummary = "Permanently abandon a development branch"
28 helpUsage = """ 28 helpUsage = """
29%prog [--all | <branchname>] [<project>...] 29%prog [--all | <branchname>] [<project>...]
30 30
31This subcommand permanently abandons a development branch by 31This subcommand permanently abandons a development branch by
@@ -33,83 +33,104 @@ deleting it (and all its history) from your local repository.
33 33
34It is equivalent to "git branch -D <branchname>". 34It is equivalent to "git branch -D <branchname>".
35""" 35"""
36 PARALLEL_JOBS = DEFAULT_LOCAL_JOBS 36 PARALLEL_JOBS = DEFAULT_LOCAL_JOBS
37 37
38 def _Options(self, p): 38 def _Options(self, p):
39 p.add_option('--all', 39 p.add_option(
40 dest='all', action='store_true', 40 "--all",
41 help='delete all branches in all projects') 41 dest="all",
42 action="store_true",
43 help="delete all branches in all projects",
44 )
42 45
43 def ValidateOptions(self, opt, args): 46 def ValidateOptions(self, opt, args):
44 if not opt.all and not args: 47 if not opt.all and not args:
45 self.Usage() 48 self.Usage()
46 49
47 if not opt.all: 50 if not opt.all:
48 nb = args[0] 51 nb = args[0]
49 if not git.check_ref_format('heads/%s' % nb): 52 if not git.check_ref_format("heads/%s" % nb):
50 self.OptionParser.error("'%s' is not a valid branch name" % nb) 53 self.OptionParser.error("'%s' is not a valid branch name" % nb)
51 else: 54 else:
52 args.insert(0, "'All local branches'") 55 args.insert(0, "'All local branches'")
53 56
54 def _ExecuteOne(self, all_branches, nb, project): 57 def _ExecuteOne(self, all_branches, nb, project):
55 """Abandon one project.""" 58 """Abandon one project."""
56 if all_branches: 59 if all_branches:
57 branches = project.GetBranches() 60 branches = project.GetBranches()
58 else: 61 else:
59 branches = [nb] 62 branches = [nb]
60 63
61 ret = {} 64 ret = {}
62 for name in branches: 65 for name in branches:
63 status = project.AbandonBranch(name) 66 status = project.AbandonBranch(name)
64 if status is not None: 67 if status is not None:
65 ret[name] = status 68 ret[name] = status
66 return (ret, project) 69 return (ret, project)
67 70
68 def Execute(self, opt, args): 71 def Execute(self, opt, args):
69 nb = args[0] 72 nb = args[0]
70 err = defaultdict(list) 73 err = defaultdict(list)
71 success = defaultdict(list) 74 success = defaultdict(list)
72 all_projects = self.GetProjects(args[1:], all_manifests=not opt.this_manifest_only) 75 all_projects = self.GetProjects(
73 _RelPath = lambda p: p.RelPath(local=opt.this_manifest_only) 76 args[1:], all_manifests=not opt.this_manifest_only
77 )
78 _RelPath = lambda p: p.RelPath(local=opt.this_manifest_only)
74 79
75 def _ProcessResults(_pool, pm, states): 80 def _ProcessResults(_pool, pm, states):
76 for (results, project) in states: 81 for results, project in states:
77 for branch, status in results.items(): 82 for branch, status in results.items():
78 if status: 83 if status:
79 success[branch].append(project) 84 success[branch].append(project)
80 else: 85 else:
81 err[branch].append(project) 86 err[branch].append(project)
82 pm.update() 87 pm.update()
83 88
84 self.ExecuteInParallel( 89 self.ExecuteInParallel(
85 opt.jobs, 90 opt.jobs,
86 functools.partial(self._ExecuteOne, opt.all, nb), 91 functools.partial(self._ExecuteOne, opt.all, nb),
87 all_projects, 92 all_projects,
88 callback=_ProcessResults, 93 callback=_ProcessResults,
89 output=Progress('Abandon %s' % (nb,), len(all_projects), quiet=opt.quiet)) 94 output=Progress(
95 "Abandon %s" % (nb,), len(all_projects), quiet=opt.quiet
96 ),
97 )
90 98
91 width = max(itertools.chain( 99 width = max(
92 [25], (len(x) for x in itertools.chain(success, err)))) 100 itertools.chain(
93 if err: 101 [25], (len(x) for x in itertools.chain(success, err))
94 for br in err.keys(): 102 )
95 err_msg = "error: cannot abandon %s" % br 103 )
96 print(err_msg, file=sys.stderr) 104 if err:
97 for proj in err[br]: 105 for br in err.keys():
98 print(' ' * len(err_msg) + " | %s" % _RelPath(proj), file=sys.stderr) 106 err_msg = "error: cannot abandon %s" % br
99 sys.exit(1) 107 print(err_msg, file=sys.stderr)
100 elif not success: 108 for proj in err[br]:
101 print('error: no project has local branch(es) : %s' % nb, 109 print(
102 file=sys.stderr) 110 " " * len(err_msg) + " | %s" % _RelPath(proj),
103 sys.exit(1) 111 file=sys.stderr,
104 else: 112 )
105 # Everything below here is displaying status. 113 sys.exit(1)
106 if opt.quiet: 114 elif not success:
107 return 115 print(
108 print('Abandoned branches:') 116 "error: no project has local branch(es) : %s" % nb,
109 for br in success.keys(): 117 file=sys.stderr,
110 if len(all_projects) > 1 and len(all_projects) == len(success[br]): 118 )
111 result = "all project" 119 sys.exit(1)
112 else: 120 else:
113 result = "%s" % ( 121 # Everything below here is displaying status.
114 ('\n' + ' ' * width + '| ').join(_RelPath(p) for p in success[br])) 122 if opt.quiet:
115 print("%s%s| %s\n" % (br, ' ' * (width - len(br)), result)) 123 return
124 print("Abandoned branches:")
125 for br in success.keys():
126 if len(all_projects) > 1 and len(all_projects) == len(
127 success[br]
128 ):
129 result = "all project"
130 else:
131 result = "%s" % (
132 ("\n" + " " * width + "| ").join(
133 _RelPath(p) for p in success[br]
134 )
135 )
136 print("%s%s| %s\n" % (br, " " * (width - len(br)), result))